Merge remote-tracking branch 'origin/master' into IDEA-CR-10038
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Mon, 25 Apr 2016 10:22:09 +0000 (12:22 +0200)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Mon, 25 Apr 2016 10:22:09 +0000 (12:22 +0200)
183 files changed:
java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java
java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java
java/java-analysis-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
java/java-analysis-impl/src/com/intellij/refactoring/util/VariableData.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorParameterFromFieldFix.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodReturnTypeFix.java
java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeInfoImpl.java
java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterInfo.java
java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java
java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectClassDescriptor.java
java/java-impl/src/com/intellij/refactoring/introduceparameterobject/JavaIntroduceParameterObjectDelegate.java
java/java-impl/src/com/intellij/refactoring/introduceparameterobject/ParameterObjectBuilder.java
java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java
java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
java/java-psi-api/src/com/intellij/psi/JVMElementFactory.java
java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
java/java-psi-api/src/com/intellij/psi/PsiClassType.java
java/java-psi-api/src/com/intellij/psi/PsiDiamondType.java
java/java-psi-api/src/com/intellij/psi/PsiDisjunctionType.java
java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java
java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
java/java-psi-api/src/com/intellij/psi/PsiJavaParserFacade.java
java/java-psi-api/src/com/intellij/psi/PsiLambdaExpressionType.java
java/java-psi-api/src/com/intellij/psi/PsiLambdaParameterType.java
java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
java/java-psi-api/src/com/intellij/psi/PsiType.java
java/java-psi-api/src/com/intellij/psi/PsiWildcardType.java
java/java-psi-api/src/com/intellij/psi/TypeAnnotationProvider.java
java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java
java/java-psi-impl/src/com/intellij/psi/Bottom.java
java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
java/java-psi-impl/src/com/intellij/psi/PsiTypeVariable.java
java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java
java/java-psi-impl/src/com/intellij/refactoring/util/CanonicalTypes.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/afterFromLambdaParameter.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/beforeFromLambdaParameter.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeCodeBlockWithReturnInSwitch.java [new file with mode: 0644]
java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression.java [new file with mode: 0644]
java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression_after.java [new file with mode: 0644]
java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Param.java [new file with mode: 0644]
java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Test.java [new file with mode: 0644]
java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/before/Test.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java
platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java
platform/lang-api/src/com/intellij/refactoring/changeSignature/ChangeInfo.java
platform/lang-api/src/com/intellij/refactoring/changeSignature/ParameterInfo.java
platform/lang-impl/src/com/intellij/application/options/colors/FontOptions.java
platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java
platform/lang-impl/src/com/intellij/ide/actions/CreateFileFromTemplateDialog.java
platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/PsiAwareTextEditorProvider.java
platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelBase.java
platform/lang-impl/src/com/intellij/refactoring/introduceParameterObject/IntroduceParameterObjectDelegate.java
platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteProcessor.java
platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-tests/testSrc/com/intellij/application/TransactionTest.groovy
platform/platform-tests/testSrc/com/intellij/util/containers/TreeTraverserTest.java
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/events/TestFailedEvent.java
platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java
platform/util/src/com/intellij/openapi/util/BuildNumber.java
platform/util/src/com/intellij/util/containers/JBIterator.java
platform/util/src/com/intellij/util/ui/ListTableModel.java
platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ConvertToVarargsMethodFix.java
plugins/InspectionGadgets/src/com/intellij/codeInspection/TrivialFunctionalExpressionUsageInspection.java
plugins/IntentionPowerPak/src/com/siyeh/ipp/varargs/MakeMethodVarargsIntention.java
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeInfoImpl.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceParameterObject/GroovyIntroduceParameterObjectDelegate.java
plugins/ui-designer-core/src/META-INF/DesignerCorePlugin.xml
plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java
python/educational-core/course-creator/resources/META-INF/plugin.xml
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java [deleted file]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCLanguageManager.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCProjectComponent.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCProjectService.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCRefactoringElementListenerProvider.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionListener.java [new file with mode: 0644]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionsProvider.java [new file with mode: 0644]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCUtils.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCVirtualFileListener.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java with 54% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAnswerPlaceholder.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAddAsTaskFile.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCAnswerPlaceholderAction.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCChangeCourseInfo.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateCourseArchive.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateStudyItemActionBase.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateTask.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCCreateTaskFile.java [deleted file]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCDeleteAllAnswerPlaceholdersAction.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCDeleteAnswerPlaceholder.java [deleted file]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCEditAnswerPlaceholder.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowAnswerPlaceholderDetails.java with 62% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCEditTaskTextAction.java [new file with mode: 0644]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCFromCourseArchive.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCHideFromStudent.java [new file with mode: 0644]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCPushCourse.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCPushLesson.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCRunTestsAction.java [deleted file]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCShowPreview.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCTaskFileActionBase.java [new file with mode: 0644]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/handlers/CCLessonMoveHandlerDelegate.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCLessonMoveHandlerDelegate.java with 93% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/handlers/CCLessonRenameHandler.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCLessonRenameHandler.java with 94% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/handlers/CCRenameHandler.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCRenameHandler.java with 88% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/handlers/CCTaskMoveHandlerDelegate.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCTaskMoveHandlerDelegate.java with 94% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/handlers/CCTaskRenameHandler.java [moved from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCTaskRenameHandler.java with 96% similarity]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/projectView/CCDirectoryNode.java [deleted file]
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/projectView/CCTreeStructureProvider.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateCourseArchiveDialog.java
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/ui/CreateCourseArchivePanel.java
python/educational-core/student/resources/META-INF/plugin.xml
python/educational-core/student/src/com/jetbrains/edu/learning/StudyActionListener.java [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/StudyActionsProvider.java [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/StudyAnswerPlaceholderExtendWordHandler.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyMoveDelegate.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyPluginConfigurator.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyTaskManager.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyActionWithShortcut.java [moved from python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyToolbarAction.java with 58% similarity]
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyFillPlaceholdersAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyRefreshAnswerPlaceholder.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyRefreshTaskFileAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyShowHintAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyWindowNavigationAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudySmartChecker.java
python/educational-core/student/src/com/jetbrains/edu/learning/core/EduAnswerPlaceholderPainter.java
python/educational-core/student/src/com/jetbrains/edu/learning/core/EduDocumentListener.java
python/educational-core/student/src/com/jetbrains/edu/learning/core/EduNames.java
python/educational-core/student/src/com/jetbrains/edu/learning/core/EduUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/AnswerPlaceholder.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Course.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/TaskFile.java
python/educational-core/student/src/com/jetbrains/edu/learning/editor/StudyEditorFactoryListener.java
python/educational-core/student/src/com/jetbrains/edu/learning/projectView/StudyTreeStructureProvider.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyJavaFxToolWindow.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java
python/educational-core/student/student.iml
python/educational-python/course-creator-python/resources/META-INF/plugin.xml
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCLanguageManager.java
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCProjectGenerator.java
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCReferenceResolveProvider.java
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/PyCCRunTests.java [deleted file]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/actions/PyCCRunTestsAction.java [deleted file]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCCommandLineState.java [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestConfiguration.java [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationFactory.java [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationProducer.java [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationType.java [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCSettingEditor.form [new file with mode: 0644]
python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCSettingsEditor.java [new file with mode: 0644]
python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyCheckAction.java
python/openapi/src/com/jetbrains/python/templateLanguages/ConfigureTemplateDirectoriesAction.java
python/setup-test-environment/build.gradle
python/src/com/jetbrains/python/BaseReference.java [new file with mode: 0644]
python/src/com/jetbrains/python/PyStringLiteralReference.java [new file with mode: 0644]
spellchecker/src/com/intellij/spellchecker/jetbrains.dic
xml/impl/src/com/intellij/xml/impl/schema/SchemaDefinitionsSearch.java

index f307ac919ddba469ac159f7b2b60eccaea5bc49d..74d0410d7fa046ec893cb2c0fb6566c2f6f2df7c 100644 (file)
@@ -27,7 +27,11 @@ import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.*;
 import com.intellij.util.PlatformIcons;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
 import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
 import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
 import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
 import org.jetbrains.annotations.NotNull;
@@ -128,6 +132,18 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
         nodeIcon = AllIcons.Debugger.Value;
       }
     }
+
+    // if watches in variables enabled, always use watch icon
+    if (valueDescriptor instanceof WatchItemDescriptor && nodeIcon != AllIcons.Debugger.Watch) {
+      XDebugSession session = XDebuggerManager.getInstance(valueDescriptor.getProject()).getCurrentSession();
+      if (session != null) {
+        XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
+        if (tab != null && tab.isWatchesInVariables()) {
+          nodeIcon = AllIcons.Debugger.Watch;
+        }
+      }
+    }
+
     final Icon valueIcon = valueDescriptor.getValueIcon();
     if (nodeIcon != null && valueIcon != null) {
       nodeIcon = new RowIcon(nodeIcon, valueIcon);
index f5ce0f3e0442d03944bac1c8478d738c66cb6105..f07cb5301613691e6cef6c9556126cd28aa96feb 100644 (file)
@@ -369,7 +369,7 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
 
   protected void writeClassesPerModule(String packageName, JavaParameters javaParameters, Map<Module, List<String>> perModule)
     throws FileNotFoundException, UnsupportedEncodingException, CantRunException {
-    if (perModule != null && perModule.size() > 1) {
+    if (perModule != null) {
       final String classpath = getScope() == TestSearchScope.WHOLE_PROJECT
                                ? null : javaParameters.getClassPath().getPathsString();
 
index 50a5e91903d08a3c9228d19231450b4c4d1f2adc..b7e0e48f8c4b5bd2ceb2ca8c3715db9c4402c555 100644 (file)
@@ -118,15 +118,12 @@ public class ParametersFolder {
     PsiExpression mostRanked = null;
     for (int i = mentionedInExpressions.size() - 1; i >= 0; i--) {
       PsiExpression expression = mentionedInExpressions.get(i);
-      if (expression instanceof PsiArrayAccessExpression) {
-        mostRanked = expression;
-        if (!isConditional(expression, scope)) {
-          myFoldingSelectedByDefault = true;
-          break;
-        }
+      boolean arrayAccess = expression instanceof PsiArrayAccessExpression && !isConditional(expression, scope);
+      if (arrayAccess) {
+        myFoldingSelectedByDefault = true;
       }
       final int r = findUsedVariables(data, inputVariables, expression).size();
-      if (currentRank < r) {
+      if (currentRank < r || arrayAccess && currentRank == r) {
         currentRank = r;
         mostRanked = expression;
       }
index d367ceb0e768268da2874849d6d3f8f8293e37e3..5c7d95416bb1149c0d9405e02f86e3ac62baf866 100644 (file)
  */
 package com.intellij.refactoring.util;
 
-import com.intellij.psi.*;
+import com.intellij.psi.LambdaUtil;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+import com.intellij.psi.SmartTypePointerManager;
 import com.intellij.psi.search.GlobalSearchScope;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -32,7 +35,7 @@ public class VariableData extends AbstractVariableData {
   public VariableData(@Nullable PsiVariable var, PsiType type) {
     variable = var;
     if (var != null) {
-      if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) {
+      if (LambdaUtil.notInferredType(type)) {
         type = PsiType.getJavaLangObject(var.getManager(), GlobalSearchScope.allScope(var.getProject()));
       }
       this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
index 5ef6d1737af4e507cc82ef5c2264c86f8bfc4e4c..97bb45cb531c89ffad0b4fb9da9b734eda1472a3 100644 (file)
@@ -125,7 +125,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
         }
       }
     });
-    final List<PsiElement> cleanupElements = new ArrayList<PsiElement>(); 
+    final List<SmartPsiElementPointer<PsiElement>> cleanupElements = new ArrayList<>();
     final List<PsiMethod> filtered = filterConstructorsIfFieldAlreadyAssigned(constructors, getField());
     if (filtered.size() > 1) {
       final PsiMethodMember[] members = new PsiMethodMember[filtered.size()];
@@ -188,7 +188,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
         fieldsToFix.clear();
       }
     }
-    GlobalInspectionContextBase.cleanupElements(project, null, cleanupElements.toArray(new PsiElement[cleanupElements.size()]));
+    GlobalInspectionContextBase.cleanupElements(project, null, cleanupElements);
   }
 
    @NotNull
@@ -237,7 +237,8 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
                                                    final PsiFile file,
                                                    final Editor editor,
                                                    final PsiMethod constructor,
-                                                   final PsiField[] fields, final List<PsiElement> cleanupElements) throws IncorrectOperationException {
+                                                   final PsiField[] fields,
+                                                   final List<SmartPsiElementPointer<PsiElement>> cleanupElements) throws IncorrectOperationException {
     final PsiParameterList parameterList = constructor.getParameterList();
     final PsiParameter[] parameters = parameterList.getParameters();
     ParameterInfoImpl[] newParamInfos = new ParameterInfoImpl[parameters.length + fields.length];
@@ -328,13 +329,14 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
   }
 
   private static boolean doCreate(Project project, Editor editor, PsiParameter[] parameters, SmartPsiElementPointer constructorPointer,
-                                  ParameterInfoImpl[] parameterInfos, Map<PsiField, String> fields, List<PsiElement> cleanupElements) {
+                                  ParameterInfoImpl[] parameterInfos, Map<PsiField, String> fields, List<SmartPsiElementPointer<PsiElement>> cleanupElements) {
     PsiMethod constructor = (PsiMethod)constructorPointer.getElement();
     assert constructor != null;
     PsiParameter[] newParameters = constructor.getParameterList().getParameters();
     if (newParameters == parameters) return false; //user must have canceled dialog
     // do not introduce assignment in chained constructor
     if (JavaHighlightUtil.getChainedConstructors(constructor) == null) {
+      final SmartPointerManager manager = SmartPointerManager.getInstance(project);
       boolean created = false;
       for (PsiField field : fields.keySet()) {
         final String defaultParamName = fields.get(field);
@@ -343,10 +345,10 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
           continue;
         }
         NullableNotNullManager.getInstance(field.getProject()).copyNotNullAnnotation(field, parameter);
-        cleanupElements.add(parameter);
+        cleanupElements.add(manager.createSmartPsiElementPointer(parameter));
         final PsiElement assignmentStatement = AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor);
         if (assignmentStatement != null) {
-          cleanupElements.add(assignmentStatement);
+          cleanupElements.add(manager.createSmartPsiElementPointer(assignmentStatement));
         }
         created = true;
       }
index 039e9f82f165ceb4fd76f5e4480e1daefc460db7..fafe647b413763e05b27a0a65c11a8f7b3b924c0 100644 (file)
@@ -261,10 +261,7 @@ public class CreateFromUsageUtils {
         names = new String[]{"p" + i};
       }
 
-      if (argType == null || PsiType.NULL.equals(argType) ||
-          argType instanceof PsiLambdaExpressionType ||
-          argType instanceof PsiLambdaParameterType ||
-          argType instanceof PsiMethodReferenceType) {
+      if (argType == null || PsiType.NULL.equals(argType) || LambdaUtil.notInferredType(argType)) {
         argType = PsiType.getJavaLangObject(psiManager, resolveScope);
       } else if (argType instanceof PsiDisjunctionType) {
         argType = ((PsiDisjunctionType)argType).getLeastUpperBound();
index aca399d6b20e5e5550f1c04d97364a1e38e06c08..bae4cd9e8beeca6de1930f2bd0f9666c498611b8 100644 (file)
@@ -78,6 +78,9 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
     final SmartTypePointer defaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(expectedTypes[0]);
     final PsiType preferredType = TypeSelectorManagerImpl.getPreferredType(expectedTypes, expectedTypes[0]);
     PsiType type = preferredType != null ? preferredType : expectedTypes[0];
+    if (LambdaUtil.notInferredType(type)) {
+      type = PsiType.getJavaLangObject(myReferenceExpression.getManager(), targetClass.getResolveScope());
+    }
 
     String varName = myReferenceExpression.getReferenceName();
     PsiExpression initializer = null;
index 2848899bab90f1e43c76994dd0aff65a0e9c4260..308ffa30cef1663edbad9a5061ba483f60d39c8a 100644 (file)
@@ -40,7 +40,6 @@ import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
 import com.intellij.refactoring.changeSignature.OverriderUsageInfo;
 import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
-import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
 import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
 import com.intellij.refactoring.typeMigration.TypeMigrationRules;
 import com.intellij.usageView.UsageInfo;
@@ -89,14 +88,16 @@ public class MethodReturnTypeFix extends LocalQuickFixAndIntentionActionOnPsiEle
                              @NotNull PsiElement endElement) {
     final PsiMethod myMethod = (PsiMethod)startElement;
 
-    PsiType myReturnType = myReturnTypePointer.getType();
-    return myMethod.isValid()
-        && myMethod.getManager().isInProject(myMethod)
-        && myReturnType != null
-        && myReturnType.isValid()
-        && !TypeConversionUtil.isNullType(myReturnType)
-        && myMethod.getReturnType() != null
-        && !Comparing.equal(myReturnType, myMethod.getReturnType());
+    final PsiType myReturnType = myReturnTypePointer.getType();
+    if (myMethod.isValid() &&
+        myMethod.getManager().isInProject(myMethod) &&
+        myReturnType != null &&
+        myReturnType.isValid() &&
+        !TypeConversionUtil.isNullType(myReturnType)) {
+      final PsiType returnType = myMethod.getReturnType();
+      if (returnType != null && returnType.isValid() && !Comparing.equal(myReturnType, returnType)) return true;
+    }
+    return false;
   }
 
   @Override
index 46021270acde52e6f3bc4e8064e5e380f1fe6151..cb1b753898f4bc2021a31d07086c530972b0c2a1 100644 (file)
@@ -309,7 +309,7 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
   @Nullable
   public PsiExpression getValue(int i, PsiCallExpression expr) throws IncorrectOperationException {
     if (defaultValues[i] != null) return defaultValues[i];
-    final PsiElement valueAtCallSite = newParms[i].getActualValue(expr);
+    final PsiElement valueAtCallSite = newParms[i].getActualValue(expr, PsiSubstitutor.EMPTY);
     return valueAtCallSite instanceof PsiExpression ? (PsiExpression)valueAtCallSite : null;
   }
 
index 1cdde7c66a3f7f9ae402cc1de59d60ca02378914..5d9eb7b102b197394630a7346ef07bbbdfe8446f 100644 (file)
@@ -410,7 +410,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
   //This methods works equally well for primary usages as well as for propagated callers' usages
   private static void fixActualArgumentsList(PsiExpressionList list,
                                              JavaChangeInfo changeInfo,
-                                             boolean toInsertDefaultValue, PsiSubstitutor substitutor) throws IncorrectOperationException {
+                                             boolean toInsertDefaultValue,
+                                             PsiSubstitutor substitutor) throws IncorrectOperationException {
     final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
     if (changeInfo.isParameterSetOrOrderChanged()) {
       if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) {
@@ -418,7 +419,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
         for (ParameterInfoImpl info : createdParmsInfo) {
           PsiExpression newArg;
           if (toInsertDefaultValue) {
-            newArg = createDefaultValue(changeInfo, factory, info, list);
+            newArg = createDefaultValue(changeInfo, factory, info, list, substitutor);
           }
           else {
             newArg = factory.createExpressionFromText(info.getName(), list);
@@ -486,12 +487,12 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
               continue;
             }
           }
-          newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
+          newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args, substitutor);
         }
         if (changeInfo.isArrayToVarargs()) {
           if (newVarargInitializers == null) {
             newArgs[newNonVarargCount] =
-              createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
+              createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args, substitutor);
           }
           else {
             System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
@@ -503,7 +504,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
           for (int i = newNonVarargCount; i < newArgsLength; i++){
             final int oldIndex = newParms[newNonVarargCount].getOldIndex();
             if (oldIndex >= 0 && oldIndex != nonVarargCount) {
-              newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
+              newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args, substitutor);
             } else {
               System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount);
               break;
@@ -526,7 +527,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
                                                     final PsiExpressionList list,
                                                     final JavaParameterInfo info,
                                                     final boolean toInsertDefaultValue,
-                                                    final PsiExpression[] args) throws IncorrectOperationException {
+                                                    final PsiExpression[] args,
+                                                    PsiSubstitutor substitutor) throws IncorrectOperationException {
     final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory();
     final int index = info.getOldIndex();
     if (index >= 0 && index < args.length) {
@@ -534,7 +536,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
     }
     else {
       if (toInsertDefaultValue) {
-        return createDefaultValue(changeInfo, factory, info, list);
+        return createDefaultValue(changeInfo, factory, info, list, substitutor);
       }
       else {
         return factory.createExpressionFromText(info.getName(), list);
@@ -546,7 +548,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
   private static PsiExpression createDefaultValue(JavaChangeInfo changeInfo,
                                                   final PsiElementFactory factory,
                                                   final JavaParameterInfo info,
-                                                  final PsiExpressionList list)
+                                                  final PsiExpressionList list, PsiSubstitutor substitutor)
     throws IncorrectOperationException {
     if (info.isUseAnySingleVariable()) {
       final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
@@ -593,7 +595,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
     }
     final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class);
     final String defaultValue = info.getDefaultValue();
-    return callExpression != null ? (PsiExpression)info.getActualValue(callExpression)
+    return callExpression != null ? (PsiExpression)info.getActualValue(callExpression, substitutor)
                                   : !StringUtil.isEmpty(defaultValue) ? factory.createExpressionFromText(defaultValue, list) : null;
   }
 
@@ -706,14 +708,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
   private static void addDelegateArguments(JavaChangeInfo changeInfo, PsiElementFactory factory, final PsiCallExpression callExpression) throws IncorrectOperationException {
     final JavaParameterInfo[] newParms = changeInfo.getNewParameters();
     final String[] oldParameterNames = changeInfo.getOldParameterNames();
-    for (int i = 0; i < newParms.length; i++) {
-      JavaParameterInfo newParm = newParms[i];
+    for (JavaParameterInfo newParm : newParms) {
       final PsiExpression actualArg;
       if (newParm.getOldIndex() >= 0) {
         actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression);
       }
       else {
-        actualArg = (PsiExpression)changeInfo.getActualValue(i, callExpression);
+        actualArg = (PsiExpression)newParm.getActualValue(callExpression, PsiSubstitutor.EMPTY);
       }
       final PsiExpressionList argumentList = callExpression.getArgumentList();
       if (actualArg != null && argumentList != null) {
index bc57405081720dcf8751afdf108dc8d8dcb0d156..b2dd2e8f0dbea33be2e85cf95fac21578bb0f08d 100644 (file)
@@ -34,8 +34,7 @@ public interface JavaParameterInfo extends ParameterInfo {
   PsiExpression getValue(PsiCallExpression callExpression);
 
   @Nullable
-  @Override
-  default PsiElement getActualValue(PsiElement callExpression) {
+  default PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
     return callExpression instanceof PsiCallExpression ? getValue((PsiCallExpression)callExpression) : null;
   }
 
index 5ae0546f216fda9f9289c58ba53ea77b5dfc143b..f5eb4cc76bb7b29efcf17123a3c8ed86f29259f5 100644 (file)
@@ -16,8 +16,8 @@
 package com.intellij.refactoring.inline;
 
 import com.intellij.codeInsight.ExceptionUtil;
-import com.intellij.codeInspection.sameParameterValue.SameParameterValueInspection;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Ref;
 import com.intellij.psi.*;
@@ -26,12 +26,18 @@ import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.refactoring.BaseRefactoringProcessor;
+import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase;
+import com.intellij.refactoring.changeSignature.JavaChangeInfo;
+import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl;
+import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import com.intellij.refactoring.util.CanonicalTypes;
 import com.intellij.refactoring.util.InlineUtil;
 import com.intellij.refactoring.util.RefactoringUIUtil;
 import com.intellij.refactoring.util.RefactoringUtil;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
 import com.intellij.usageView.UsageViewUtil;
+import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -53,6 +59,9 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
   private final PsiCodeBlock myCallingBlock;
   private final boolean myCreateLocal;
 
+  private JavaChangeInfo myChangeInfo;
+  private UsageInfo[] myChangeSignatureUsages;
+
   public InlineParameterExpressionProcessor(final PsiCallExpression methodCall,
                                             final PsiMethod method,
                                             final PsiParameter parameter,
@@ -147,6 +156,28 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
       }
     }
 
+
+    final PsiParameter[] parameters = myMethod.getParameterList().getParameters();
+    final List<ParameterInfoImpl> psiParameters = new ArrayList<ParameterInfoImpl>();
+    int paramIdx = 0;
+    final String paramName = myParameter.getName();
+    for (PsiParameter param : parameters) {
+      if (!Comparing.strEqual(paramName, param.getName())) {
+        psiParameters.add(new ParameterInfoImpl(paramIdx, param.getName(), param.getType()));
+      }
+      paramIdx++;
+    }
+
+    PsiType returnType = myMethod.getReturnType();
+    myChangeInfo = new JavaChangeInfoImpl(VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()), myMethod, myMethod.getName(),
+                                          returnType != null ? CanonicalTypes.createTypeWrapper(returnType) : null,
+                                          psiParameters.toArray(new ParameterInfoImpl[psiParameters.size()]),
+                                          null,
+                                          false,
+                                          Collections.emptySet(),
+                                          Collections.emptySet() );
+    myChangeSignatureUsages = ChangeSignatureProcessorBase.findUsages(myChangeInfo);
+
     final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
     return UsageViewUtil.removeDuplicatedUsages(usageInfos);
   }
@@ -267,7 +298,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
       }
     }
 
-    SameParameterValueInspection.InlineParameterValueFix.removeParameter(myMethod, myParameter);
+    ChangeSignatureProcessorBase.doChangeSignature(myChangeInfo, myChangeSignatureUsages);
 
     if (!thrownExceptions.isEmpty()) {
       for (PsiClassType exception : thrownExceptions) {
index f19c14328faddcbcf4197ef063c46b2b0024a00b..ef2387ea2f8f4aff7f3fe20fb04196edee39037d 100644 (file)
@@ -32,20 +32,19 @@ import com.intellij.refactoring.MoveDestination;
 import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
 import com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectClassDescriptor;
 import com.intellij.refactoring.introduceParameterObject.IntroduceParameterObjectDelegate;
-import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.HashMap;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
 public class JavaIntroduceParameterObjectClassDescriptor extends IntroduceParameterObjectClassDescriptor<PsiMethod, ParameterInfoImpl> {
   private static final Logger LOG = Logger.getInstance("#" + JavaIntroduceParameterObjectClassDescriptor.class.getName());
-  private final Set<PsiTypeParameter> myTypeParameters = new HashSet<>();
+  private final Set<PsiTypeParameter> myTypeParameters = new LinkedHashSet<>();
   private final Map<ParameterInfoImpl, ParameterBean> myExistingClassProperties = new HashMap<>();
   private final MoveDestination myMoveDestination;
 
@@ -106,12 +105,7 @@ public class JavaIntroduceParameterObjectClassDescriptor extends IntroduceParame
   public String createFakeClassTypeText() {
     String text = StringUtil.getQualifiedName(getPackageName(), getClassName());
     if (!myTypeParameters.isEmpty()) {
-      text += "<" + StringUtil.join(myTypeParameters, new Function<PsiTypeParameter, String>() {
-        @Override
-        public String fun(PsiTypeParameter parameter) {
-          return parameter.getName();
-        }
-      }, ", ") + ">";
+      text += "<" + StringUtil.join(myTypeParameters, PsiNamedElement::getName, ", ") + ">";
     }
     return text;
   }
index 713afe952eb59ac18f34c5ddcb4432c2d68eac29..09ce3b828eaf04e493c49fcffb8fcedffd567f25 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.impl.PsiDiamondTypeUtil;
 import com.intellij.psi.search.LocalSearchScope;
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -42,6 +43,7 @@ import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -86,9 +88,9 @@ public class JavaIntroduceParameterObjectDelegate
     return new ParameterInfoImpl(-1, paramName, facade.getElementFactory().createTypeFromText(classTypeText, method), null) {
       @Nullable
       @Override
-      public PsiElement getActualValue(PsiElement exp) {
+      public PsiElement getActualValue(PsiElement exp, Object substitutor) {
         final IntroduceParameterObjectDelegate<PsiNamedElement, ParameterInfo, IntroduceParameterObjectClassDescriptor<PsiNamedElement, ParameterInfo>> delegate = findDelegate(exp);
-        return delegate != null ? delegate.createNewParameterInitializerAtCallSite(exp, descriptor, oldMethodParameters) : null;
+        return delegate != null ? delegate.createNewParameterInitializerAtCallSite(exp, descriptor, oldMethodParameters, substitutor) : null;
       }
     };
   }
@@ -96,7 +98,8 @@ public class JavaIntroduceParameterObjectDelegate
   @Override
   public PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
                                                             IntroduceParameterObjectClassDescriptor descriptor,
-                                                            List<? extends ParameterInfo> oldMethodParameters) {
+                                                            List<? extends ParameterInfo> oldMethodParameters,
+                                                            Object substitutor) {
     if (callExpression instanceof PsiCallExpression) {
       final PsiCallExpression expr = (PsiCallExpression)callExpression;
       final JavaPsiFacade facade = JavaPsiFacade.getInstance(expr.getProject());
@@ -109,16 +112,31 @@ public class JavaIntroduceParameterObjectDelegate
 
       final PsiExpression[] args = argumentList.getExpressions();
       StringBuilder newExpression = new StringBuilder();
-      final JavaResolveResult resolvant = expr.resolveMethodGenerics();
-      final PsiSubstitutor substitutor = resolvant.getSubstitutor();
-      newExpression.append("new ")
-        .append(JavaPsiFacade.getElementFactory(expr.getProject()).createType(existingClass, substitutor).getCanonicalText());
+      newExpression.append("new ").append(existingClass.getQualifiedName());
+      if (descriptor instanceof JavaIntroduceParameterObjectClassDescriptor) {
+        List<String> types = new ArrayList<>();
+        for (PsiTypeParameter parameter : ((JavaIntroduceParameterObjectClassDescriptor)descriptor).getTypeParameters()) {
+          PsiType type = ((PsiSubstitutor)substitutor).substitute(parameter);
+          if (type == null) {
+            types.clear();
+            break;
+          }
+          types.add(type.getCanonicalText());
+        }
+        if (!types.isEmpty()) {
+          newExpression.append("<").append(StringUtil.join(types, ", ")).append(">");
+        }
+      }
       newExpression.append('(');
       newExpression.append(getMergedArgs(descriptor, oldMethodParameters, args));
       newExpression.append(')');
 
-      return JavaCodeStyleManager.getInstance(callExpression.getProject())
+      PsiNewExpression newClassExpression = (PsiNewExpression)JavaCodeStyleManager.getInstance(callExpression.getProject())
         .shortenClassReferences(facade.getElementFactory().createExpressionFromText(newExpression.toString(), expr));
+      if (PsiDiamondTypeUtil.canChangeContextForDiamond(newClassExpression, newClassExpression.getType())) {
+        PsiDiamondTypeUtil.replaceExplicitWithDiamond(newClassExpression.getClassOrAnonymousClassReference().getParameterList());
+      }
+      return newClassExpression;
     }
     return null;
   }
index ae0fc205a68c47f29a03ea08716d7b9a7a08bb01..ac91a848aae801910fb18833dbabb59854134adc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -137,8 +137,8 @@ class ParameterObjectBuilder {
             out.append(CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS ? " final " : "");
             final String parameterName = parameter.getName();
           final PsiType type = field.getType();
-          final PsiType fieldType = parameter.isVarArgs() && type instanceof PsiArrayType ? 
-                                    PsiEllipsisType.createEllipsis(((PsiArrayType)type).getComponentType(), PsiAnnotation.EMPTY_ARRAY) : type;
+          final PsiType fieldType = parameter.isVarArgs() && type instanceof PsiArrayType ?
+                                    new PsiEllipsisType(((PsiArrayType)type).getComponentType()) : type;
             out.append(' ' + fieldType.getCanonicalText() + ' ' + parameterName);
             if (iterator.hasNext()) {
                 out.append(", ");
index 8f48d192d81f7c5a153592d9510f1ed32e43feb8..d37425b05967b5912eb775a747af439034d60699 100644 (file)
@@ -385,7 +385,7 @@ public class RefactoringUtil {
   public static PsiType getTypeByExpressionWithExpectedType(PsiExpression expr) {
     PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
     PsiType type = getTypeByExpression(expr, factory);
-    final boolean isFunctionalType = type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType || type instanceof PsiLambdaParameterType;
+    final boolean isFunctionalType = LambdaUtil.notInferredType(type);
     final boolean isDenotable = PsiTypesUtil.isDenotableType(expr.getType());
     if (type != null && !isFunctionalType && isDenotable) {
       return type;
@@ -404,9 +404,7 @@ public class RefactoringUtil {
   public static PsiType getTypeByExpression(PsiExpression expr) {
     PsiElementFactory factory = JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
     PsiType type = getTypeByExpression(expr, factory);
-    if (type instanceof PsiLambdaParameterType ||
-        type instanceof PsiLambdaExpressionType ||
-        type instanceof PsiMethodReferenceType) {
+    if (LambdaUtil.notInferredType(type)) {
       type = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, expr.getResolveScope());
     }
     return type;
index 4a8655419bd34393f1c8eed6575ff36857a0e91b..b24655b12bdea7c78bb7ccf6632f44cbf9fecf01 100644 (file)
@@ -59,8 +59,6 @@ public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiM
 
       for (String name : potentials.keySet()) {
         ProgressManager.checkCanceled();
-        if (inheritor.findMethodsByName(name, true).length == 0) continue;
-
         for (PsiMethod superMethod : potentials.get(name)) {
           ProgressManager.checkCanceled();
           if (superMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) &&
index 94ba3199fa094f5acfa2b89346995a07f6d8ee98..959e9814c8d13bac6dc379502023b25c8bd843c7 100644 (file)
 package com.intellij.psi.impl.search;
 
 import com.intellij.lang.spi.SPILanguage;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
 import com.intellij.psi.*;
 import com.intellij.psi.search.FilenameIndex;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -30,73 +28,46 @@ import com.intellij.util.Processor;
 import org.jetbrains.annotations.NotNull;
 
 public class SPIReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
+  public SPIReferencesSearcher() {
+    super(true);
+  }
+
   @Override
   public void processQuery(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
-    final SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
-      @Override
-      public SearchScope compute() {
-        return p.getEffectiveSearchScope();
-      }
-    });
-    if (!(scope instanceof GlobalSearchScope)) return;
-    
     final PsiElement element = p.getElementToSearch();
+    if (!element.isValid()) return;
+
+    final SearchScope scope = p.getEffectiveSearchScope();
+    if (!(scope instanceof GlobalSearchScope)) return;
+
     if (element instanceof PsiClass) {
       final PsiClass aClass = (PsiClass)element;
-      final String jvmClassName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
-        @Override
-        public String compute() {
-          return ClassUtil.getJVMClassName(aClass);
-        }
-      });
+      final String jvmClassName = ClassUtil.getJVMClassName(aClass);
 
       if (jvmClassName == null) return;
-      final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
-        @Override
-        public PsiFile[] compute() {
-          return FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope);
-        }
-      });
+      final PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope);
       for (PsiFile file : files) {
         if (file.getLanguage() == SPILanguage.INSTANCE) {
           final PsiReference reference = file.getReference();
           if (reference != null) {
-            ApplicationManager.getApplication().runReadAction(new Runnable() {
-              @Override
-              public void run() {
-                consumer.process(reference);
-              }
-            });
+            consumer.process(reference);
           }
         }
       }
-    } else if (element instanceof PsiPackage) {
+    }
+    else if (element instanceof PsiPackage) {
       final String qualifiedName = ((PsiPackage)element).getQualifiedName();
       final Project project = element.getProject();
-      final String[] filenames = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
-        @Override
-        public String[] compute() {
-          return FilenameIndex.getAllFilenames(project);
-        }
-      });
+      final String[] filenames = FilenameIndex.getAllFilenames(project);
       for (final String filename : filenames) {
         if (filename.startsWith(qualifiedName + ".")) {
-          final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
-            @Override
-            public PsiFile[] compute() {
-              return FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope);
-            }
-          });
+          final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope);
           for (PsiFile file : files) {
             if (file.getLanguage() == SPILanguage.INSTANCE) {
               final PsiReference[] references = file.getReferences();
               for (final PsiReference reference : references) {
                 if (reference.getCanonicalText().equals(qualifiedName)) {
-                  ApplicationManager.getApplication().runReadAction(new Runnable() {
-                    public void run() {
-                      consumer.process(reference);
-                    }
-                  });
+                  consumer.process(reference);
                 }
               }
             }
index aaf7141512ab2c45417c936e9d44637dd4cdd075..aa050b3113599e8b8a7baf586b22e6632fc04c25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -376,11 +376,14 @@ public class GenericsUtil {
           LOG.assertTrue(toPut == null || toPut.isValid(), toPut);
           substitutor = substitutor.put(typeParameter, toPut);
         }
-        final PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
-        if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0 && !(aClass instanceof PsiTypeParameter)) return classType;
+        PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
+        if (substitutor == PsiSubstitutor.EMPTY && !toExtend && applicableAnnotations.length == 0 && !(aClass instanceof PsiTypeParameter)) {
+          return classType;
+        }
         PsiManager manager = aClass.getManager();
         PsiType result = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory()
-          .createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass), applicableAnnotations);
+          .createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass))
+          .annotate(TypeAnnotationProvider.Static.create(applicableAnnotations));
         if (toExtend) result = PsiWildcardType.createExtends(manager, result);
         return result;
       }
index 7c3999e37a7b5f7f9fb7a5de922cb5c2de348eba..6b1f4f8532b5d0f2318bd438f9dfc024e91cd601 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ public interface JVMElementFactory {
    *
    * @param name the name of the class to create.
    * @return the created class instance.
-   * @throws com.intellij.util.IncorrectOperationException
+   * @throws IncorrectOperationException
    *          if <code>name</code> is not a valid Java identifier.
    */
   @NotNull
@@ -175,7 +175,7 @@ public interface JVMElementFactory {
    *
    * @param name the name of the annotation type to create.
    * @return the created annotation type instance.
-   * @throws com.intellij.util.IncorrectOperationException if <code>name</code> is not a valid Java identifier.
+   * @throws IncorrectOperationException if <code>name</code> is not a valid Java identifier.
    */
   @NotNull
   PsiClass createAnnotationType(@NotNull @NonNls String name) throws IncorrectOperationException;
@@ -201,13 +201,20 @@ public interface JVMElementFactory {
   @NotNull
   PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor);
 
-  /*
-   additional languageLevel parameter to memorize language level for allowing/prohibiting boxing/unboxing
-  */
+  /**
+   * Creates a class type for the specified class, using the specified substitutor
+   * to replace generic type parameters on the class.
+   *
+   * @param resolve       the class for which the class type is created.
+   * @param substitutor   the substitutor to use.
+   * @param languageLevel to memorize language level for allowing/prohibiting boxing/unboxing.
+   * @return the class type instance.
+   */
   @NotNull
   PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @NotNull LanguageLevel languageLevel);
 
-  @NotNull
+  /** @deprecated use {@link PsiType#annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
+  @SuppressWarnings("unused")
   PsiClassType createType(@NotNull PsiClass resolve,
                           @NotNull PsiSubstitutor substitutor,
                           @NotNull LanguageLevel languageLevel,
index 71292309cfc43f5a902d06fb021734df53198dc2..5019d5b57fed6839924adee4c8ffd6ee1a02f337 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,24 +26,26 @@ import org.jetbrains.annotations.NotNull;
 public class PsiArrayType extends PsiType.Stub {
   private final PsiType myComponentType;
 
-  /**
-   * Creates an array type with the specified component type.
-   *
-   * @param componentType the type of the array component.
-   */
   public PsiArrayType(@NotNull PsiType componentType) {
-    this(componentType, PsiAnnotation.EMPTY_ARRAY);
+    this(componentType, TypeAnnotationProvider.EMPTY);
   }
 
   public PsiArrayType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
     super(annotations);
     myComponentType = componentType;
   }
-  public PsiArrayType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider annotations) {
-    super(annotations);
+
+  public PsiArrayType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider provider) {
+    super(provider);
     myComponentType = componentType;
   }
 
+  @NotNull
+  @Override
+  public PsiArrayType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiArrayType(myComponentType, provider);
+  }
+
   @NotNull
   @Override
   public String getPresentableText() {
@@ -117,13 +119,15 @@ public class PsiArrayType extends PsiType.Stub {
     return myComponentType;
   }
 
+  @Override
   public boolean equals(Object obj) {
     return obj instanceof PsiArrayType &&
            (this instanceof PsiEllipsisType == obj instanceof PsiEllipsisType) &&
            myComponentType.equals(((PsiArrayType)obj).getComponentType());
   }
 
+  @Override
   public int hashCode() {
     return myComponentType.hashCode() * 3;
   }
-}
+}
\ No newline at end of file
index b9d13bc76073b8e72af66968aba7ea55f82affc9..c69c9250b8a2b81631cf880630afe89ef1898593 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
   private PsiCapturedWildcardType(@NotNull PsiWildcardType existential,
                                   @NotNull PsiElement context,
                                   @Nullable PsiTypeParameter parameter) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
     myExistential = existential;
     myContext = context;
     myParameter = parameter;
@@ -208,4 +208,4 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
   public PsiTypeParameter getTypeParameter() {
     return myParameter;
   }
-}
+}
\ No newline at end of file
index 8a322bca993beb1e02370e8bfd6ceb4764c132bd..4c11523f2c4623b600a545c7302e99ec8cd825e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -30,9 +30,6 @@ import org.jetbrains.annotations.Nullable;
  * @author max
  */
 public abstract class PsiClassType extends PsiType {
-  /**
-   * The empty array of PSI class types which can be reused to avoid unnecessary allocations.
-   */
   public static final PsiClassType[] EMPTY_ARRAY = new PsiClassType[0];
   public static final ArrayFactory<PsiClassType> ARRAY_FACTORY = new ArrayFactory<PsiClassType>() {
     @NotNull
@@ -53,11 +50,17 @@ public abstract class PsiClassType extends PsiType {
     myLanguageLevel = languageLevel;
   }
 
-  public PsiClassType(LanguageLevel languageLevel, @NotNull TypeAnnotationProvider annotations) {
-    super(annotations);
+  public PsiClassType(LanguageLevel languageLevel, @NotNull TypeAnnotationProvider provider) {
+    super(provider);
     myLanguageLevel = languageLevel;
   }
 
+  @NotNull
+  @Override
+  public PsiClassType annotate(@NotNull TypeAnnotationProvider provider) {
+    return (PsiClassType)super.annotate(provider);
+  }
+
   /**
    * Resolves the class reference and returns the resulting class.
    *
@@ -221,7 +224,7 @@ public abstract class PsiClassType extends PsiType {
   public abstract PsiClassType rawType();
 
   /**
-   * Overrides {@link com.intellij.psi.PsiType#getResolveScope()} to narrow specify @NotNull.
+   * Overrides {@link PsiType#getResolveScope()} to narrow specify @NotNull.
    */
   @Override
   @NotNull
@@ -314,4 +317,4 @@ public abstract class PsiClassType extends PsiType {
     @Override
     public abstract String getCanonicalText(boolean annotated);
   }
-}
+}
\ No newline at end of file
index bc71843ee20b4cf7f0b5879bbe82a0f18486325e..8b92ec95a3ae347b6ba415d6897d25fecaac7da4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@ import java.util.List;
 public abstract class PsiDiamondType extends PsiType {
   public static final RecursionGuard ourDiamondGuard = RecursionManager.createGuard("diamondInference");
 
-  public PsiDiamondType(PsiAnnotation[] annotations) {
-    super(annotations);
+  public PsiDiamondType() {
+    super(TypeAnnotationProvider.EMPTY);
   }
 
   public abstract DiamondInferenceResult resolveInferredTypes();
index 2b5299e353276e76f41e1e9af71431fdc51f27a9..d2c4a2ea06511914066cde78bd5d73c533ada147 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ public class PsiDisjunctionType extends PsiType.Stub {
   private final CachedValue<PsiType> myLubCache;
 
   public PsiDisjunctionType(@NotNull List<PsiType> types, @NotNull PsiManager psiManager) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
 
     myManager = psiManager;
     myTypes = Collections.unmodifiableList(types);
@@ -168,4 +168,4 @@ public class PsiDisjunctionType extends PsiType.Stub {
 
     return true;
   }
-}
+}
\ No newline at end of file
index 41ac7289824532080da2667cdc90d49f64117b1e..404a39672972da01de2066133ee54e0ad6084c43 100644 (file)
@@ -178,12 +178,6 @@ public interface PsiElementFactory extends PsiJavaParserFacade, JVMElementFactor
   @Override
   @NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel);
 
-  @Override
-  @NotNull PsiClassType createType(@NotNull PsiClass resolve,
-                                   @NotNull PsiSubstitutor substitutor,
-                                   @Nullable LanguageLevel languageLevel,
-                                   @NotNull PsiAnnotation[] annotations);
-
   /**
    * Creates a class type for the specified reference pointing to a class.
    *
index b00ece6a779841e4635f9079beb480dcce389154..0738462ee21c90b55392a6c2c9b80f96b4564e2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,11 +23,6 @@ import org.jetbrains.annotations.NotNull;
  * @author ven
  */
 public class PsiEllipsisType extends PsiArrayType {
-  /**
-   * Creates an ellipsis type instance with the specified component type.
-   *
-   * @param componentType the type of the varargs array component.
-   */
   public PsiEllipsisType(@NotNull PsiType componentType) {
     super(componentType);
   }
@@ -35,11 +30,19 @@ public class PsiEllipsisType extends PsiArrayType {
   public PsiEllipsisType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
     super(componentType, annotations);
   }
-  public PsiEllipsisType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider annotations) {
-    super(componentType, annotations);
+
+  public PsiEllipsisType(@NotNull PsiType componentType, @NotNull TypeAnnotationProvider provider) {
+    super(componentType, provider);
   }
 
   @NotNull
+  @Override
+  public PsiEllipsisType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiEllipsisType(getComponentType(), provider);
+  }
+
+  /** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
+  @SuppressWarnings("unused")
   public static PsiType createEllipsis(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
     return new PsiEllipsisType(componentType, annotations);
   }
@@ -82,7 +85,8 @@ public class PsiEllipsisType extends PsiArrayType {
     return visitor.visitEllipsisType(this);
   }
 
+  @Override
   public int hashCode() {
     return super.hashCode() * 5;
   }
-}
+}
\ No newline at end of file
index f46e68012ed940778db6f3761d93d92fec804386..0adc5e1c79e9314b4cdc9f4e1b3e93a1c4824133 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class PsiIntersectionType extends PsiType.Stub {
   private final PsiType[] myConjuncts;
 
   private PsiIntersectionType(@NotNull PsiType[] conjuncts) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
     myConjuncts = conjuncts;
   }
 
@@ -176,6 +176,7 @@ public class PsiIntersectionType extends PsiType.Stub {
     return myConjuncts[0];
   }
 
+  @Override
   public boolean equals(final Object obj) {
     if (this == obj) return true;
     if (!(obj instanceof PsiIntersectionType)) return false;
@@ -190,6 +191,7 @@ public class PsiIntersectionType extends PsiType.Stub {
     return true;
   }
 
+  @Override
   public int hashCode() {
     return myConjuncts[0].hashCode();
   }
@@ -221,4 +223,4 @@ public class PsiIntersectionType extends PsiType.Stub {
     }
     return null;
   }
-}
+}
\ No newline at end of file
index 70d7d3f46bd3130e8107e4ac8f236cbd1868d0f0..64fe93db80d449166d1847ecf475ab3a08e2abbe 100644 (file)
@@ -235,11 +235,14 @@ public interface PsiJavaParserFacade {
   /**
    * Creates a Java type from the specified text.
    *
-   * @param text        the text of the type to create (a primitive type keyword).
-   * @param annotations array (possible empty) of annotations to annotate the created type.
+   * @param text the text of the type to create (a primitive type keyword).
    * @return the created type instance.
    * @throws IncorrectOperationException if some of the parameters are not valid.
    */
   @NotNull
+  PsiType createPrimitiveTypeFromText(@NotNull String text) throws IncorrectOperationException;
+
+  /** @deprecated use {@link PsiType#annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
+  @SuppressWarnings("unused")
   PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException;
 }
\ No newline at end of file
index db9db62596c1d0a39c4f37409341d7cece513db6..7f6b0e7e53d2462304e27b698ed0f02717fd21a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ public class PsiLambdaExpressionType extends PsiType {
   private final PsiLambdaExpression myExpression;
 
   public PsiLambdaExpressionType(PsiLambdaExpression expression) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
     myExpression = expression;
   }
 
@@ -77,4 +77,4 @@ public class PsiLambdaExpressionType extends PsiType {
   public PsiLambdaExpression getExpression() {
     return myExpression;
   }
-}
+}
\ No newline at end of file
index 6a1991c60b3941ccd4903dec11a6b510ca3549d1..9d0e550c6feb207090c03ee0ec4ee4a26871ccc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ public class PsiLambdaParameterType extends PsiType {
   private final PsiParameter myParameter;
 
   public PsiLambdaParameterType(PsiParameter parameter) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
     myParameter = parameter;
   }
 
@@ -77,4 +77,4 @@ public class PsiLambdaParameterType extends PsiType {
   public PsiParameter getParameter() {
     return myParameter;
   }
-}
+}
\ No newline at end of file
index 82854ddffb85aab566237e1a7f32a9582a64aeb2..1862c29a916c2c89edaa5d978010c6bcb5eb5bef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiUtil;
 import gnu.trove.THashMap;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -36,23 +35,30 @@ public class PsiPrimitiveType extends PsiType.Stub {
 
   private final String myName;
 
-  PsiPrimitiveType(@NonNls @NotNull String name, @NonNls String boxedName) {
-    this(name, PsiAnnotation.EMPTY_ARRAY);
+  PsiPrimitiveType(@NotNull String name, String boxedName) {
+    this(name, TypeAnnotationProvider.EMPTY);
     if (boxedName != null) {
       ourQNameToUnboxed.put(boxedName, this);
       ourUnboxedToQName.put(this, boxedName);
     }
   }
 
-  public PsiPrimitiveType(@NonNls @NotNull String name, @NotNull PsiAnnotation[] annotations) {
+  public PsiPrimitiveType(@NotNull String name, @NotNull PsiAnnotation[] annotations) {
     super(annotations);
     myName = name;
   }
-  public PsiPrimitiveType(@NonNls @NotNull String name, @NotNull TypeAnnotationProvider annotations) {
-    super(annotations);
+
+  public PsiPrimitiveType(@NotNull String name, @NotNull TypeAnnotationProvider provider) {
+    super(provider);
     myName = name;
   }
 
+  @NotNull
+  @Override
+  public PsiPrimitiveType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiPrimitiveType(myName, provider);
+  }
+
   @NotNull
   @Override
   public String getPresentableText() {
@@ -119,19 +125,18 @@ public class PsiPrimitiveType extends PsiType.Stub {
   @Nullable
   public static PsiPrimitiveType getUnboxedType(PsiType type) {
     if (!(type instanceof PsiClassType)) return null;
+
+    assert type.isValid() : type;
     LanguageLevel languageLevel = ((PsiClassType)type).getLanguageLevel();
     if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;
 
-    assert type.isValid() : type;
     PsiClass psiClass = ((PsiClassType)type).resolve();
     if (psiClass == null) return null;
 
     PsiPrimitiveType unboxed = ourQNameToUnboxed.get(psiClass.getQualifiedName());
-    PsiAnnotation[] annotations = type.getAnnotations();
-    if (unboxed != null && annotations.length > 0) {
-      unboxed = new PsiPrimitiveType(unboxed.myName, annotations);
-    }
-    return unboxed;
+    if (unboxed == null) return null;
+
+    return unboxed.annotate(type.getAnnotationProvider());
   }
 
   public String getBoxedTypeName() {
@@ -146,31 +151,30 @@ public class PsiPrimitiveType extends PsiType.Stub {
    *         it was not possible to resolve the reference to the class.
    */
   @Nullable
-  public PsiClassType getBoxedType(PsiElement context) {
+  public PsiClassType getBoxedType(@NotNull PsiElement context) {
     PsiFile file = context.getContainingFile();
     LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
     if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;
 
     String boxedQName = getBoxedTypeName();
-    //[ven]previous call returns null for NULL, VOID
     if (boxedQName == null) return null;
+
     JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
     PsiClass aClass = facade.findClass(boxedQName, file.getResolveScope());
     if (aClass == null) return null;
 
     PsiElementFactory factory = facade.getElementFactory();
-    return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel, getAnnotations());
+    return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel).annotate(getAnnotationProvider());
   }
 
   @Nullable
-  public PsiClassType getBoxedType(final PsiManager manager, final GlobalSearchScope resolveScope) {
-    final String boxedQName = getBoxedTypeName();
-
-    //[ven]previous call returns null for NULL, VOID
+  public PsiClassType getBoxedType(@NotNull PsiManager manager, @NotNull GlobalSearchScope resolveScope) {
+    String boxedQName = getBoxedTypeName();
     if (boxedQName == null) return null;
 
-    final PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(boxedQName, resolveScope);
+    PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(boxedQName, resolveScope);
     if (aClass == null) return null;
+
     return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(aClass);
   }
 
@@ -187,4 +191,4 @@ public class PsiPrimitiveType extends PsiType.Stub {
   public boolean equals(Object obj) {
     return obj instanceof PsiPrimitiveType && myName.equals(((PsiPrimitiveType)obj).myName);
   }
-}
+}
\ No newline at end of file
index 3c59fd2633e9d11c4b0c5627a1127fd2ec3c574a..6220ffd8cba1a89f8a83b7529de455a7e2d1be30 100644 (file)
@@ -56,13 +56,7 @@ public abstract class PsiType implements PsiAnnotationOwner {
    * Constructs a PsiType with given annotations
    */
   protected PsiType(@NotNull final PsiAnnotation[] annotations) {
-    this(annotations.length == 0 ? TypeAnnotationProvider.EMPTY : new TypeAnnotationProvider() {
-      @NotNull
-      @Override
-      public PsiAnnotation[] getAnnotations() {
-        return annotations;
-      }
-    });
+    this(TypeAnnotationProvider.Static.create(annotations));
   }
 
   /**
@@ -72,6 +66,11 @@ public abstract class PsiType implements PsiAnnotationOwner {
     myAnnotationProvider = annotations;
   }
 
+  @NotNull
+  public PsiType annotate(@NotNull TypeAnnotationProvider provider) {
+    throw new UnsupportedOperationException("Not implemented for " + getClass());
+  }
+
   /**
    * Creates array type with this type as a component.
    */
@@ -80,10 +79,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
     return new PsiArrayType(this);
   }
 
-  /**
-   * Creates array type with this type as a component.
-   */
-  @NotNull
+  /** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
+  @SuppressWarnings("unused")
   public PsiArrayType createArrayType(@NotNull PsiAnnotation... annotations) {
     return new PsiArrayType(this, annotations);
   }
index f5c199de6642e56abe08749744de15a769ec061f..263f02029ce4e961c2640506468d330cd33c12d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ public class PsiWildcardType extends PsiType.Stub {
   public static final String EXTENDS_PREFIX = "? extends ";
   public static final String SUPER_PREFIX = "? super ";
 
-  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiWildcardType");
+  private static final Logger LOG = Logger.getInstance(PsiWildcardType.class);
   private static final Key<PsiWildcardType> UNBOUNDED_WILDCARD = new Key<PsiWildcardType>("UNBOUNDED_WILDCARD");
 
   private final PsiManager myManager;
@@ -39,14 +39,14 @@ public class PsiWildcardType extends PsiType.Stub {
   private final PsiType myBound;
 
   private PsiWildcardType(@NotNull PsiManager manager, boolean isExtending, @Nullable PsiType bound) {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
     myManager = manager;
     myIsExtending = isExtending;
     myBound = bound;
   }
 
-  private PsiWildcardType(@NotNull PsiWildcardType type, @NotNull TypeAnnotationProvider annotations) {
-    super(annotations);
+  private PsiWildcardType(@NotNull PsiWildcardType type, @NotNull TypeAnnotationProvider provider) {
+    super(provider);
     myManager = type.myManager;
     myIsExtending = type.myIsExtending;
     myBound = type.myBound;
@@ -75,20 +75,16 @@ public class PsiWildcardType extends PsiType.Stub {
     return new PsiWildcardType(manager, false, bound);
   }
 
-  @NotNull
+  /** @deprecated use {@link #annotate(TypeAnnotationProvider)} (to be removed in IDEA 18) */
+  @SuppressWarnings("unused")
   public PsiWildcardType annotate(@NotNull final PsiAnnotation[] annotations) {
-    return annotations.length == 0 ? this : new PsiWildcardType(this, new TypeAnnotationProvider() {
-      @NotNull
-      @Override
-      public PsiAnnotation[] getAnnotations() {
-        return annotations;
-      }
-    });
+    return annotations.length == 0 ? this : new PsiWildcardType(this, TypeAnnotationProvider.Static.create(annotations));
   }
 
   @NotNull
-  public PsiWildcardType annotate(@NotNull final TypeAnnotationProvider annotations) {
-    return new PsiWildcardType(this, annotations);
+  @Override
+  public PsiWildcardType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiWildcardType(this, provider);
   }
 
   @NotNull
@@ -261,4 +257,4 @@ public class PsiWildcardType extends PsiType.Stub {
   public PsiType getSuperBound() {
     return myBound == null || myIsExtending ? NULL : myBound;
   }
-}
+}
\ No newline at end of file
index 8184778ee46c1cad9735498402b9f455794c9a42..05600cffde2f0488969f6f036c964a8ce3f59c76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,4 +36,24 @@ public interface TypeAnnotationProvider {
 
   @NotNull
   PsiAnnotation[] getAnnotations();
-}
+
+
+  class Static implements TypeAnnotationProvider {
+    private final PsiAnnotation[] myAnnotations;
+
+    private Static(PsiAnnotation[] annotations) {
+      myAnnotations = annotations;
+    }
+
+    @NotNull
+    @Override
+    public PsiAnnotation[] getAnnotations() {
+      return myAnnotations;
+    }
+
+    @NotNull
+    public static TypeAnnotationProvider create(@NotNull PsiAnnotation[] annotations) {
+      return annotations.length == 0 ? EMPTY : new Static(annotations);
+    }
+  }
+}
\ No newline at end of file
index d2fc5de10594a6ed9a923c0e1dfbe6c1b2d3aa62..532dda378f079b6187304d27b4a755d4b010f6b1 100644 (file)
@@ -142,8 +142,9 @@ public abstract class PsiAugmentProvider {
   }
 
   private static void forEach(Project project, Processor<PsiAugmentProvider> processor) {
+    boolean dumb = DumbService.isDumb(project);
     for (PsiAugmentProvider provider : Extensions.getExtensions(EP_NAME)) {
-      if (!DumbService.isDumb(project) || DumbService.isDumbAware(provider)) {
+      if (!dumb || DumbService.isDumbAware(provider)) {
         try {
           boolean goOn = processor.process(provider);
           if (!goOn) break;
index 022c8636800a9668aea4779e3fcb454fee69a2b1..c128579b50cc0f705b2672ebff4c0bf026593f37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ public class Bottom extends PsiType {
   public static final Bottom BOTTOM = new Bottom();
 
   private Bottom() {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
   }
 
   @NotNull
@@ -56,12 +56,9 @@ public class Bottom extends PsiType {
     return text.equals("_");
   }
 
+  @Override
   public boolean equals(Object o) {
-    if (o instanceof Bottom) {
-      return true;
-    }
-
-    return false;
+    return o instanceof Bottom;
   }
 
   @Override
@@ -84,4 +81,4 @@ public class Bottom extends PsiType {
   public GlobalSearchScope getResolveScope() {
     return null;
   }
-}
+}
\ No newline at end of file
index 45dcee6e9460481fb6df9bc6ef71e8d698fed7f4..537a4dcf5759fe74c15c66777fed9b43d89661af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,13 +47,12 @@ import java.util.*;
  * @since Jul 30, 2010
  */
 public class PsiDiamondTypeImpl extends PsiDiamondType {
-  private static final Logger LOG = Logger.getInstance("#" + PsiDiamondTypeImpl.class.getName());
+  private static final Logger LOG = Logger.getInstance(PsiDiamondTypeImpl.class);
 
   private final PsiManager myManager;
   private final PsiTypeElement myTypeElement;
 
   public PsiDiamondTypeImpl(PsiManager manager, PsiTypeElement psiTypeElement) {
-    super(PsiAnnotation.EMPTY_ARRAY);
     myManager = manager;
     myTypeElement = psiTypeElement;
   }
@@ -134,9 +133,9 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
 
     final DiamondInferenceResult inferenceResult = resolveInferredTypesNoCheck(newExpression, context);
     if (anonymousClass != null && PsiUtil.isLanguageLevel9OrHigher(newExpression)) {
-      final InferredAnonymTypeVisitor anonymTypeVisitor = new InferredAnonymTypeVisitor(context);
+      final InferredAnonymousTypeVisitor anonymousTypeVisitor = new InferredAnonymousTypeVisitor(context);
       for (PsiType type : inferenceResult.getInferredTypes()) {
-        final Boolean accepted = type.accept(anonymTypeVisitor);
+        final Boolean accepted = type.accept(anonymousTypeVisitor);
         if (accepted != null && !accepted.booleanValue()) {
           return PsiDiamondTypeImpl.DiamondInferenceResult.ANONYMOUS_INNER_RESULT;
         } 
@@ -150,17 +149,16 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
     final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, new Computable<PsiSubstitutor>() {
       @Override
       public PsiSubstitutor compute() {
-        final JavaResolveResult staticFactoryCandidateInfo = context == newExpression ? 
-                                                               CachedValuesManager.getCachedValue(newExpression,
-                                                                                                  new CachedValueProvider<JavaResolveResult>() {
-                                                                                                    @Nullable
-                                                                                                    @Override
-                                                                                                    public Result<JavaResolveResult> compute() {
-                                                                                                      return new Result<JavaResolveResult>(getStaticFactoryCandidateInfo(newExpression, newExpression), 
-                                                                                                                                           PsiModificationTracker.MODIFICATION_COUNT);
-                                                                                                    }
-                                                                                                  }) 
-                                                                                        : getStaticFactoryCandidateInfo(newExpression, context);
+        final JavaResolveResult staticFactoryCandidateInfo =
+          context == newExpression
+          ? CachedValuesManager.getCachedValue(newExpression, new CachedValueProvider<JavaResolveResult>() {
+            @Nullable
+            @Override
+            public Result<JavaResolveResult> compute() {
+              return new Result<JavaResolveResult>(getStaticFactoryCandidateInfo(newExpression, newExpression), PsiModificationTracker.MODIFICATION_COUNT);
+            }
+          })
+          : getStaticFactoryCandidateInfo(newExpression, context);
         staticFactoryRef.set(staticFactoryCandidateInfo);
         if (staticFactoryCandidateInfo != null) {
           PsiSubstitutor substitutor = staticFactoryCandidateInfo.getSubstitutor();
@@ -515,10 +513,10 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
    * The term "subexpression" includes type arguments of parameterized types (4.5), bounds of wildcards (4.5.1), and element types of array types (10.1).
    * It excludes bounds of type variables.
    */
-  private static class InferredAnonymTypeVisitor extends PsiTypeVisitor<Boolean> {
+  private static class InferredAnonymousTypeVisitor extends PsiTypeVisitor<Boolean> {
     private final PsiElement myExpression;
 
-    public InferredAnonymTypeVisitor(PsiElement expression) {
+    public InferredAnonymousTypeVisitor(PsiElement expression) {
       myExpression = expression;
     }
 
@@ -564,4 +562,4 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
       return true;
     }
   }
-}
+}
\ No newline at end of file
index 872c8ded71ea3bd7e474e93639c726808d0caae7..83ab830926890c04a6d33f07a24e74cadbe2af0c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
  */
 public abstract class PsiTypeVariable extends PsiType {
   protected PsiTypeVariable() {
-    super(PsiAnnotation.EMPTY_ARRAY);
+    super(TypeAnnotationProvider.EMPTY);
   }
 
   public abstract int getIndex();
@@ -37,4 +37,4 @@ public abstract class PsiTypeVariable extends PsiType {
       return visitor.visitType(this);
     }
   }
-}
+}
\ No newline at end of file
index 956490c773848db2fb960d6e315bf7b75a41befe..121ba9dbc33b26bbf480000506392d023a825e80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -383,13 +383,18 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade {
   }
 
   @NotNull
-  @Override
-  public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException {
-    final PsiPrimitiveType primitiveType = getPrimitiveType(text);
+  public PsiType createPrimitiveTypeFromText(@NotNull String text) throws IncorrectOperationException {
+    PsiPrimitiveType primitiveType = getPrimitiveType(text);
     if (primitiveType == null) {
       throw new IncorrectOperationException("Incorrect primitive type '" + text + "'");
     }
-    return annotations.length == 0 ? primitiveType : new PsiPrimitiveType(text, annotations);
+    return primitiveType;
+  }
+
+  @NotNull
+  @Override
+  public PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException {
+    return createPrimitiveTypeFromText(text).annotate(TypeAnnotationProvider.Static.create(annotations));
   }
 
   public static PsiPrimitiveType getPrimitiveType(final String text) {
index f1cde7acd2ce4d4260df90f21aeb9e8a07a15041..f5f2ff22f1e9370a7cdf5e1ae9050b6c3a60bc96 100644 (file)
@@ -42,7 +42,7 @@ class TypeCorrector extends PsiTypeMapper {
 
   @Override
   public PsiType visitType(PsiType type) {
-    if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) {
+    if (LambdaUtil.notInferredType(type)) {
       return type;
     }
     return super.visitType(type);
index c4cf9db93b6c2ac754bce495c6ba83b4f0977d41..5859227343459e8a9db3820336afa57cb7139f79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -42,8 +42,8 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
     myReference = reference;
   }
 
-  public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull TypeAnnotationProvider annotations) {
-    super(level, annotations);
+  public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull TypeAnnotationProvider provider) {
+    super(level, provider);
     myReference = reference;
   }
 
@@ -58,6 +58,12 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
     return result == null ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
   }
 
+  @NotNull
+  @Override
+  public PsiClassReferenceType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiClassReferenceType(myReference, myLanguageLevel, provider);
+  }
+
   @Override
   public boolean isValid() {
     return myReference.isValid();
@@ -222,4 +228,4 @@ public class PsiClassReferenceType extends PsiClassType.Stub {
   public PsiJavaCodeReferenceElement getReference() {
     return myReference;
   }
-}
+}
\ No newline at end of file
index 15823d067a90895d1791a5b07959cc5d7b45e6ac..f2bd79ba335ec66a8e97150608c07024416a26aa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -79,11 +79,11 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
   };
 
   public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor) {
-    this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY);
+    this(aClass, substitutor, null, TypeAnnotationProvider.EMPTY);
   }
 
   public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level) {
-    this(aClass, substitutor, level, PsiAnnotation.EMPTY_ARRAY);
+    this(aClass, substitutor, level, TypeAnnotationProvider.EMPTY);
   }
 
   public PsiImmediateClassType(@NotNull PsiClass aClass,
@@ -96,17 +96,24 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
     mySubstitutor = substitutor;
     assert substitutor.isValid();
   }
+
   public PsiImmediateClassType(@NotNull PsiClass aClass,
                                @NotNull PsiSubstitutor substitutor,
                                @Nullable LanguageLevel level,
-                               @NotNull TypeAnnotationProvider annotations) {
-    super(level, annotations);
+                               @NotNull TypeAnnotationProvider provider) {
+    super(level, provider);
     myClass = aClass;
     myManager = aClass.getManager();
     mySubstitutor = substitutor;
     assert substitutor.isValid();
   }
 
+  @NotNull
+  @Override
+  public PsiImmediateClassType annotate(@NotNull TypeAnnotationProvider provider) {
+    return provider == getAnnotationProvider() ? this : new PsiImmediateClassType(myClass, mySubstitutor, myLanguageLevel, provider);
+  }
+
   @Override
   public PsiClass resolve() {
     return myClass;
@@ -116,6 +123,7 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
   public String getClassName() {
     return myClass.getName();
   }
+
   @Override
   @NotNull
   public PsiType[] getParameters() {
@@ -127,12 +135,10 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
     List<PsiType> lst = new ArrayList<PsiType>();
     for (PsiTypeParameter parameter : parameters) {
       PsiType substituted = mySubstitutor.substitute(parameter);
-      if (substituted != null) {
-        lst.add(substituted);
-      }
-      else {
+      if (substituted == null) {
         return PsiType.EMPTY_ARRAY;
       }
+      lst.add(substituted);
     }
     return lst.toArray(createArray(lst.size()));
   }
@@ -313,4 +319,4 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
   public PsiClassType setLanguageLevel(@NotNull LanguageLevel level) {
     return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotationProvider());
   }
-}
+}
\ No newline at end of file
index 18ff2d110ad92eabb9251e144b22395ff8506745..07fcb8023c55b9075c654cede3ecb5cfd15dbfee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ public class JavaSharedImplUtil {
     List<PsiAnnotation[]> allAnnotations = collectAnnotations(anchor, stopAt);
     if (allAnnotations == null) return null;
     for (PsiAnnotation[] annotations : allAnnotations) {
-      type = type.createArrayType(annotations);
+      type = type.createArrayType().annotate(TypeAnnotationProvider.Static.create(annotations));
     }
 
     return type;
index 7862a7381011b83daa1ca7ee3e99f677cdd49802..f093215ee502ef0a97257ac5924334dff242e3c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -73,20 +73,22 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
       else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
         assert type == null : this;
         PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
-        type = factory.createPrimitiveType(child.getText(), ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
+        type = factory.createPrimitiveTypeFromText(child.getText()).annotate(TypeAnnotationProvider.Static.create(copy));
         if (stop) return type;
       }
       else if (elementType == JavaTokenType.LBRACKET) {
         assert type != null : this;
-        type = type.createArrayType(ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
+        type = type.createArrayType().annotate(TypeAnnotationProvider.Static.create(copy));
         if (stop) return type;
       }
       else if (elementType == JavaElementType.ANONYMOUS_CLASS) {
         PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
         PsiClass aClass = (PsiClass)child.getPsi();
         PsiSubstitutor substitutor = aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : factory.createRawSubstitutor(aClass);
-        type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass),
-                                  ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+        PsiAnnotation[] copy = ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true);
+        type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass)).annotate(TypeAnnotationProvider.Static.create(copy));
         if (stop) return type;
       }
     }
index ccb12db66200b5be68f3a92cff9c4fe95dc1c72e..99c1dad3c89c65308a700bd7f08d7d4d589775f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,10 +50,10 @@ public class CanonicalTypes {
   }
 
   private abstract static class AnnotatedType extends Type {
-    protected final PsiAnnotation[] myAnnotations;
+    protected final TypeAnnotationProvider myProvider;
 
-    protected AnnotatedType(@NotNull PsiAnnotation[] annotations) {
-      myAnnotations = annotations;
+    public AnnotatedType(@NotNull TypeAnnotationProvider provider) {
+      myProvider = TypeAnnotationProvider.Static.create(provider.getAnnotations());
     }
   }
 
@@ -61,14 +61,14 @@ public class CanonicalTypes {
     private final PsiPrimitiveType myType;
 
     private Primitive(@NotNull PsiPrimitiveType type) {
-      super(type.getAnnotations());
+      super(type.getAnnotationProvider());
       myType = type;
     }
 
     @NotNull
     @Override
     public PsiType getType(PsiElement context, PsiManager manager) {
-      return myAnnotations.length == 0 ? myType : new PsiPrimitiveType(myType.getCanonicalText(false), myAnnotations);
+      return myType.annotate(myProvider);
     }
 
     @Override
@@ -81,14 +81,14 @@ public class CanonicalTypes {
     protected final Type myComponentType;
 
     private Array(@NotNull PsiType original, @NotNull Type componentType) {
-      super(original.getAnnotations());
+      super(original.getAnnotationProvider());
       myComponentType = componentType;
     }
 
     @NotNull
     @Override
     public PsiType getType(PsiElement context, PsiManager manager) throws IncorrectOperationException {
-      return myComponentType.getType(context, manager).createArrayType(myAnnotations);
+      return myComponentType.getType(context, manager).createArrayType().annotate(myProvider);
     }
 
     @Override
@@ -115,7 +115,7 @@ public class CanonicalTypes {
     @NotNull
     @Override
     public PsiType getType(PsiElement context, PsiManager manager) throws IncorrectOperationException {
-      return new PsiEllipsisType(myComponentType.getType(context, manager), myAnnotations);
+      return new PsiEllipsisType(myComponentType.getType(context, manager)).annotate(myProvider);
     }
 
     @Override
@@ -129,7 +129,7 @@ public class CanonicalTypes {
     private final Type myBound;
 
     private WildcardType(@NotNull PsiType original, boolean isExtending, @Nullable Type bound) {
-      super(original.getAnnotations());
+      super(original.getAnnotationProvider());
       myIsExtending = isExtending;
       myBound = bound;
     }
@@ -147,7 +147,7 @@ public class CanonicalTypes {
       else {
         type = PsiWildcardType.createSuper(manager, myBound.getType(context, manager));
       }
-      return type.annotate(myAnnotations);
+      return type.annotate(myProvider);
     }
 
     @Override
@@ -205,7 +205,7 @@ public class CanonicalTypes {
     private final Map<String, Type> mySubstitutor;
 
     private ClassType(@NotNull PsiType original, @NotNull String classQName, @NotNull Map<String, Type> substitutor) {
-      super(original.getAnnotations());
+      super(original.getAnnotationProvider());
       myPresentableText = original.getPresentableText();
       myClassQName = classQName;
       mySubstitutor = substitutor;
@@ -227,7 +227,7 @@ public class CanonicalTypes {
         Type substitute = mySubstitutor.get(typeParameter.getName());
         substitutionMap.put(typeParameter, substitute != null ? substitute.getType(context, manager) : null);
       }
-      return factory.createType(aClass, factory.createSubstitutor(substitutionMap), null, myAnnotations);
+      return factory.createType(aClass, factory.createSubstitutor(substitutionMap), null).annotate(myProvider);
     }
 
     @Override
@@ -326,7 +326,7 @@ public class CanonicalTypes {
           PsiType substitute = substitutor.substitute(typeParameter);
           substitutionMap.put(typeParameter.getName(), substitute != null ? substitute.accept(this) : null);
         }
-        String qualifiedName = ObjectUtils.notNull(aClass.getQualifiedName(), aClass.getName());
+        String qualifiedName = ObjectUtils.notNull(aClass.getQualifiedName(), ObjectUtils.assertNotNull(aClass.getName()));
         return new ClassType(type, qualifiedName, substitutionMap);
       }
     }
@@ -358,4 +358,4 @@ public class CanonicalTypes {
   public static Type createTypeWrapper(@NotNull PsiType type) {
     return type.accept(Creator.INSTANCE);
   }
-}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/afterFromLambdaParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/afterFromLambdaParameter.java
new file mode 100644 (file)
index 0000000..3ef4c22
--- /dev/null
@@ -0,0 +1,8 @@
+// "Create local variable 'a'" "true"
+class C {
+  void foo() {
+    (s) -> {
+        Object a = s;
+    };
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/beforeFromLambdaParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage/beforeFromLambdaParameter.java
new file mode 100644 (file)
index 0000000..0c02370
--- /dev/null
@@ -0,0 +1,8 @@
+// "Create local variable 'a'" "true"
+class C {
+  void foo() {
+    (s) -> {
+      <caret>a = s;
+    };
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeCodeBlockWithReturnInSwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeCodeBlockWithReturnInSwitch.java
new file mode 100644 (file)
index 0000000..02526ba
--- /dev/null
@@ -0,0 +1,13 @@
+// "Replace method call on lambda with lambda body" "false"
+import java.util.function.Supplier;
+
+class Test {
+  {
+    System.out.println(((Supplier<String>)() -> {
+      switch () {
+        default:
+          return "";
+      }
+    }).g<caret>et());
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression.java b/java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression.java
new file mode 100644 (file)
index 0000000..453e376
--- /dev/null
@@ -0,0 +1,8 @@
+class Test {
+  {
+    int i = 0;
+    double[] doubles = null;
+
+    <selection>double progressResult = doubles[0] / i;</selection>
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression_after.java b/java/java-tests/testData/refactoring/extractMethod/ArrayAccessWithTopExpression_after.java
new file mode 100644 (file)
index 0000000..11b7df9
--- /dev/null
@@ -0,0 +1,12 @@
+class Test {
+  {
+    int i = 0;
+    double[] doubles = null;
+
+      newMethod(doubles[0] / i);
+  }
+
+    private void newMethod(double v) {
+        double progressResult = v;
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Param.java b/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Param.java
new file mode 100644 (file)
index 0000000..1bb4043
--- /dev/null
@@ -0,0 +1,13 @@
+import java.util.List;
+
+public class Param<T> {
+    private final List<T> y;
+
+    public Param(List<T> y) {
+        this.y = y;
+    }
+
+    public List<T> getY() {
+        return y;
+    }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/after/Test.java
new file mode 100644 (file)
index 0000000..68610f7
--- /dev/null
@@ -0,0 +1,11 @@
+import java.util.List;
+
+public class Test {
+  public static <T> String foo(Param<T> param) {
+    return null;
+  }
+
+  void bar(List<Integer> list) {
+    System.out.println(foo(new Param<>(list)));
+  }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/before/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/typeParametersWithSubstitution/before/Test.java
new file mode 100644 (file)
index 0000000..f139379
--- /dev/null
@@ -0,0 +1,12 @@
+import java.util.Collection;
+import java.util.List;
+
+public class Test {
+  public static <T> String foo(List<T> y) {
+    return null;
+  }
+
+  void bar(List<Integer> list) {
+    System.out.println(foo(list));
+  }
+}
index 7df6b43c8fb7c1627336989381faa23d6139032c..35946793c3a8694fc114065b1e19578cbf04492c 100644 (file)
@@ -500,6 +500,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
     doTest();
   }
 
+  public void testArrayAccessWithTopExpression() throws Exception {
+    doTest();
+  }
+
   public void testArrayAccessWithDuplicates() throws Exception {
     doDuplicatesTest();
   }
index 1f82ad987ab0396e193854fedf1e1af6d45dee60..c35b9fd93c7915c834603e29fff8d223fc7f82ed 100644 (file)
@@ -22,7 +22,9 @@ package com.intellij.refactoring;
 
 import com.intellij.JavaTestUtil;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
 import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.refactoring.changeSignature.JavaMethodDescriptor;
@@ -132,6 +134,18 @@ public class IntroduceParameterObjectTest extends MultiFileTestCase{
     doTest();
   }
 
+  public void testTypeParametersWithSubstitution() throws Exception {
+    final LanguageLevelProjectExtension projectExtension = LanguageLevelProjectExtension.getInstance(getProject());
+    final LanguageLevel oldLevel = projectExtension.getLanguageLevel();
+    try {
+      projectExtension.setLanguageLevel(LanguageLevel.HIGHEST);
+      doTest();
+    }
+    finally {
+      projectExtension.setLanguageLevel(oldLevel);
+    }
+  }
+
   public void testSameTypeAndVarargs() throws Exception {
     doTest(false, false, method -> {
       final PsiParameter[] parameters = method.getParameterList().getParameters();
index e58dfe17f109ad4e64f05bacf218cc7537c80408..47798746608621d955d6889e78e4cf371a58fbf2 100644 (file)
@@ -1041,50 +1041,94 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
     final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
     final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
 
-    final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(mcallRef1.getReferenceNameElement());
+    final PsiElement patternMethodName = mcallRef1.getReferenceNameElement();
+    final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(patternMethodName);
 
-    if (!myMatchingVisitor.matchText(mcallRef1.getReferenceNameElement(), mcallRef2.getReferenceNameElement()) && !isTypedVar) {
+    if (!isTypedVar && !myMatchingVisitor.matchText(patternMethodName, mcallRef2.getReferenceNameElement())) {
       myMatchingVisitor.setResult(false);
       return;
     }
 
-    final PsiExpression qualifier = mcallRef1.getQualifierExpression();
-    final PsiExpression elementQualifier = mcallRef2.getQualifierExpression();
-    if (qualifier != null) {
+    final PsiExpression patternQualifier = mcallRef1.getQualifierExpression();
+    final PsiExpression matchedQualifier = mcallRef2.getQualifierExpression();
+    if (patternQualifier != null) {
 
-      if (elementQualifier != null) {
-        myMatchingVisitor.setResult(myMatchingVisitor.match(qualifier, elementQualifier));
+      if (matchedQualifier != null) {
+        myMatchingVisitor.setResult(myMatchingVisitor.match(patternQualifier, matchedQualifier));
         if (!myMatchingVisitor.getResult()) return;
       }
       else {
         final PsiMethod method = mcall2.resolveMethod();
         if (method != null) {
-          if (qualifier instanceof PsiThisExpression) {
+          if (patternQualifier instanceof PsiThisExpression) {
             myMatchingVisitor.setResult(!method.hasModifierProperty(PsiModifier.STATIC));
             return;
           }
         }
-        final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(qualifier);
+        final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(patternQualifier);
         matchImplicitQualifier(handler, method, myMatchingVisitor.getMatchContext());
         if (!myMatchingVisitor.getResult()) {
           return;
         }
       }
     }
-    else if (elementQualifier != null) {
+    else if (matchedQualifier != null) {
       myMatchingVisitor.setResult(false);
       return;
     }
 
     myMatchingVisitor.setResult(myMatchingVisitor.matchSons(mcall.getArgumentList(), mcall2.getArgumentList()));
 
+    if (myMatchingVisitor.getResult()) {
+      myMatchingVisitor.setResult(matchTypeParameters(mcallRef1, mcallRef2));
+    }
+
     if (myMatchingVisitor.getResult() && isTypedVar) {
       boolean res = myMatchingVisitor.getResult();
-      res &= myMatchingVisitor.handleTypedElement(mcallRef1.getReferenceNameElement(), mcallRef2.getReferenceNameElement());
+      res &= myMatchingVisitor.handleTypedElement(patternMethodName, mcallRef2.getReferenceNameElement());
       myMatchingVisitor.setResult(res);
     }
   }
 
+  private boolean matchTypeParameters(PsiJavaCodeReferenceElement mcallRef1, PsiJavaCodeReferenceElement mcallRef2) {
+    final PsiReferenceParameterList patternParameterList = mcallRef1.getParameterList();
+    if (patternParameterList == null) {
+      return true;
+    }
+    final PsiTypeElement[] patternTypeElements = patternParameterList.getTypeParameterElements();
+    if (patternTypeElements.length == 0) {
+      return true;
+    }
+    PsiReferenceParameterList matchedParameterList = mcallRef2.getParameterList();
+    if (matchedParameterList == null) {
+      return false;
+    }
+    if (matchedParameterList.getFirstChild() == null) { // check inferred type parameters
+      final JavaResolveResult resolveResult = mcallRef2.advancedResolve(false);
+      final PsiMethod targetMethod = (PsiMethod)resolveResult.getElement();
+      if (targetMethod == null) {
+        return false;
+      }
+      final PsiTypeParameterList typeParameterList = targetMethod.getTypeParameterList();
+      if (typeParameterList == null) {
+        return false;
+      }
+      final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters();
+      final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
+      matchedParameterList = (PsiReferenceParameterList)matchedParameterList.copy();
+      for (final PsiTypeParameter typeParameter : typeParameters) {
+        final PsiType type = substitutor.substitute(typeParameter);
+        if (type == null) {
+          return false;
+        }
+        final PsiTypeElement matchedTypeElement = JavaPsiFacade.getElementFactory(mcallRef1.getProject()).createTypeElement(type);
+        matchedParameterList.add(matchedTypeElement);
+      }
+    }
+    final PsiTypeElement[] matchedTypeElements = matchedParameterList.getTypeParameterElements();
+    return myMatchingVisitor.matchSequentially(patternTypeElements, matchedTypeElements);
+  }
+
   @Override
   public void visitExpressionStatement(final PsiExpressionStatement expr) {
     final PsiElement other = myMatchingVisitor.getElement();
index d506f8d1c1db5d05cc2c2e8f2820cd40c52874b7..496aa8f55ac2dc98c3606e243561fd94f3d40b5d 100644 (file)
@@ -412,6 +412,12 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
       elements.add(manager.createSmartPsiElementPointer(element));
     }
 
+    cleanupElements(project, runnable, elements);
+  }
+
+  public static void cleanupElements(@NotNull final Project project,
+                                     @Nullable final Runnable runnable,
+                                     final List<SmartPsiElementPointer<PsiElement>> elements) {
     Runnable cleanupRunnable = new Runnable() {
       @Override
       public void run() {
@@ -441,7 +447,7 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
     }
   }
 
-   public void close(boolean noSuspisiousCodeFound) {
+  public void close(boolean noSuspisiousCodeFound) {
     cleanup();
   }
 
index 101dc097da0392d5bb0f09841550e66c828116c8..9b5a6ba6fcb875fa12662545430d95bff2fb203e 100644 (file)
@@ -94,7 +94,7 @@ public class PluginManagerCore {
       if (ourBuildNumber == null) {
         ourBuildNumber = BUILD_NUMBER == null ? null : BuildNumber.fromString(BUILD_NUMBER);
         if (ourBuildNumber == null) {
-          ourBuildNumber = BuildNumber.fromString("SNAPSHOT");
+          ourBuildNumber = BuildNumber.currentVersion();
         }
       }
       return ourBuildNumber;
index 184ed367e9bb405d0cb4a0cb5253bcbedef2655d..237df5160ca33e02d401cb438b198e3ee459b7ab 100644 (file)
@@ -60,6 +60,7 @@ public class TransactionGuardImpl extends TransactionGuard {
       public void finish() {
         Queue<Transaction> queue = getQueue(prevTransaction);
         queue.addAll(myCurrentTransaction.myQueue);
+        myCurrentTransaction.myQueue = queue;
         if (!queue.isEmpty()) {
           pollQueueLater();
         }
@@ -72,14 +73,7 @@ public class TransactionGuardImpl extends TransactionGuard {
 
   @NotNull
   private Queue<Transaction> getQueue(@Nullable TransactionIdImpl transaction) {
-    if (transaction == null) {
-      return myQueue;
-    }
-    if (myCurrentTransaction != null && transaction.myStartCounter > myCurrentTransaction.myStartCounter) {
-      // transaction is finished already, it makes no sense to add to its queue
-      return myCurrentTransaction.myQueue;
-    }
-    return transaction.myQueue;
+    return transaction == null ? myQueue : transaction.myQueue;
   }
 
   private void pollQueueLater() {
@@ -304,7 +298,7 @@ public class TransactionGuardImpl extends TransactionGuard {
   private static class TransactionIdImpl implements TransactionId {
     private static final AtomicLong ourTransactionCounter = new AtomicLong();
     final long myStartCounter = ourTransactionCounter.getAndIncrement();
-    final Queue<Transaction> myQueue = new LinkedBlockingQueue<Transaction>();
+    Queue<Transaction> myQueue = new LinkedBlockingQueue<Transaction>();
 
     @Override
     public String toString() {
index deee40749a0e1f4687f331de1cbd6cc502c53040..6e37873a31182919d522fb35610bccc23a7ca2ea 100644 (file)
@@ -52,13 +52,4 @@ public interface ChangeInfo {
   String getNewName();
 
   Language getLanguage();
-
-  /**
-   * For added parameters, return expression to be inserted as argument at the parameter position in callExpression.
-   * Based on parameter default value {@link ParameterInfo#getActualValue(PsiElement)}
-   */
-  default PsiElement getActualValue(int i, PsiElement callExpression) {
-    final ParameterInfo[] parameters = getNewParameters();
-    return i < parameters.length ? parameters[i].getActualValue(callExpression) : null;
-  }
 }
index 2a9f07a8e736f4e08d8cffbb0400a6a071200c04..61198c412b68d37c7ee4994b05ea43d4495da532 100644 (file)
@@ -55,7 +55,7 @@ public interface ParameterInfo {
    * Could be overridden to provide values which depend on the call site
    */
   @Nullable
-  default PsiElement getActualValue(PsiElement callExpression) {
+  default PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
     return null;
   }
 
index 7ac5e87668fbca685edb80f1d95998ad9a5f80f3..6a14e51b5b7259d199fcdc2a4c711d13ad56bf61 100644 (file)
@@ -211,7 +211,7 @@ public class FontOptions extends JPanel implements OptionsPanel{
     Object source = event.getSource();
     if (source instanceof FontComboBox) {
       FontComboBox combo = (FontComboBox)source;
-      if (combo.isEnabled() && combo.getSelectedItem() != null) {
+      if (combo.isEnabled() && combo.isShowing() && combo.getSelectedItem() != null) {
         syncFontFamilies();
       }
     }
index f7e436086ce3d2cedd5cb56c1793f2a12c42e982..80ac45003bbee62e2b4b0833f2ffd8a3610cd0be 100644 (file)
@@ -186,7 +186,6 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
     Document document = editor.getDocument();
     PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
     if (file == null || !file.getViewProvider().isPhysical() || !file.isValid()) return;
-    PsiDocumentManager.getInstance(myProject).commitDocument(document);
 
     Editor[] otherEditors = EditorFactory.getInstance().getEditors(document, myProject);
     if (otherEditors.length == 0 && !editor.isDisposed()) {
index 294b8ee6544fd767e6476b7847d5ab1f8cc1395d..b29f4c6a53661980527edb2182971f38608435c3 100644 (file)
@@ -80,9 +80,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
     LOG.assertTrue(!editor.isDisposed());
     clear();
 
-    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
-    documentManager.commitDocument(editor.getDocument());
-    PsiFile file = documentManager.getPsiFile(editor.getDocument());
+    PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
 
     SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
     EditorFoldingInfo info = EditorFoldingInfo.get(editor);
index 2d93ffec1a1474902d3f5c5f90d4a47075508703..e584694f946dd383f405a362ceed1dddf3fa8c70 100644 (file)
@@ -59,7 +59,7 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
   @Override
   protected ValidationInfo doValidate() {
     if (myInputValidator != null) {
-      final String text = myNameField.getText();
+      final String text = myNameField.getText().trim();
       final boolean canClose = myInputValidator.canClose(text);
       if (!canClose) {
         String errorText = LangBundle.message("incorrect.name");
index 89866c8887586d297ea9984a2008a6d2d24c5022..c4b72aa189f31e4d843768e6b72fb536bb76abb1 100644 (file)
@@ -137,7 +137,6 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider implements As
     if (FileEditorStateLevel.FULL == level) {
       // Folding
       if (project != null && !project.isDisposed() && !editor.isDisposed() && project.isInitialized()) {
-        PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
         state.setFoldingState(CodeFoldingManager.getInstance(project).saveFoldingState(editor));
       }
       else {
@@ -154,7 +153,7 @@ public class PsiAwareTextEditorProvider extends TextEditorProvider implements As
     // Folding
     final CodeFoldingState foldState = state.getFoldingState();
     if (project != null && foldState != null) {
-      PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
+      LOG.assertTrue(PsiDocumentManager.getInstance(project).isCommitted(editor.getDocument()));
       editor.getFoldingModel().runBatchFoldingOperation(
         () -> CodeFoldingManager.getInstance(project).restoreFoldingState(editor, foldState)
       );
index 21b1a41b8d6f43d99fe2ede05bd164c51c2aa48d..b1fd7f19fe38f6996b94c831ff0f3b0b8b881686 100644 (file)
@@ -64,13 +64,7 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo, TableItem
   }
 
   public void setValueAtWithoutUpdate(Object aValue, int rowIndex, int columnIndex) {
-    super.setValueAt(aValue, rowIndex, columnIndex);
-  }
-
-  @Override
-  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
-    super.setValueAt(aValue, rowIndex, columnIndex);
-    fireTableCellUpdated(rowIndex, columnIndex); // to update signature
+    setValueAt(aValue, rowIndex, columnIndex, false);
   }
 
   protected static abstract class ColumnInfoBase<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>, Aspect>
index e7c53c24066bb4fc03fa3d08fd5112622ea435fd..def9b138945cbeeb4200f772aa899185cb50e083 100644 (file)
@@ -100,10 +100,12 @@ public abstract class IntroduceParameterObjectDelegate<M extends PsiNamedElement
   /**
    * Call site should be updated according to the selected parameters, which correspond to the parameters to merge ({@link IntroduceParameterObjectClassDescriptor#getParamsToMerge()})
    * E.g. for the call foo(a, b, c) and parameter class which corresponds to the first 2 parameters, actual value should represent foo(new P(a, b), c)
+   * @param substitutor should contain call substitutor before change signature replaced parameters
    */
   public abstract PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
                                                                      IntroduceParameterObjectClassDescriptor descriptor,
-                                                                     List<? extends ParameterInfo> oldMethodParameters);
+                                                                     List<? extends ParameterInfo> oldMethodParameters,
+                                                                     Object substitutor);
 
   /**
    * Pass new parameter infos to the change info constructor which corresponds to the language of this delegate
index 41ca52e1b334c52edaeda9dcdf62782e82fd13b7..caad0352049c637e47a7cf77bfce9641ea18f589 100644 (file)
@@ -313,23 +313,18 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor {
 
     @Override
     public void run() {
-      ApplicationManager.getApplication().invokeLater(new Runnable() {
-          @Override
-          public void run() {
-            PsiDocumentManager.getInstance(myProject).commitAllDocuments();
-            myUsageView.close();
-            ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
-            for (SmartPsiElementPointer pointer : myPointers) {
-              final PsiElement element = pointer.getElement();
-              if (element != null) {
-                elements.add(element);
-              }
-            }
-            if(!elements.isEmpty()) {
-              SafeDeleteHandler.invoke(myProject, PsiUtilCore.toPsiElementArray(elements), true);
-            }
-          }
-        });
+      PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+      myUsageView.close();
+      ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
+      for (SmartPsiElementPointer pointer : myPointers) {
+        final PsiElement element = pointer.getElement();
+        if (element != null) {
+          elements.add(element);
+        }
+      }
+      if(!elements.isEmpty()) {
+        SafeDeleteHandler.invoke(myProject, PsiUtilCore.toPsiElementArray(elements), true);
+      }
     }
   }
 
index c0fd4beeb80cce917ca98f32b6d277149136db37..d84bb3341d77a49e0e3d03302bd5e317361fff30 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.ui.components;
 
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.registry.Registry;
@@ -177,8 +178,9 @@ public class JBScrollPane extends JScrollPane {
   }
 
   private static void updateInputMap(InputMap map, String prefix, String... actions) {
-    if (map != null) {
+    if (map != null && null != ApplicationManager.getApplication()) {
       ActionManager manager = ActionManager.getInstance();
+      if (manager != null)
       for (String action : actions) {
         KeyboardShortcut shortcut = manager.getKeyboardShortcut(prefix + action);
         if (shortcut != null) map.put(shortcut.getFirstKeyStroke(), action);
index b41d5f7292e5fec5aad9f83303bc4da4e883eca4..8e51040024b80d88f4c8cdf71e6eed8481b6b222 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -787,7 +787,7 @@ public class IdeEventQueue extends EventQueue {
     if (e instanceof WindowEvent) {
       final WindowEvent we = (WindowEvent)e;
 
-      ApplicationActivationStateManager.get().updateState(we);
+      ApplicationActivationStateManager.updateState(we);
 
       storeLastFocusedComponent(we);
     }
index 1c41c4cf27709d14a87fb607a0195a89d659892c..361a49b9fe74d185ab23b5235e8842fb8dff34be 100644 (file)
@@ -4413,7 +4413,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       return;
     }
 
-    if (getMouseEventArea(e) == EditorMouseEventArea.LINE_MARKERS_AREA) {
+    EditorMouseEventArea eventArea = getMouseEventArea(e);
+    if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA ||
+        eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA && !isInsideGutterWhitespaceArea(e)) {
       // The general idea is that we don't want to change caret position on gutter marker area click (e.g. on setting a breakpoint)
       // but do want to allow bulk selection on gutter marker mouse drag. However, when a drag is performed, the first event is
       // a 'mouse pressed' event, that's why we remember target line on 'mouse pressed' processing and use that information on
@@ -5857,7 +5859,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
         myExpectedCaretOffset = -1;
       }
 
-      if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) {
+      if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA ||
+          event.getArea() == EditorMouseEventArea.FOLDING_OUTLINE_AREA && !isInsideGutterWhitespaceArea(e)) {
         myDragOnGutterSelectionStartLine = EditorUtil.yPositionToLogicalLine(EditorImpl.this, e);
       }
 
index b810c6eacc2791e702862b14686095a454104002..1b68f58338bd25d6434eb4f3f005a55281928d64 100644 (file)
@@ -216,4 +216,18 @@ class TransactionTest extends LightPlatformTestCase {
     assert log == ['1', '2', '3', '4', '5']
   }
 
+  public void "test don't add transaction to outdated queue"() {
+    TransactionGuard.submitTransaction testRootDisposable, {
+      log << '1'
+      guard.submitTransactionLater testRootDisposable, { log << '3' }
+      log << '2'
+    }
+    TransactionGuard.submitTransaction testRootDisposable, {
+      UIUtil.dispatchAllInvocationEvents()
+      assert log == ['1', '2']
+    }
+    UIUtil.dispatchAllInvocationEvents()
+    assert log == ['1', '2', '3']
+  }
+
 }
index d3cd404e9312c4cb6833f25cf0592f11192d1da0..f04035c86f8cf402ac5684e1e2dfb0d12cd9a204 100644 (file)
@@ -23,6 +23,7 @@ import junit.framework.TestCase;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static com.intellij.openapi.util.Conditions.not;
 
@@ -227,6 +228,20 @@ public class TreeTraverserTest extends TestCase {
     assertEquals(Arrays.asList(1, 2), list);
   }
 
+  public void testIteratorContractsSkipAndStop() {
+    final AtomicInteger count = new AtomicInteger(0);
+    JBIterator<Integer> it = new JBIterator<Integer>() {
+
+      @Override
+      protected Integer nextImpl() {
+        return count.get() < 0 ? stop() :
+               count.incrementAndGet() < 10 ? skip() :
+               (Integer)count.addAndGet(-count.get() - 1);
+      }
+    };
+    assertEquals(JBIterable.of(-1).toList(), JBIterable.once(it).toList());
+  }
+
   // JBIterable ----------------------------------------------
 
   public void testAppend() {
index 8cbb3fc8bceaf73535d8b58056fe5959ef2cc42e..2646cceaa08d036377ae7cf27461a50b8a310780 100644 (file)
@@ -270,7 +270,9 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP
         String stackTrace = testFailedEvent.getStacktrace();
         if (comparisonFailureActualText != null && comparisonFailureExpectedText != null) {
           testProxy.setTestComparisonFailed(failureMessage, stackTrace,
-                                            comparisonFailureActualText, comparisonFailureExpectedText, testFailedEvent.getFilePath());
+                                            comparisonFailureActualText, comparisonFailureExpectedText,
+                                            testFailedEvent.getExpectedFilePath(),
+                                            testFailedEvent.getActualFilePath());
         } else if (comparisonFailureActualText == null && comparisonFailureExpectedText == null) {
           testProxy.setTestFailed(failureMessage, stackTrace, testFailedEvent.isTestError());
         } else {
index b8a37e3595185d70fb927b0c9ba1d1e3b5d25411..f663eac2954174920b282fb7f39b8322da5e37fc 100644 (file)
@@ -409,7 +409,7 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
         if (comparisionFailureActualText != null && comparisionFailureExpectedText != null) {
           testProxy.setTestComparisonFailed(localizedMessage, stackTrace,
                                             comparisionFailureActualText, comparisionFailureExpectedText, 
-                                            testFailedEvent.getFilePath(), testFailedEvent.getActualFilePath());
+                                            testFailedEvent.getExpectedFilePath(), testFailedEvent.getActualFilePath());
         }
         else if (comparisionFailureActualText == null && comparisionFailureExpectedText == null) {
           testProxy.setTestFailed(localizedMessage, stackTrace, isTestError);
index 9065828abdc77773478f0f1fe3293e45487a31e3..a24f824c129c3944dc74edac967dbd7cd195e8dc 100644 (file)
@@ -27,17 +27,20 @@ public class TestFailedEvent extends TreeNodeEvent {
   private final boolean myTestError;
   private final String myComparisonFailureActualText;
   private final String myComparisonFailureExpectedText;
-  private final String myFilePath;
+  private final String myExpectedFilePath;
   private final String myActualFilePath;
   private final long myDurationMillis;
 
   public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError) {
     this(testFailed, testError, null);
   }
-  public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, String filePath) {
-    this(testFailed, testError, filePath, null);
+  public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, @Nullable String expectedFilePath) {
+    this(testFailed, testError, expectedFilePath, null);
   }  
-  public TestFailedEvent(@NotNull TestFailed testFailed, boolean testError, String filePath, String actualFilePath) {
+  public TestFailedEvent(@NotNull TestFailed testFailed,
+                         boolean testError,
+                         @Nullable String expectedFilePath,
+                         @Nullable String actualFilePath) {
     super(testFailed.getTestName(), TreeNodeEvent.getNodeId(testFailed));
     if (testFailed.getFailureMessage() == null) throw new NullPointerException();
     myLocalizedFailureMessage = testFailed.getFailureMessage();
@@ -45,7 +48,7 @@ public class TestFailedEvent extends TreeNodeEvent {
     myTestError = testError;
     myComparisonFailureActualText = testFailed.getActual();
     myComparisonFailureExpectedText = testFailed.getExpected();
-    myFilePath = filePath;
+    myExpectedFilePath = expectedFilePath;
     myActualFilePath = actualFilePath;
     myDurationMillis = parseDuration(testFailed.getAttributes().get("duration"));
   }
@@ -85,7 +88,7 @@ public class TestFailedEvent extends TreeNodeEvent {
                          boolean testError,
                          @Nullable String comparisonFailureActualText,
                          @Nullable String comparisonFailureExpectedText,
-                         @Nullable String expectedTextFilePath,
+                         @Nullable String expectedFilePath,
                          long durationMillis) {
     super(testName, id);
     myLocalizedFailureMessage = localizedFailureMessage;
@@ -93,7 +96,7 @@ public class TestFailedEvent extends TreeNodeEvent {
     myTestError = testError;
     myComparisonFailureActualText = comparisonFailureActualText;
     myComparisonFailureExpectedText = comparisonFailureExpectedText;
-    myFilePath = expectedTextFilePath;
+    myExpectedFilePath = expectedFilePath;
     myActualFilePath = null;
     myDurationMillis = durationMillis;
   }
@@ -131,10 +134,19 @@ public class TestFailedEvent extends TreeNodeEvent {
     append(buf, "comparisonFailureExpectedText", myComparisonFailureExpectedText);
   }
 
+  /**
+   * @deprecated use {@link #getExpectedFilePath()} instead
+   */
   public String getFilePath() {
-    return myFilePath;
+    return myExpectedFilePath;
   }
 
+  @Nullable
+  public String getExpectedFilePath() {
+    return myExpectedFilePath;
+  }
+
+  @Nullable
   public String getActualFilePath() {
     return myActualFilePath;
   }
index 73a8eff7fa73622f5b65cf14ebd1c6bf44388277..1d33cca4914ba12d1880bfa466f6f7607abb90ac 100644 (file)
@@ -3443,4 +3443,23 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
     assertEquals("any variable can be final", 3, findMatchesCount(source, "@Modifier(\"final\") '_T '_a;"));
     assertEquals("parameters and local variables are not instance fields", 1, findMatchesCount(source, "@Modifier(\"Instance\") '_T '_a;"));
   }
+
+  public void testFindParameterizedMethodCalls() {
+    String source = "interface Foo {" +
+                    "  <T> T bar();" +
+                    "  <S, T> void bar2(S, T);" +
+                    "}" +
+                    "class X {" +
+                    "  void x(Foo foo) {" +
+                    "    foo.<String>bar();" +
+                    "    foo.<Integer>bar();" +
+                    "    String s = foo.bar();" +
+                    "    foo.bar2(1, 2);" +
+                    "  }" +
+                    "}";
+    assertEquals("find parameterized method calls 1", 1, findMatchesCount(source, "foo.<Integer>bar()"));
+    assertEquals("find parameterized method calls 2", 2, findMatchesCount(source, "foo.<String>bar()"));
+    assertEquals("find parameterized method calls 3", 3, findMatchesCount(source, "'_a.<'_b>'_c('_d*)"));
+    assertEquals("find parameterized method calls 4", 4, findMatchesCount(source, "'_a.<'_b+>'_c('_d*)"));
+  }
 }
index c736162a16e0d315c665f499d647b1adbf8ceb22..73a0bec3492acf10cdb89d7b0754f2fe28560355 100644 (file)
@@ -96,7 +96,7 @@ public class BuildNumber implements Comparable<BuildNumber> {
 
     if (BUILD_NUMBER.equals(version) || SNAPSHOT.equals(version)) {
       final String productCode = name != null ? name : "";
-      return new BuildNumber(productCode, Holder.CURRENT_VERSION.myComponents);
+      return new BuildNumber(productCode, currentVersion().myComponents);
     }
 
     String code = version;
@@ -171,9 +171,17 @@ public class BuildNumber implements Comparable<BuildNumber> {
     }
     catch (IOException ignored) { }
 
-    return fallback();
+    return fromString(FALLBACK_VERSION);
+  }
+
+  /**
+   * This method is for internal platform use only. In regular code use {@link com.intellij.openapi.application.ApplicationInfo#getBuild()} instead.
+   */
+  public static BuildNumber currentVersion() {
+    return Holder.CURRENT_VERSION;
   }
 
+  @Deprecated
   public static BuildNumber fallback() {
     return fromString(FALLBACK_VERSION);
   }
index c14a398ce6fb1fd2b7119d537c6ba76bc1f7ab5e..8caa1e2140d706691e9b314efeb45729e3a2dfcb 100644 (file)
@@ -45,7 +45,7 @@ import java.util.NoSuchElementException;
  *
  * @author gregsh
  *
- * @noinspection unchecked
+ * @noinspection unchecked, AssignmentToForLoopParameter
  */
 public abstract class JBIterator<E> implements Iterator<E> {
   private static final Object NONE = new String("#none");
@@ -137,18 +137,14 @@ public abstract class JBIterator<E> implements Iterator<E> {
 
   private void peekNext() {
     if (myNext != NONE) return;
-    Object o = nextImpl();
-    if (myNext == STOP) return;
-    Op op = myFirstOp.nextOp;
-    while (op != null) {
-      o = op.apply(o);
+    Object o = NONE;
+    for (Op op = myFirstOp; op != null; op = op == null ? myFirstOp : op.nextOp) {
+      o = op == myFirstOp ? nextImpl() : op.apply(o);
       if (myNext == SKIP) {
-        myNext = NONE;
-        o = nextImpl();
-        op = myFirstOp;
+        o = myNext = NONE;
+        op = null;
       }
       if (myNext == STOP) return;
-      op = op.nextOp;
     }
     myNext = o;
   }
index bdd04ec399aceda179e9606c6154de73432ef8eb..28386e00e89e8edc6a52729cf110dd6c663bc961 100644 (file)
@@ -113,10 +113,23 @@ public class ListTableModel<Item> extends TableViewModel<Item> implements Editab
 
   @Override
   public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+    setValueAt(aValue, rowIndex, columnIndex, true);
+  }
+
+  /**
+   * Sets the value in the cell at {@code columnIndex} and {@code rowIndex} to {@code aValue}.
+   * This method allows to choose will the model listeners notified or not.
+   *
+   * @param aValue          the new value
+   * @param rowIndex        the row whose value is to be changed
+   * @param columnIndex     the column whose value is to be changed
+   * @param notifyListeners indicates whether the model listeners are notified
+   */
+  public void setValueAt(Object aValue, int rowIndex, int columnIndex, boolean notifyListeners) {
     if (rowIndex < myItems.size()) {
       myColumnInfos[columnIndex].setValue(getItem(rowIndex), aValue);
     }
-    fireTableCellUpdated(rowIndex, columnIndex);
+    if (notifyListeners) fireTableCellUpdated(rowIndex, columnIndex);
   }
 
   /**
index 2a49881972ec3aa913babd397de53e796758631f..cb91d33654c4160aea1fddc682c5ecee49cd10a0 100644 (file)
@@ -129,12 +129,12 @@ public class BuildNumberTest {
   }
 
   @Test
-  public void fallbackVersion() throws Exception {
-    assertParsed(BuildNumber.fallback(), 999, BuildNumber.SNAPSHOT_VALUE, "999.SNAPSHOT");
-    assertTrue(BuildNumber.fallback().isSnapshot());
+  public void currentVersion() throws Exception {
+    BuildNumber current = BuildNumber.currentVersion();
+    assertTrue(current.isSnapshot());
 
-    assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("7512")) > 0);
-    assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145")) > 0);
-    assertTrue(BuildNumber.fallback().compareTo(BuildNumber.fromString("145.12")) > 0);
+    assertTrue(current.compareTo(BuildNumber.fromString("7512")) > 0);
+    assertTrue(current.compareTo(BuildNumber.fromString("145")) > 0);
+    assertTrue(current.compareTo(BuildNumber.fromString("145.12")) > 0);
   }
 }
\ No newline at end of file
index 2c0212fafc2ffbfdc587b4334e113d5528a10ffd..384b63aa754596ddcf50d8d9b1d238ccf5d6cb57 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,8 +20,6 @@ import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Query;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.InspectionGadgetsFix;
 import org.jetbrains.annotations.NotNull;
@@ -90,7 +88,7 @@ public class ConvertToVarargsMethodFix extends InspectionGadgetsFix {
     final PsiArrayType arrayType = (PsiArrayType)type;
     final PsiType componentType = arrayType.getComponentType();
     final PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
-    final PsiType ellipsisType = PsiEllipsisType.createEllipsis(componentType, type.getAnnotations());
+    final PsiType ellipsisType = new PsiEllipsisType(componentType, TypeAnnotationProvider.Static.create(type.getAnnotations()));
     final PsiTypeElement newTypeElement = factory.createTypeElement(ellipsisType);
     final PsiTypeElement typeElement = lastParameter.getTypeElement();
     if (typeElement != null) {
index 2e3814f14768a9bf1042692a96f426a3f271aa0b..74d527aab46d6b5e5d71e25cffb660f5c8bb6695 100644 (file)
@@ -39,36 +39,35 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
 
       @Override
       public void visitMethodReferenceExpression(final PsiMethodReferenceExpression expression) {
-        doCheckMethodCallOnFunctionalExpression(expression, new Condition<PsiElement>() {
-          @Override
-          public boolean value(PsiElement element) {
-            return expression.resolve() != null;
-          }
-        });
+        doCheckMethodCallOnFunctionalExpression(expression, element -> expression.resolve() != null);
       }
 
       @Override
       public void visitLambdaExpression(final PsiLambdaExpression expression) {
-        doCheckMethodCallOnFunctionalExpression(expression, new Condition<PsiElement>() {
-          @Override
-          public boolean value(PsiElement ggParent) {
-            final PsiElement body = expression.getBody();
-            if (!(body instanceof PsiCodeBlock) || 
-                ((PsiCodeBlock)body).getStatements().length == 1) {
-              return true;
-            }
-            final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(expression);
-            if (returnExpressions.size() > 1) {
-              return false;
-            }
-            final PsiElement callParent = ggParent.getParent();
-            if (returnExpressions.isEmpty()) {
-              return callParent instanceof PsiStatement;
-            }
-            return callParent instanceof PsiStatement || 
-                   callParent instanceof PsiLocalVariable ||
-                   callParent instanceof PsiExpression && PsiTreeUtil.getParentOfType(callParent, PsiStatement.class) != null;
+        doCheckMethodCallOnFunctionalExpression(expression, ggParent -> {
+          final PsiElement callParent = ggParent.getParent();
+
+          final PsiElement body = expression.getBody();
+          if (!(body instanceof PsiCodeBlock)) {
+            return callParent instanceof PsiStatement || callParent instanceof PsiLocalVariable || expression.isValueCompatible();
+          }
+
+          if (((PsiCodeBlock)body).getStatements().length == 1) {
+            return callParent instanceof PsiStatement
+                   || callParent instanceof PsiLocalVariable
+                   || ((PsiCodeBlock)body).getStatements()[0] instanceof PsiReturnStatement && expression.isValueCompatible();
+          }
+
+          final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(expression);
+          if (returnExpressions.size() > 1) {
+            return false;
           }
+
+          if (returnExpressions.isEmpty()) {
+            return callParent instanceof PsiStatement;
+          }
+          return callParent instanceof PsiStatement ||
+                 callParent instanceof PsiLocalVariable;
         });
       }
 
@@ -76,20 +75,17 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
       public void visitAnonymousClass(final PsiAnonymousClass aClass) {
         if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, false, Collections.emptySet())) {
           final PsiElement newExpression = aClass.getParent();
-          doCheckMethodCallOnFunctionalExpression(new Condition<PsiElement>() {
-            @Override
-            public boolean value(PsiElement ggParent) {
-              final PsiMethod method = aClass.getMethods()[0];
-              final PsiCodeBlock body = method.getBody();
-              final PsiReturnStatement[] returnStatements = PsiUtil.findReturnStatements(body);
-              if (returnStatements.length > 1) {
-                return false;
-              }
-              final PsiElement callParent = ggParent.getParent();
-              return callParent instanceof PsiStatement ||
-                     callParent instanceof PsiLocalVariable;
+          doCheckMethodCallOnFunctionalExpression(ggParent -> {
+            final PsiMethod method = aClass.getMethods()[0];
+            final PsiCodeBlock body = method.getBody();
+            final PsiReturnStatement[] returnStatements = PsiUtil.findReturnStatements(body);
+            if (returnStatements.length > 1) {
+              return false;
             }
-          }, newExpression, aClass.getBaseClassType(), "Replace call with method body");
+            final PsiElement callParent = ggParent.getParent();
+            return callParent instanceof PsiStatement ||
+                   callParent instanceof PsiLocalVariable;
+          }, newExpression, aClass.getBaseClassType(), new ReplaceAnonymousWithLambdaBodyFix());
         }
       }
 
@@ -99,16 +95,15 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
         if (parent instanceof PsiTypeCastExpression) {
           final PsiType interfaceType = ((PsiTypeCastExpression)parent).getType();
           doCheckMethodCallOnFunctionalExpression(elementContainerCondition, parent, interfaceType,
-                                                  "Replace method call " + 
-                                                  (expression instanceof PsiLambdaExpression ? "on lambda with lambda body"
-                                                                                             : "on method reference with corresponding method call"));
+                                                  expression instanceof PsiLambdaExpression ? new ReplaceWithLambdaBodyFix()
+                                                                                             : new ReplaceWithMethodReferenceFix());
         }
       }
 
       private void doCheckMethodCallOnFunctionalExpression(Condition<PsiElement> elementContainerCondition,
                                                            PsiElement parent,
                                                            PsiType interfaceType, 
-                                                           String quickFixName) {
+                                                           LocalQuickFix fix) {
         final PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
         if (gParent instanceof PsiReferenceExpression) {
           final PsiElement ggParent = gParent.getParent();
@@ -123,8 +118,6 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
               final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
               if (resolveMethod == interfaceMethod || 
                   interfaceMethod != null && MethodSignatureUtil.isSuperMethod(interfaceMethod, resolveMethod)) {
-                final ReplaceWithLambdaBodyFix fix = 
-                  new ReplaceWithLambdaBodyFix(quickFixName);
                 holder.registerProblem(referenceNameElement, "Method call can be simplified", fix);
               }
             }
@@ -134,125 +127,157 @@ public class TrivialFunctionalExpressionUsageInspection extends BaseJavaBatchLoc
     };
   }
 
-  private static class ReplaceWithLambdaBodyFix implements LocalQuickFix {
-    private String myName;
+  private static void replaceWithLambdaBody(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
+    inlineCallArguments(callExpression, element);
+
+    final PsiElement body = element.getBody();
+    if (body instanceof PsiExpression) {
+      callExpression.replace(body);
+    }
+    else if (body instanceof PsiCodeBlock) {
+      final PsiElement parent = callExpression.getParent();
+      if (parent instanceof PsiStatement) {
+        final PsiElement gParent = parent.getParent();
+        restoreComments(gParent, parent, body);
+        for (PsiStatement statement : ((PsiCodeBlock)body).getStatements()) {
+          PsiElement toInsert;
+          if (statement instanceof PsiReturnStatement) {
+            toInsert = ((PsiReturnStatement)statement).getReturnValue();
+          }
+          else {
+            toInsert = statement;
+          }
+
+          if (toInsert != null) {
+            gParent.addBefore(toInsert, parent);
+          }
+        }
+        parent.delete();
+      }
+      else {
+        final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
+        if (statements.length > 0) {
+          final PsiStatement anchor = PsiTreeUtil.getParentOfType(parent, PsiStatement.class);
+          if (anchor != null) {
+            final PsiElement gParent = anchor.getParent();
+            restoreComments(gParent, anchor, body);
+            for (int i = 0; i < statements.length - 1; i++) {
+              gParent.addBefore(statements[i], anchor);
+            }
+          }
+          PsiStatement statement = statements[statements.length - 1];
+          final PsiExpression returnValue = ((PsiReturnStatement)statement).getReturnValue();
+          if (returnValue != null) {
+            callExpression.replace(returnValue);
+          }
+        }
+      }
+    }
+  }
+
+  private static void restoreComments(PsiElement gParent, PsiElement parent, PsiElement body) {
+    for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
+      gParent.addBefore(comment, parent);
+    }
+  }
 
-    public ReplaceWithLambdaBodyFix(String name) {
-      myName = name;
+  private static void inlineCallArguments(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
+    final PsiExpression[] args = callExpression.getArgumentList().getExpressions();
+    final PsiParameter[] parameters = element.getParameterList().getParameters();
+    for (int i = 0; i < parameters.length; i++) {
+      final PsiParameter parameter = parameters[i];
+      final PsiExpression initializer = args[i];
+      for (PsiReference reference : ReferencesSearch.search(parameter)) {
+        final PsiElement referenceElement = reference.getElement();
+        if (referenceElement instanceof PsiJavaCodeReferenceElement) {
+          InlineUtil.inlineVariable(parameter, initializer, (PsiJavaCodeReferenceElement)referenceElement);
+        }
+      }
     }
+  }
+
+  private static class ReplaceWithLambdaBodyFix extends ReplaceFix {
 
     @Nls
     @NotNull
     @Override
-    public String getName() {
-      return getFamilyName();
+    public String getFamilyName() {
+      return "Replace method call on lambda with lambda body";
     }
 
+    @Override
+    protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
+      if (qualifierExpression instanceof PsiTypeCastExpression) {
+        final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
+        if (element instanceof PsiLambdaExpression) {
+          replaceWithLambdaBody(callExpression, (PsiLambdaExpression)element);
+        }
+      }
+    }
+  }
+
+  private static class ReplaceWithMethodReferenceFix extends ReplaceFix {
     @Nls
     @NotNull
     @Override
     public String getFamilyName() {
-      return myName;
+      return "Replace method call on method reference with corresponding method call";
     }
 
     @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      final PsiElement psiElement = descriptor.getPsiElement();
-      if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return;
-      final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
-      if (callExpression != null) {
-        final PsiExpression qualifierExpression = PsiUtil.skipParenthesizedExprDown(callExpression.getMethodExpression().getQualifierExpression());
-        if (qualifierExpression instanceof PsiTypeCastExpression) {
-          final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
-          if (element instanceof PsiLambdaExpression) {
-            replaceWithLambdaBody(callExpression, (PsiLambdaExpression)element);
-          }
-          else if (element instanceof PsiMethodReferenceExpression) {
-            final PsiLambdaExpression lambdaExpression =
-              LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)element, false, true);
-            if (lambdaExpression != null) {
-              replaceWithLambdaBody(callExpression, lambdaExpression);
-            }
-          }
-        }
-        else if (qualifierExpression instanceof PsiNewExpression) {
-          final PsiExpression cast = AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(qualifierExpression, true, false);
-          if (cast instanceof PsiTypeCastExpression) {
-            final PsiExpression lambdaExpression = ((PsiTypeCastExpression)cast).getOperand();
-            if (lambdaExpression instanceof PsiLambdaExpression) {
-              replaceWithLambdaBody(callExpression, (PsiLambdaExpression)lambdaExpression);
-            }
+    protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
+      if (qualifierExpression instanceof PsiTypeCastExpression) {
+        final PsiExpression element = ((PsiTypeCastExpression)qualifierExpression).getOperand();
+        if (element instanceof PsiMethodReferenceExpression) {
+          final PsiLambdaExpression lambdaExpression =
+            LambdaRefactoringUtil.convertMethodReferenceToLambda((PsiMethodReferenceExpression)element, false, true);
+          if (lambdaExpression != null) {
+            replaceWithLambdaBody(callExpression, lambdaExpression);
           }
         }
       }
     }
+  }
 
-    private static void replaceWithLambdaBody(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
-      inlineCallArguments(callExpression, element);
+  private static class ReplaceAnonymousWithLambdaBodyFix extends ReplaceFix {
 
-      final PsiElement body = element.getBody();
-      if (body instanceof PsiExpression) {
-        callExpression.replace(body);
-      }
-      else if (body instanceof PsiCodeBlock) {
-        final PsiElement parent = callExpression.getParent();
-        if (parent instanceof PsiStatement) {
-          final PsiElement gParent = parent.getParent();
-          restoreComments(gParent, parent, body);
-          for (PsiStatement statement : ((PsiCodeBlock)body).getStatements()) {
-            PsiElement toInsert;
-            if (statement instanceof PsiReturnStatement) {
-              toInsert = ((PsiReturnStatement)statement).getReturnValue();
-            }
-            else {
-              toInsert = statement;
-            }
+    @Nls
+    @NotNull
+    @Override
+    public String getFamilyName() {
+      return "Replace call with method body";
+    }
 
-            if (toInsert != null) {
-              gParent.addBefore(toInsert, parent);
-            }
-          }
-          parent.delete();
-        }
-        else {
-          final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
-          if (statements.length > 0) {
-            final PsiStatement anchor = PsiTreeUtil.getParentOfType(parent, PsiStatement.class);
-            if (anchor != null) {
-              final PsiElement gParent = anchor.getParent();
-              restoreComments(gParent, anchor, body);
-              for (int i = 0; i < statements.length - 1; i++) {
-                gParent.addBefore(statements[i], anchor);
-              }
-            }
-            final PsiExpression returnValue = ((PsiReturnStatement)statements[statements.length - 1]).getReturnValue();
-            if (returnValue != null) {
-              callExpression.replace(returnValue);
-            }
-          }
+    @Override
+    protected void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression) {
+      final PsiExpression cast = AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(qualifierExpression, true, false);
+      if (cast instanceof PsiTypeCastExpression) {
+        final PsiExpression lambdaExpression = ((PsiTypeCastExpression)cast).getOperand();
+        if (lambdaExpression instanceof PsiLambdaExpression) {
+          replaceWithLambdaBody(callExpression, (PsiLambdaExpression)lambdaExpression);
         }
       }
     }
+  }
 
-    private static void restoreComments(PsiElement gParent, PsiElement parent, PsiElement body) {
-      for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
-        gParent.addBefore(comment, parent);
-      }
+  private static abstract class ReplaceFix implements LocalQuickFix {
+    @Nls
+    @NotNull
+    @Override
+    public String getName() {
+      return getFamilyName();
     }
 
-    private static void inlineCallArguments(PsiMethodCallExpression callExpression, PsiLambdaExpression element) {
-      final PsiExpression[] args = callExpression.getArgumentList().getExpressions();
-      final PsiParameter[] parameters = element.getParameterList().getParameters();
-      for (int i = 0; i < parameters.length; i++) {
-        final PsiParameter parameter = parameters[i];
-        final PsiExpression initializer = args[i];
-        for (PsiReference reference : ReferencesSearch.search(parameter)) {
-          final PsiElement referenceElement = reference.getElement();
-          if (referenceElement instanceof PsiJavaCodeReferenceElement) {
-            InlineUtil.inlineVariable(parameter, initializer, (PsiJavaCodeReferenceElement)referenceElement);
-          }
-        }
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      final PsiElement psiElement = descriptor.getPsiElement();
+      if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return;
+      final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
+      if (callExpression != null) {
+        fixExpression(callExpression, PsiUtil.skipParenthesizedExprDown(callExpression.getMethodExpression().getQualifierExpression()));
       }
     }
+
+    protected abstract void fixExpression(PsiMethodCallExpression callExpression, PsiExpression qualifierExpression);
   }
 }
index 2b0617c673a6aed0174758f7ae3f02def29f2163..24881155584b77006559e664fdd0b20301c25c7a 100644 (file)
@@ -48,7 +48,7 @@ public class MakeMethodVarargsIntention extends Intention {
     final PsiElementFactory factory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory();
     final PsiTypeElement typeElement = lastParameter.getTypeElement();
     LOG.assertTrue(typeElement != null);
-    final PsiType ellipsisType = PsiEllipsisType.createEllipsis(((PsiArrayType)type).getComponentType(), type.getAnnotations());
+    final PsiType ellipsisType = new PsiEllipsisType(((PsiArrayType)type).getComponentType(), TypeAnnotationProvider.Static.create(type.getAnnotations()));
     typeElement.replace(factory.createTypeElement(ellipsisType));
   }
 
index 2a2db5ecaeb923359bde677f7b804f107258ce65..33003a77b739b146821261d2ab015d60d7e2fdd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1131,6 +1131,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
     return JavaPsiFacade.getElementFactory(myProject).createType(resolve, substitutor, languageLevel);
   }
 
+  @SuppressWarnings("deprecation")
   @NotNull
   @Override
   public PsiClassType createType(@NotNull PsiClass resolve,
index 63ac084238150e3e1a53f7beefe9c79a99b5214d..e8e1fe8f2d758348b28b22e49955246c2ac4e118 100644 (file)
@@ -336,7 +336,7 @@ public class GrChangeInfoImpl implements JavaChangeInfo {
   @Override
   public PsiExpression getValue(int i, PsiCallExpression callExpression) {
     if (defaultValues[i] != null) return defaultValues[i];
-    final PsiElement valueAtCallSite = parameters.get(i).getActualValue(callExpression);
+    final PsiElement valueAtCallSite = parameters.get(i).getActualValue(callExpression, PsiSubstitutor.EMPTY);
     return valueAtCallSite instanceof PsiExpression ? (PsiExpression)valueAtCallSite : null;
   }
 
index 63e9e67d663fa9de34076a3922517a909b13eea9..312a53febdeb5f2c9f242a557e9f1d6a4ec60dd6 100644 (file)
@@ -529,7 +529,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
           argsToDelete.removeAll(map[index].args);
         }
         else {
-          values[i] = createDefaultValue(factory, changeInfo, parameter, argumentList);
+          values[i] = createDefaultValue(factory, changeInfo, parameter, argumentList, substitutor);
         }
       }
 
@@ -640,7 +640,8 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
   private static GrExpression createDefaultValue(GroovyPsiElementFactory factory,
                                                  JavaChangeInfo changeInfo,
                                                  JavaParameterInfo info,
-                                                 final GrArgumentList list) {
+                                                 final GrArgumentList list,
+                                                 PsiSubstitutor substitutor) {
     if (info.isUseAnySingleVariable()) {
       final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
       final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
@@ -689,7 +690,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
       }
     }
 
-    final PsiElement element = info.getActualValue(list.getParent());
+    final PsiElement element = info.getActualValue(list.getParent(), substitutor);
     if (element instanceof GrExpression) {
       return (GrExpression)element;
     }
index 63d8b3bdc52fd665ee3cb5e4a75065605c0839d9..3985d2d2aa3ff3db1df63ab28f4f4011749ace93 100644 (file)
@@ -76,10 +76,10 @@ public class GroovyIntroduceParameterObjectDelegate
     return new GrParameterInfo(descriptor.getClassName(), null, null, classType, -1, false) {
       @Nullable
       @Override
-      public PsiElement getActualValue(PsiElement callExpression) {
+      public PsiElement getActualValue(PsiElement callExpression, Object substitutor) {
         final IntroduceParameterObjectDelegate<PsiNamedElement, ParameterInfo, IntroduceParameterObjectClassDescriptor<PsiNamedElement, ParameterInfo>>
           delegate = findDelegate(callExpression);
-        return delegate != null ? delegate.createNewParameterInitializerAtCallSite(callExpression, descriptor, oldMethodParameters) : null;
+        return delegate != null ? delegate.createNewParameterInitializerAtCallSite(callExpression, descriptor, oldMethodParameters, substitutor) : null;
       }
     };
   }
@@ -87,7 +87,8 @@ public class GroovyIntroduceParameterObjectDelegate
   @Override
   public PsiElement createNewParameterInitializerAtCallSite(PsiElement callExpression,
                                                             IntroduceParameterObjectClassDescriptor descriptor,
-                                                            List<? extends ParameterInfo> oldMethodParameters) {
+                                                            List<? extends ParameterInfo> oldMethodParameters,
+                                                            Object substitutor) {
     if (callExpression instanceof GrCallExpression) {
       final GrArgumentList list = ((GrCallExpression)callExpression).getArgumentList();
       if (list == null) {
index ede0d2b92f018dfec11cca05024a0b67e40d8f18..499619eea8eb3e9fbf1484597d6dd649ce0d3677 100644 (file)
@@ -7,9 +7,11 @@
   <project-components>
     <component>
       <implementation-class>com.intellij.designer.DesignerToolWindowManager</implementation-class>
+      <headless-implementation-class></headless-implementation-class>
     </component>
     <component>
       <implementation-class>com.intellij.designer.palette.PaletteToolWindowManager</implementation-class>
+      <headless-implementation-class></headless-implementation-class>
     </component>
   </project-components>
 
index c1d5cb386ce05c6d350aa608b8d62d26d1b980e0..53acb8928f79c148ef4880314bef21e3e6bba572 100644 (file)
@@ -550,14 +550,7 @@ public class XPathEvalAction extends XPathAction {
     public abstract static class EditExpressionAction implements Runnable {
         @Override
         public void run() {
-            Runnable runnable = new Runnable() {
-                @Override
-                public void run() {
-                    execute();
-                }
-
-            };
-            SwingUtilities.invokeLater(runnable);
+          execute();
         }
 
         protected abstract void execute();
index 131d9f5b46d8376e25b441cc526e1f9fa0442954..421b23fef48ed4412120cc60504f25376c110b55 100644 (file)
     <projectService serviceImplementation="com.jetbrains.edu.coursecreator.CCProjectService"/>
     <treeStructureProvider implementation="com.jetbrains.edu.coursecreator.projectView.CCTreeStructureProvider"/>
     <refactoring.elementListenerProvider implementation="com.jetbrains.edu.coursecreator.CCRefactoringElementListenerProvider"/>
-    <refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.CCLessonMoveHandlerDelegate" order="first"/>
-    <refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.CCTaskMoveHandlerDelegate" order="first"/>
-    <renameHandler implementation="com.jetbrains.edu.coursecreator.CCTaskRenameHandler" order="first"/>
-    <renameHandler implementation="com.jetbrains.edu.coursecreator.CCLessonRenameHandler" order="first"/>
+    <refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCLessonMoveHandlerDelegate" order="first"/>
+    <refactoring.moveHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCTaskMoveHandlerDelegate" order="first"/>
+    <renameHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCTaskRenameHandler" order="first"/>
+    <renameHandler implementation="com.jetbrains.edu.coursecreator.handlers.CCLessonRenameHandler" order="first"/>
+  </extensions>
+  <extensions defaultExtensionNs="Edu">
+    <studyActionsProvider implementation="com.jetbrains.edu.coursecreator.CCStudyActionsProvider"/>
+    <studyActionListener implementation="com.jetbrains.edu.coursecreator.CCStudyActionListener"/>
   </extensions>
-
-  <application-components>
-    <!-- Add your application components here -->
-  </application-components>
 
   <project-components>
-    <!-- Add your project components here -->
     <component>
       <implementation-class>com.jetbrains.edu.coursecreator.CCProjectComponent</implementation-class>
     </component>
     <action id="CreateLesson" class="com.jetbrains.edu.coursecreator.actions.CCCreateLesson">
       <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
     </action>
-    <action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="PackCourse"/>
-    </action>
     <action id="CreateTask" class="com.jetbrains.edu.coursecreator.actions.CCCreateTask">
       <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
     </action>
-    <action id="CreateTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCCreateTaskFile">
-      <add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFile"/>
-    </action>
-    <action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile" text="Add As Task File">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
-    </action>
-    <action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddAnswerPlaceholder">
-      <add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
-    </action>
-    <action id="ShowTaskWindowDetails" class="com.jetbrains.edu.coursecreator.actions.CCShowAnswerPlaceholderDetails">
-      <add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
-    </action>
-    <action id="DeleteTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAnswerPlaceholder">
-      <add-to-group group-id="EditorPopupMenu" anchor="before" relative-to-action="CopyReference"/>
-    </action>
-    <action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
-      <add-to-group group-id="EditorTabPopupMenu"/>
-    </action>
-    <action id="PackCourse" class="com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
+
+    <group id="CCProjectViewGroup">
+      <action id="AddTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCAddAsTaskFile" text="Add as Task File"/>
+      <action id="HideTaskFile" class="com.jetbrains.edu.coursecreator.actions.CCHideFromStudent" text="Hide from Student"/>
+      <action id="ShowPreview" class="com.jetbrains.edu.coursecreator.actions.CCShowPreview">
+        <add-to-group group-id="EditorTabPopupMenu"/>
+      </action>
+      <action id="DeleteAllPlaceholders" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAllAnswerPlaceholdersAction"/>
+      <action id="PackCourse" class="com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive">
+        <add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
+      </action>
+      <action id="PushLesson" class="com.jetbrains.edu.coursecreator.actions.CCPushLesson">
       <add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
-    </action>
-    <action id="UnpackCourse" class="com.jetbrains.edu.coursecreator.actions.CCFromCourseArchive"/>
-    <action id="PushLesson" class="com.jetbrains.edu.coursecreator.actions.CCPushLesson">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
+      </action>
+      <action id="PushCourse" class="com.jetbrains.edu.coursecreator.actions.CCPushCourse">
       <add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
-    </action>
-    <action id="PushCourse" class="com.jetbrains.edu.coursecreator.actions.CCPushCourse">
+      </action>
+      <action id="ChangeCourseInfo" class="com.jetbrains.edu.coursecreator.actions.CCChangeCourseInfo"/>
+      <separator/>
       <add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
-      <add-to-group group-id="FileMenu" relative-to-action="FileMainSettingsGroup" anchor="before"/>
-    </action>
+    </group>
 
-    <action id="DeleteAllPlaceholders" class="com.jetbrains.edu.coursecreator.actions.CCDeleteAllAnswerPlaceholdersAction">
-      <add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
-      <add-to-group group-id="EditorPopupMenu" anchor="after" relative-to-action="DeleteTaskWindow"/>
-    </action>
+    <group id="AnswerPlaceholderGroup">
+      <action id="EditAnswerPlaceholder" class="com.jetbrains.edu.coursecreator.actions.CCEditAnswerPlaceholder"/>
+      <action id="AddTaskWindow" class="com.jetbrains.edu.coursecreator.actions.CCAddAnswerPlaceholder"/>
+      <reference ref="DeleteAllPlaceholders"/>
+      <separator/>
+      <add-to-group group-id="EditorPopupMenu" anchor="first"/>
+    </group>
+
+    <action id="UnpackCourse" class="com.jetbrains.edu.coursecreator.actions.CCFromCourseArchive"/>
   </actions>
 
 </idea-plugin>
\ No newline at end of file
diff --git a/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java b/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCEditorFactoryListener.java
deleted file mode 100644 (file)
index 0ecea37..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.jetbrains.edu.coursecreator;
-
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.actionSystem.EditorActionManager;
-import com.intellij.openapi.editor.colors.EditorColors;
-import com.intellij.openapi.editor.event.EditorFactoryEvent;
-import com.intellij.openapi.editor.event.EditorFactoryListener;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.jetbrains.edu.learning.core.EduAnswerPlaceholderDeleteHandler;
-import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
-import com.jetbrains.edu.learning.core.EduDocumentListener;
-import com.jetbrains.edu.learning.core.EduNames;
-import com.jetbrains.edu.learning.courseFormat.Course;
-import com.jetbrains.edu.learning.courseFormat.TaskFile;
-import org.jetbrains.annotations.NotNull;
-
-public class CCEditorFactoryListener implements EditorFactoryListener {
-  @Override
-  public void editorCreated(@NotNull EditorFactoryEvent event) {
-    Editor editor = event.getEditor();
-    Project project = editor.getProject();
-    if (project == null) {
-      return;
-    }
-    VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());
-    if (virtualFile == null) {
-      return;
-    }
-    final CCProjectService service = CCProjectService.getInstance(project);
-    Course course = service.getCourse();
-    if (course == null) {
-      return;
-    }
-    final VirtualFile taskDir = virtualFile.getParent();
-    if (taskDir == null || !taskDir.getName().contains(EduNames.TASK)) {
-      return;
-    }
-    final VirtualFile lessonDir = taskDir.getParent();
-    if (lessonDir == null) return;
-    final TaskFile taskFile = service.getTaskFile(virtualFile);
-    if (taskFile == null) {
-      return;
-    }
-    EduDocumentListener listener = new EduDocumentListener(taskFile, true, true);
-    CCProjectService.addDocumentListener(editor.getDocument(), listener);
-    editor.getDocument().addDocumentListener(listener);
-    EditorActionManager.getInstance()
-      .setReadonlyFragmentModificationHandler(editor.getDocument(), new EduAnswerPlaceholderDeleteHandler(editor));
-    service.drawAnswerPlaceholders(virtualFile, editor);
-    editor.getColorsScheme().setColor(EditorColors.READONLY_FRAGMENT_BACKGROUND_COLOR, null);
-    EduAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile, false);
-  }
-
-  @Override
-  public void editorReleased(@NotNull EditorFactoryEvent event) {
-    Editor editor = event.getEditor();
-    Document document = editor.getDocument();
-    EduDocumentListener listener = CCProjectService.getListener(document);
-    if (listener != null) {
-      document.removeDocumentListener(listener);
-      CCProjectService.removeListener(document);
-    }
-    editor.getMarkupModel().removeAllHighlighters();
-    editor.getSelectionModel().removeSelection();
-  }
-}
index 5ab5f5591ed850529bf5d9ac55e09f1b647e291e..b6c8fd4ecf533aad3d0473f2bfa9a145981d4fb5 100644 (file)
@@ -3,6 +3,7 @@ package com.jetbrains.edu.coursecreator;
 import com.intellij.ide.fileTemplates.FileTemplate;
 import com.intellij.lang.LanguageExtension;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -21,4 +22,8 @@ public interface CCLanguageManager {
   FileTemplate getTestsTemplate(@NotNull final Project project);
 
   boolean doNotPackFile(File pathname);
+
+  default boolean isTestFile(VirtualFile file) {
+    return false;
+  }
 }
index e5871848ecf1e553fa713d8f3bec95e001dc8802..b5a23ba917ed33b3a2e9835e9199f1a5a4e164f4 100644 (file)
@@ -1,33 +1,40 @@
 package com.jetbrains.edu.coursecreator;
 
-import com.intellij.openapi.components.ProjectComponent;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.event.EditorFactoryEvent;
-import com.intellij.openapi.editor.impl.EditorFactoryImpl;
-import com.intellij.openapi.fileEditor.FileEditor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.AbstractProjectComponent;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.startup.StartupManager;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
+import com.jetbrains.edu.learning.StudyProjectComponent;
+import com.jetbrains.edu.learning.StudyTaskManager;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import org.jetbrains.annotations.NotNull;
 
-public class CCProjectComponent implements ProjectComponent {
+import java.io.File;
+
+public class CCProjectComponent extends AbstractProjectComponent {
+  private final CCVirtualFileListener myTaskFileLifeListener = new CCVirtualFileListener();
   private final Project myProject;
-  private CCFileDeletedListener myListener;
 
-  public CCProjectComponent(Project project) {
+  protected CCProjectComponent(Project project) {
+    super(project);
     myProject = project;
   }
 
   public void initComponent() {
+    VirtualFileManager.getInstance().addVirtualFileListener(myTaskFileLifeListener);
   }
 
-  public void disposeComponent() {
+  public void migrateIfNeeded() {
+    Course studyCourse = StudyTaskManager.getInstance(myProject).getCourse();
+    Course course = CCProjectService.getInstance(myProject).getCourse();
+    if (studyCourse == null && course != null) {
+      course.setCourseMode(CCUtils.COURSE_MODE);
+      File coursesDir = new File(PathManager.getConfigPath(), "courses");
+      File courseDir = new File(coursesDir, course.getName() + "-" + myProject.getName());
+      course.setCourseDirectory(courseDir.getPath());
+      StudyTaskManager.getInstance(myProject).setCourse(course);
+      StudyProjectComponent.getInstance(myProject).registerStudyToolWindow(course);
+    }
   }
 
   @NotNull
@@ -36,36 +43,11 @@ public class CCProjectComponent implements ProjectComponent {
   }
 
   public void projectOpened() {
-    StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
-      @Override
-      public void run() {
-        final Course course = CCProjectService.getInstance(myProject).getCourse();
-        if (course != null) {
-          course.initCourse(true);
-          myListener = new CCFileDeletedListener(myProject);
-          VirtualFileManager.getInstance().addVirtualFileListener(myListener);
-          final CCEditorFactoryListener editorFactoryListener = new CCEditorFactoryListener();
-          EditorFactory.getInstance().addEditorFactoryListener(editorFactoryListener, myProject);
-          VirtualFile[] files = FileEditorManager.getInstance(myProject).getOpenFiles();
-          for (VirtualFile file : files) {
-            if (CCProjectService.getInstance(myProject).isTaskFile(file)) {
-              FileEditorManager.getInstance(myProject).closeFile(file);
-              continue;
-            }
-            FileEditor fileEditor = FileEditorManager.getInstance(myProject).getSelectedEditor(file);
-            if (fileEditor instanceof PsiAwareTextEditorImpl) {
-              Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
-              editorFactoryListener.editorCreated(new EditorFactoryEvent(new EditorFactoryImpl(ProjectManager.getInstance()), editor));
-            }
-          }
-        }
-      }
-    });
+    migrateIfNeeded();
+    VirtualFileManager.getInstance().addVirtualFileListener(myTaskFileLifeListener);
   }
 
   public void projectClosed() {
-    if (myListener != null) {
-      VirtualFileManager.getInstance().removeVirtualFileListener(myListener);
-    }
+    VirtualFileManager.getInstance().removeVirtualFileListener(myTaskFileLifeListener);
   }
 }
index ba98866926717401457e6b90b3d950c9ba97a6be..2ff6f8051033d6c55ef704697f2cc0fda3a2f349 100644 (file)
  */
 package com.jetbrains.edu.coursecreator;
 
-import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.components.PersistentStateComponent;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.components.State;
 import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.JBColor;
 import com.intellij.util.xmlb.XmlSerializerUtil;
-import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
-import com.jetbrains.edu.learning.core.EduDocumentListener;
-import com.jetbrains.edu.learning.core.EduNames;
-import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.courseFormat.Course;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 @State(name = "CCProjectService", storages = @Storage("course_service.xml"))
 public class CCProjectService implements PersistentStateComponent<CCProjectService> {
   private Course myCourse;
 
-  private static final Map<Document, EduDocumentListener> myDocumentListeners = new HashMap<Document, EduDocumentListener>();
-
-  @Nullable
-  public TaskFile getTaskFile(@NotNull final VirtualFile virtualFile) {
-    VirtualFile taskDir = virtualFile.getParent();
-    if (taskDir == null) {
-      return null;
-    }
-    String taskDirName = taskDir.getName();
-    if (!taskDirName.contains(EduNames.TASK)) {
-      return null;
-    }
-    VirtualFile lessonDir = taskDir.getParent();
-    if (lessonDir == null) {
-      return null;
-    }
-    String lessonDirName = lessonDir.getName();
-    if (!lessonDirName.contains(EduNames.LESSON)) {
-      return null;
-    }
-    Lesson lesson = myCourse.getLesson(lessonDirName);
-    if (lesson == null) {
-      return null;
-    }
-    Task task = lesson.getTask(taskDir.getName());
-    if (task == null) {
-      return null;
-    }
-    return task.getTaskFile(virtualFile.getName());
-  }
-
-  public void drawAnswerPlaceholders(@NotNull final VirtualFile virtualFile, @NotNull final Editor editor) {
-    TaskFile taskFile = getTaskFile(virtualFile);
-    if (taskFile == null) {
-      return;
-    }
-    List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
-    for (AnswerPlaceholder answerPlaceholder : answerPlaceholders) {
-      EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, false, JBColor.BLUE);
-    }
-  }
-
-  public static void addDocumentListener(Document document, EduDocumentListener listener) {
-    myDocumentListeners.put(document, listener);
-  }
-
-  public static EduDocumentListener getListener(Document document) {
-    return myDocumentListeners.get(document);
-  }
-
-  public static void removeListener(Document document) {
-    myDocumentListeners.remove(document);
-  }
-
-  @Nullable
-  public Task getTask(VirtualFile file) {
-    if (myCourse == null || file == null) {
-      return null;
-    }
-    VirtualFile taskDir = file.getParent();
-    if (taskDir != null) {
-      String taskDirName = taskDir.getName();
-      if (taskDirName.contains(EduNames.TASK)) {
-        VirtualFile lessonDir = taskDir.getParent();
-        if (lessonDir != null) {
-          String lessonDirName = lessonDir.getName();
-          int lessonIndex = EduUtils.getIndex(lessonDirName, EduNames.LESSON);
-          List<Lesson> lessons = myCourse.getLessons();
-          if (!EduUtils.indexIsValid(lessonIndex, lessons)) {
-            return null;
-          }
-          Lesson lesson = lessons.get(lessonIndex);
-          int taskIndex = EduUtils.getIndex(taskDirName, EduNames.TASK);
-          List<Task> tasks = lesson.getTaskList();
-          if (!EduUtils.indexIsValid(taskIndex, tasks)) {
-            return null;
-          }
-          return tasks.get(taskIndex);
-        }
-      }
-    }
-    return null;
-  }
-
-  public boolean isTaskFile(VirtualFile file) {
-    Task task = getTask(file);
-    return task != null && task.isTaskFile(file.getName());
-  }
-
-  public static boolean setCCActionAvailable(@NotNull AnActionEvent e) {
-    final Project project = e.getProject();
-    if (project == null) {
-      return false;
-    }
-    if (getInstance(project).getCourse() == null) {
-      EduUtils.enableAction(e, false);
-      return false;
-    }
-    EduUtils.enableAction(e, true);
-    return true;
-  }
-
   public Course getCourse() {
     return myCourse;
   }
 
-  public void setCourse(@NotNull final Course course) {
+  public void setCourse(Course course) {
     myCourse = course;
   }
 
index ed9b404e04a540d4fcf046256ca7797ea3d15ab0..7dbd894d898035e49963d815ce836eece1e01b87 100644 (file)
 package com.jetbrains.edu.coursecreator;
 
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.refactoring.listeners.RefactoringElementAdapter;
 import com.intellij.refactoring.listeners.RefactoringElementListener;
 import com.intellij.refactoring.listeners.RefactoringElementListenerProvider;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.core.EduNames;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Lesson;
 import com.jetbrains.edu.learning.courseFormat.Task;
 import com.jetbrains.edu.learning.courseFormat.TaskFile;
-import com.jetbrains.edu.coursecreator.actions.CCRunTestsAction;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.IOException;
 import java.util.Map;
 
 public class CCRefactoringElementListenerProvider implements RefactoringElementListenerProvider {
+  private static final Logger LOG = Logger.getInstance(CCRefactoringElementListenerProvider.class);
+
   @Nullable
   @Override
   public RefactoringElementListener getListener(PsiElement element) {
@@ -62,8 +68,7 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
 
     private static void tryToRenameTaskFile(PsiFile file, String oldName) {
       final PsiDirectory taskDir = file.getContainingDirectory();
-      final CCProjectService service = CCProjectService.getInstance(file.getProject());
-      Course course = service.getCourse();
+      Course course = StudyTaskManager.getInstance(file.getProject()).getCourse();
       if (course == null) {
         return;
       }
@@ -82,16 +87,29 @@ public class CCRefactoringElementListenerProvider implements RefactoringElementL
       if (task == null) {
         return;
       }
+      Map<String, TaskFile> taskFiles = task.getTaskFiles();
+      TaskFile taskFile = task.getTaskFile(oldName);
+      if (taskFile == null) {
+        return;
+      }
       ApplicationManager.getApplication().runWriteAction(new Runnable() {
         @Override
         public void run() {
-          CCRunTestsAction.clearTestEnvironment(taskDir.getVirtualFile(), taskDir.getProject());
+          VirtualFile patternFile = StudyUtils.getPatternFile(taskFile, oldName);
+          if (patternFile != null) {
+            try {
+              patternFile.delete(CCRefactoringElementListenerProvider.class);
+            }
+            catch (IOException e) {
+              LOG.info(e);
+            }
+          }
         }
       });
-      Map<String, TaskFile> taskFiles = task.getTaskFiles();
-      TaskFile taskFile = task.getTaskFile(oldName);
+
       taskFiles.remove(oldName);
       taskFiles.put(file.getName(), taskFile);
+      CCUtils.createResourceFile(file.getVirtualFile(), course, taskDir.getVirtualFile());
     }
 
     @Override
diff --git a/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionListener.java b/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionListener.java
new file mode 100644 (file)
index 0000000..945026b
--- /dev/null
@@ -0,0 +1,36 @@
+package com.jetbrains.edu.coursecreator;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.learning.StudyActionListener;
+import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.courseFormat.Task;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
+
+public class CCStudyActionListener implements StudyActionListener {
+  @Override
+  public void beforeCheck(AnActionEvent event) {
+    Project project = event.getProject();
+    if (project == null) {
+      return;
+    }
+    VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(event.getDataContext());
+    if (virtualFile == null) {
+      return;
+    }
+
+    TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile);
+    if (taskFile == null) {
+      return;
+    }
+
+    Task task = taskFile.getTask();
+    VirtualFile taskDir = StudyUtils.getTaskDir(virtualFile);
+    if (taskDir == null) {
+      return;
+    }
+    CCUtils.createResources(project, task, taskDir);
+  }
+}
diff --git a/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionsProvider.java b/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCStudyActionsProvider.java
new file mode 100644 (file)
index 0000000..7ccdc07
--- /dev/null
@@ -0,0 +1,12 @@
+package com.jetbrains.edu.coursecreator;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.jetbrains.edu.coursecreator.actions.CCEditTaskTextAction;
+import com.jetbrains.edu.learning.StudyActionsProvider;
+
+public class CCStudyActionsProvider implements StudyActionsProvider{
+  @Override
+  public AnAction[] getActions() {
+    return new AnAction[]{new CCEditTaskTextAction()};
+  }
+}
index 65131d0b36ae167fdb33cbe4a5b52351e4080ab0..f6dd7417a32d7b0b86547fd3e967b64709d89cff 100644 (file)
@@ -6,6 +6,8 @@ import com.intellij.ide.projectView.actions.MarkRootActionBase;
 import com.intellij.lang.Language;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.DumbModePermission;
 import com.intellij.openapi.project.DumbService;
@@ -14,27 +16,27 @@ import com.intellij.openapi.roots.ContentEntry;
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileEvent;
 import com.intellij.psi.PsiDirectory;
+import com.intellij.util.DocumentUtil;
 import com.intellij.util.Function;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.core.EduUtils;
-import com.jetbrains.edu.learning.courseFormat.Course;
-import com.jetbrains.edu.learning.courseFormat.StudyItem;
+import com.jetbrains.edu.learning.courseFormat.*;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.*;
 
 public class CCUtils {
   private static final Logger LOG = Logger.getInstance(CCUtils.class);
   public static final String GENERATED_FILES_FOLDER = ".coursecreator";
-  public static final String TESTS = "coursecreatortests";
-  public static final String RESOURCES = "coursecreatorresources";
+  public static final String COURSE_MODE = "Course Creator";
 
   @Nullable
   public static CCLanguageManager getStudyLanguageManager(@NotNull final Course course) {
@@ -100,9 +102,9 @@ public class CCUtils {
     if (sourceDirectory == null) {
       return false;
     }
-    CCProjectService service = CCProjectService.getInstance(sourceDirectory.getProject());
-    Course course = service.getCourse();
-    if (course != null && course.getLesson(sourceDirectory.getName()) != null) {
+    Project project = sourceDirectory.getProject();
+    Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course != null && isCourseCreator(project) && course.getLesson(sourceDirectory.getName()) != null) {
       return true;
     }
     return false;
@@ -169,4 +171,74 @@ public class CCUtils {
     });
     return folder.get();
   }
+
+  public static boolean isCourseCreator(@NotNull Project project) {
+    Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null) {
+      return false;
+    }
+
+    return COURSE_MODE.equals(course.getCourseMode());
+  }
+
+  public static boolean isTestsFile(@NotNull Project project, @NotNull VirtualFile file) {
+    Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null) {
+      return false;
+    }
+    CCLanguageManager manager = getStudyLanguageManager(course);
+    if (manager == null) {
+      return false;
+    }
+    return manager.isTestFile(file);
+  }
+
+  public static void createResourceFile(VirtualFile createdFile, Course course, VirtualFile taskVF) {
+    VirtualFile lessonVF = taskVF.getParent();
+    if (lessonVF == null) {
+      return;
+    }
+
+    String taskResourcesPath = FileUtil.join(course.getCourseDirectory(), lessonVF.getName(), taskVF.getName());
+    File taskResourceFile = new File(taskResourcesPath);
+    if (!taskResourceFile.exists()) {
+      if (!taskResourceFile.mkdirs()) {
+        LOG.info("Failed to create resources for task " + taskResourcesPath);
+      }
+    }
+    try {
+      File toFile = new File(taskResourceFile, createdFile.getName());
+      FileUtil.copy(new File(createdFile.getPath()), toFile);
+    }
+    catch (IOException e) {
+      LOG.info("Failed to copy created task file to resources " + createdFile.getPath());
+    }
+  }
+
+
+  public static void createResources(Project project, Task task, VirtualFile taskDir) {
+    Map<String, TaskFile> files = task.getTaskFiles();
+    for (Map.Entry<String, TaskFile> entry : files.entrySet()) {
+      String name = entry.getKey();
+      VirtualFile child = taskDir.findChild(name);
+      if (child == null) {
+        continue;
+      }
+      Document patternDocument = StudyUtils.getPatternDocument(entry.getValue(), name);
+      Document document = FileDocumentManager.getInstance().getDocument(child);
+      if (document == null || patternDocument == null) {
+        return;
+      }
+      DocumentUtil.writeInRunUndoTransparentAction(() -> {
+        patternDocument.replaceString(0, patternDocument.getTextLength(), document.getCharsSequence());
+        FileDocumentManager.getInstance().saveDocument(patternDocument);
+      });
+      TaskFile target = new TaskFile();
+      TaskFile.copy(entry.getValue(), target);
+      for (AnswerPlaceholder placeholder : target.getAnswerPlaceholders()) {
+        placeholder.setUseLength(false);
+      }
+      EduUtils.createStudentDocument(project, target, child, patternDocument);
+    }
+  }
 }
similarity index 54%
rename from python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCFileDeletedListener.java
rename to python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/CCVirtualFileListener.java
index 1d840f0c594300b38b631eb6ee8f7df3efd884ff..3c3be598ca7f064e7ced9d1d437285a9bff197e8 100644 (file)
@@ -1,54 +1,95 @@
 package com.jetbrains.edu.coursecreator;
 
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileAdapter;
 import com.intellij.openapi.vfs.VirtualFileEvent;
 import com.intellij.util.Function;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.core.EduNames;
 import com.jetbrains.edu.learning.courseFormat.*;
 import org.jetbrains.annotations.NotNull;
 
-class CCFileDeletedListener extends VirtualFileAdapter {
+public class CCVirtualFileListener extends VirtualFileAdapter {
 
-  private final Project myProject;
+  private static final Logger LOG = Logger.getInstance(CCVirtualFileListener.class);
 
-  CCFileDeletedListener(@NotNull final Project project) {
-    myProject = project;
+  @Override
+  public void fileCreated(@NotNull VirtualFileEvent event) {
+    VirtualFile createdFile = event.getFile();
+    Project project = ProjectUtil.guessProjectForFile(createdFile);
+    if (project == null) {
+      return;
+    }
+    Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null || !CCUtils.isCourseCreator(project)) {
+      return;
+    }
+    TaskFile taskFile = StudyUtils.getTaskFile(project, createdFile);
+    if (taskFile != null) {
+      return;
+    }
+
+    String name = createdFile.getName();
+    if (CCUtils.isTestsFile(project, createdFile)
+        || EduNames.TASK_HTML.equals(name)
+        || name.contains(EduNames.WINDOW_POSTFIX)
+        || name.contains(EduNames.WINDOWS_POSTFIX)
+        || name.contains(EduNames.ANSWERS_POSTFIX)) {
+      return;
+    }
+
+    VirtualFile taskVF = createdFile.getParent();
+    if (taskVF == null) {
+      return;
+    }
+    Task task = StudyUtils.getTask(project, taskVF);
+    if (task == null) {
+      return;
+    }
+
+    CCUtils.createResourceFile(createdFile, course, taskVF);
+
+    task.addTaskFile(name, 1);
   }
 
   @Override
   public void fileDeleted(@NotNull VirtualFileEvent event) {
-    if (myProject.isDisposed() || !myProject.isOpen()) {
-      return;
-    }
     VirtualFile removedFile = event.getFile();
     if (removedFile.getPath().contains(CCUtils.GENERATED_FILES_FOLDER)) {
       return;
     }
-    final TaskFile taskFile = CCProjectService.getInstance(myProject).getTaskFile(removedFile);
-    if (taskFile != null) {
-      deleteTaskFile(removedFile, taskFile);
+
+    Project project = ProjectUtil.guessProjectForFile(removedFile);
+    if (project == null) {
       return;
     }
-    Course course = CCProjectService.getInstance(myProject).getCourse();
+    Course course = StudyTaskManager.getInstance(project).getCourse();
     if (course == null) {
       return;
     }
+    final TaskFile taskFile = StudyUtils.getTaskFile(project, removedFile);
+    if (taskFile != null) {
+      deleteTaskFile(removedFile, taskFile);
+      return;
+    }
     if (removedFile.getName().contains(EduNames.TASK)) {
-      deleteTask(course, removedFile, myProject);
+      deleteTask(course, removedFile);
     }
     if (removedFile.getName().contains(EduNames.LESSON)) {
-      deleteLesson(course, removedFile);
+      deleteLesson(course, removedFile, project);
     }
   }
 
-  private void deleteLesson(@NotNull final Course course, @NotNull final VirtualFile removedLessonFile) {
+  private static void deleteLesson(@NotNull final Course course, @NotNull final VirtualFile removedLessonFile, Project project) {
     Lesson removedLesson = course.getLesson(removedLessonFile.getName());
     if (removedLesson == null) {
       return;
     }
-    VirtualFile courseDir = myProject.getBaseDir();
+    VirtualFile courseDir = project.getBaseDir();
     CCUtils.updateHigherElements(courseDir.getChildren(), new Function<VirtualFile, StudyItem>() {
       @Override
       public StudyItem fun(VirtualFile file) {
@@ -58,7 +99,7 @@ class CCFileDeletedListener extends VirtualFileAdapter {
     course.getLessons().remove(removedLesson);
   }
 
-  private static void deleteTask(@NotNull final Course course, @NotNull final VirtualFile removedTask, @NotNull final Project project) {
+  private static void deleteTask(@NotNull final Course course, @NotNull final VirtualFile removedTask) {
     VirtualFile lessonDir = removedTask.getParent();
     if (lessonDir == null || !lessonDir.getName().contains(EduNames.LESSON)) {
       return;
index 791d7fb0efae49949a7713ab5c2248292ba7f748..5eae370909ee4d5cbce19b63cc5c9601eb835032 100644 (file)
@@ -1,32 +1,32 @@
 package com.jetbrains.edu.coursecreator.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.SelectionModel;
-import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiFile;
 import com.intellij.ui.JBColor;
-import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
-import com.jetbrains.edu.coursecreator.CCProjectService;
+import com.intellij.util.DocumentUtil;
 import com.jetbrains.edu.coursecreator.ui.CCCreateAnswerPlaceholderDialog;
-import com.jetbrains.edu.learning.courseFormat.*;
+import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.core.EduAnswerPlaceholderPainter;
+import com.jetbrains.edu.learning.core.EduNames;
+import com.jetbrains.edu.learning.core.EduUtils;
+import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
+import com.jetbrains.edu.learning.courseFormat.TaskFile;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
-public class CCAddAnswerPlaceholder extends DumbAwareAction {
-  private static final Logger LOG = Logger.getInstance(CCAddAnswerPlaceholder.class);
+public class CCAddAnswerPlaceholder extends CCAnswerPlaceholderAction {
 
   public CCAddAnswerPlaceholder() {
-    super("Add Answer Placeholder", "Add answer placeholder", null);
+    super("Add/Delete Answer Placeholder", "Add/Delete answer placeholder", null);
   }
 
 
@@ -43,114 +43,131 @@ public class CCAddAnswerPlaceholder extends DumbAwareAction {
     return false;
   }
 
-  @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-    final Project project = e.getData(CommonDataKeys.PROJECT);
-    if (project == null) {
+  private static void addPlaceholder(@NotNull CCState state) {
+    Editor editor = state.getEditor();
+    Project project = state.getProject();
+    PsiFile file = state.getFile();
+
+    final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+    if (document == null) {
       return;
     }
-    final PsiFile file = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
-    if (file == null) return;
-    final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
-    if (editor == null) return;
+
     final SelectionModel model = editor.getSelectionModel();
-    final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
-    if (document == null) return;
     final int start = model.getSelectionStart();
-    final int end = model.getSelectionEnd();
     final int lineNumber = document.getLineNumber(start);
     int realStart = start - document.getLineStartOffset(lineNumber);
-
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final PsiDirectory taskDir = file.getContainingDirectory();
-    final PsiDirectory lessonDir = taskDir.getParent();
-    if (lessonDir == null) return;
-
-    final TaskFile taskFile = service.getTaskFile(file.getVirtualFile());
-    if (taskFile == null) {
-      return;
-    }
-    if (arePlaceholdersIntersect(taskFile, document, start, end)) {
-      return;
-    }
     final AnswerPlaceholder answerPlaceholder = new AnswerPlaceholder();
     answerPlaceholder.setLine(lineNumber);
     answerPlaceholder.setStart(realStart);
-    answerPlaceholder.setPossibleAnswer(model.getSelectedText());
+    answerPlaceholder.setUseLength(false);
+    String selectedText = model.getSelectedText();
+    answerPlaceholder.setPossibleAnswer(selectedText);
 
-    CCCreateAnswerPlaceholderDialog dlg = new CCCreateAnswerPlaceholderDialog(project, answerPlaceholder
-    );
+    CCCreateAnswerPlaceholderDialog dlg = new CCCreateAnswerPlaceholderDialog(project, answerPlaceholder);
     dlg.show();
     if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
       return;
     }
+
+    TaskFile taskFile = state.getTaskFile();
     int index = taskFile.getAnswerPlaceholders().size() + 1;
     answerPlaceholder.setIndex(index);
     taskFile.addAnswerPlaceholder(answerPlaceholder);
+    answerPlaceholder.setTaskFile(taskFile);
     taskFile.sortAnswerPlaceholders();
-    EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, false, JBColor.BLUE);
-    EduAnswerPlaceholderPainter.createGuardedBlocks(editor, answerPlaceholder, false);
+
+
+    computeInitialState(project, file, taskFile, document);
+
+    EduAnswerPlaceholderPainter.drawAnswerPlaceholder(editor, answerPlaceholder, JBColor.BLUE);
+    EduAnswerPlaceholderPainter.createGuardedBlocks(editor, answerPlaceholder);
+  }
+
+  private static void computeInitialState(Project project, PsiFile file, TaskFile taskFile, Document document) {
+    Document patternDocument = StudyUtils.getPatternDocument(taskFile, file.getName());
+    if (patternDocument == null) {
+      return;
+    }
+    DocumentUtil.writeInRunUndoTransparentAction(() -> {
+      patternDocument.replaceString(0, patternDocument.getTextLength(), document.getCharsSequence());
+      FileDocumentManager.getInstance().saveDocument(patternDocument);
+    });
+    TaskFile target = new TaskFile();
+    TaskFile.copy(taskFile, target);
+    List<AnswerPlaceholder> placeholders = target.getAnswerPlaceholders();
+    for (AnswerPlaceholder placeholder : placeholders) {
+      placeholder.setUseLength(false);
+    }
+    EduUtils.createStudentDocument(project, target, file.getVirtualFile(), patternDocument);
+
+    for (int i = 0; i < placeholders.size(); i++) {
+      AnswerPlaceholder fromPlaceholder = placeholders.get(i);
+      taskFile.getAnswerPlaceholders().get(i).setInitialState(fromPlaceholder);
+    }
   }
 
   @Override
-  public void update(@NotNull AnActionEvent event) {
-    if (!CCProjectService.setCCActionAvailable(event)) {
+  protected void performAnswerPlaceholderAction(@NotNull CCState state) {
+    if (canAddPlaceholder(state)) {
+      addPlaceholder(state);
       return;
     }
+    if (canDeletePlaceholder(state)) {
+      deletePlaceholder(state);
+    }
+  }
+
+  private static void deletePlaceholder(@NotNull CCState state) {
+    Project project = state.getProject();
+    PsiFile psiFile = state.getFile();
+    final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
+    if (document == null) return;
+    TaskFile taskFile = state.getTaskFile();
+    AnswerPlaceholder answerPlaceholder = state.getAnswerPlaceholder();
+    final List<AnswerPlaceholder> answerPlaceholders = taskFile.getAnswerPlaceholders();
+    if (answerPlaceholders.contains(answerPlaceholder)) {
+      answerPlaceholders.remove(answerPlaceholder);
+      final Editor editor = state.getEditor();
+      editor.getMarkupModel().removeAllHighlighters();
+      StudyUtils.drawAllWindows(editor, taskFile);
+      EduAnswerPlaceholderPainter.createGuardedBlocks(editor, taskFile);
+    }
+  }
+
+  @Override
+  public void update(@NotNull AnActionEvent event) {
     final Presentation presentation = event.getPresentation();
-    final Project project = event.getData(CommonDataKeys.PROJECT);
-    if (project == null) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
+    presentation.setEnabledAndVisible(false);
+
+    CCState state = getState(event);
+    if (state == null) {
       return;
     }
-    final Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext());
-    final PsiFile file = CommonDataKeys.PSI_FILE.getData(event.getDataContext());
-    if (editor == null || file == null) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
+
+    presentation.setVisible(true);
+    if (canAddPlaceholder(state) || canDeletePlaceholder(state)) {
+      presentation.setEnabled(true);
+      presentation.setText((state.getAnswerPlaceholder() == null ? "Add " : "Delete ") + EduNames.PLACEHOLDER);
     }
+  }
+
+
+  private static boolean canAddPlaceholder(@NotNull CCState state) {
+    Editor editor = state.getEditor();
     SelectionModel selectionModel = editor.getSelectionModel();
     if (!selectionModel.hasSelection()) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
+      return false;
     }
     int start = selectionModel.getSelectionStart();
     int end = selectionModel.getSelectionEnd();
+    return !arePlaceholdersIntersect(state.getTaskFile(), editor.getDocument(), start, end);
+  }
 
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final PsiDirectory taskDir = file.getContainingDirectory();
-    final PsiDirectory lessonDir = taskDir.getParent();
-    if (lessonDir == null) return;
-
-    final Course course = service.getCourse();
-    final Lesson lesson = course.getLesson(lessonDir.getName());
-    if (lesson == null) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
+  private static boolean canDeletePlaceholder(@NotNull CCState state) {
+    if (state.getEditor().getSelectionModel().hasSelection()) {
+      return false;
     }
-    final Task task = lesson.getTask(taskDir.getName());
-    if (task == null) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
-    }
-    TaskFile taskFile = service.getTaskFile(file.getVirtualFile());
-    if (taskFile == null) {
-      LOG.info("could not find task file");
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
-    }
-    if (arePlaceholdersIntersect(taskFile, editor.getDocument(), start, end)) {
-      presentation.setVisible(false);
-      presentation.setEnabled(false);
-      return;
-    }
-    presentation.setVisible(true);
-    presentation.setEnabled(true);
+    return state.getAnswerPlaceholder() != null;
   }
 }
\ No newline at end of file
index 867cc77440b6418f26c779965862097b65258301..c62bd5e1e069935658d820f8a6e93e5e4547e6df 100644 (file)
@@ -1,46 +1,20 @@
 package com.jetbrains.edu.coursecreator.actions;
 
-import com.intellij.ide.projectView.ProjectView;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.edu.coursecreator.CCUtils;
+import com.jetbrains.edu.learning.StudyUtils;
+import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.Task;
-import com.jetbrains.edu.coursecreator.CCProjectService;
 
-public class CCAddAsTaskFile extends AnAction {
-  @Override
-  public void actionPerformed(final AnActionEvent e) {
-    Project project = e.getProject();
-    if (project == null) {
-      return;
-    }
-    final VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
-    if (file == null) {
-      return;
-    }
-    Task task = CCProjectService.getInstance(project).getTask(file);
-    if (task == null) {
-      return;
-    }
+public class CCAddAsTaskFile extends CCTaskFileActionBase {
+
+  protected void performAction(VirtualFile file, Task task, Course course, Project project) {
     task.addTaskFile(file.getName(), task.getTaskFiles().size());
-    ProjectView.getInstance(project).refresh();
+    CCUtils.createResourceFile(file, course, StudyUtils.getTaskDir(file));
   }
 
-
-  @Override
-  public void update(AnActionEvent e) {
-    Project project = e.getProject();
-    Presentation presentation = e.getPresentation();
-    if (project == null) {
-      presentation.setEnabledAndVisible(false);
-      return;
-    }
-    VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
-    if (file == null || file.isDirectory() || CCProjectService.getInstance(project).getTaskFile(file) != null) {
-      presentation.setEnabledAndVisible(false);
-    }
+  protected boolean isAvailable(Project project, VirtualFile file) {
+    return StudyUtils.getTaskFile(project, file) == null && !CCUtils.isTestsFile(project, file);
   }
 }
index 48425e247100938014dc46891a205968394bb1b2..e1633044d5e6ea34c1ba82900af38739bde6b054 100644 (file)
@@ -2,15 +2,15 @@ package com.jetbrains.edu.coursecreator.actions;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiFile;
+import com.jetbrains.edu.coursecreator.CCUtils;
+import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
 import com.jetbrains.edu.learning.courseFormat.TaskFile;
-import com.jetbrains.edu.coursecreator.CCProjectService;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -23,9 +23,9 @@ abstract public class CCAnswerPlaceholderAction extends DumbAwareAction {
   }
 
   @Nullable
-  private static CCState getState(@NotNull AnActionEvent e) {
+  protected static CCState getState(@NotNull AnActionEvent e) {
     final Project project = e.getProject();
-    if (project == null || CCProjectService.getInstance(project).getCourse() == null) {
+    if (project == null || !CCUtils.isCourseCreator(project)) {
       return null;
     }
     final PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(e.getDataContext());
@@ -40,27 +40,16 @@ abstract public class CCAnswerPlaceholderAction extends DumbAwareAction {
     if (editor == null) {
       return null;
     }
-    TaskFile taskFile = CCProjectService.getInstance(project).getTaskFile(virtualFile);
+    TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile);
     if (taskFile == null) {
       return null;
     }
     AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholder(editor.getDocument(),
                                                                         editor.getCaretModel().getLogicalPosition(),
                                                                         true);
-    if (answerPlaceholder == null) {
-      return null;
-    }
     return new CCState(taskFile, answerPlaceholder, psiFile, editor, project);
   }
 
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    Presentation presentation = e.getPresentation();
-    boolean isAvailable = getState(e) != null;
-    presentation.setEnabled(isAvailable);
-    presentation.setVisible(isAvailable);
-  }
-
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
     CCState state = getState(e);
@@ -80,7 +69,7 @@ abstract public class CCAnswerPlaceholderAction extends DumbAwareAction {
     private Project myProject;
 
     public CCState(@NotNull final TaskFile taskFile,
-                   @NotNull final AnswerPlaceholder answerPlaceholder,
+                   @Nullable final AnswerPlaceholder answerPlaceholder,
                    @NotNull final PsiFile file,
                    @NotNull final Editor editor,
                    @NotNull final Project project) {
@@ -96,7 +85,7 @@ abstract public class CCAnswerPlaceholderAction extends DumbAwareAction {
       return myTaskFile;
     }
 
-    @NotNull
+    @Nullable
     public AnswerPlaceholder getAnswerPlaceholder() {
       return myAnswerPlaceholder;
     }
index 28706dae9a72da9a16cce7d84e5f6199e19cba5f..3423c822aae87f9453710ffaee944990e898aff6 100644 (file)
@@ -2,41 +2,41 @@ package com.jetbrains.edu.coursecreator.actions;
 
 import com.intellij.ide.IdeView;
 import com.intellij.ide.projectView.ProjectView;
-import com.intellij.ide.util.DirectoryChooserUtil;
 import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.LangDataKeys;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.DialogBuilder;
 import com.intellij.psi.PsiDirectory;
-import com.jetbrains.edu.learning.courseFormat.Course;
-import com.jetbrains.edu.coursecreator.CCProjectService;
+import com.intellij.util.ui.JBUI;
+import com.jetbrains.edu.coursecreator.CCUtils;
 import com.jetbrains.edu.coursecreator.ui.CCNewProjectPanel;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.courseFormat.Course;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
-import java.awt.*;
 
 public class CCChangeCourseInfo extends DumbAwareAction {
+
+  private static final String ACTION_TEXT = "Change Course Information";
+
   public CCChangeCourseInfo() {
-    super("Change Course Information", "Change Course Information", null);
+    super(ACTION_TEXT, ACTION_TEXT, null);
   }
 
   @Override
   public void update(@NotNull AnActionEvent event) {
-    if (!CCProjectService.setCCActionAvailable(event)) {
-      return;
-    }
+    final Project project = event.getProject();
     final Presentation presentation = event.getPresentation();
-    presentation.setVisible(false);
-    presentation.setEnabled(false);
-    final Project project = event.getData(CommonDataKeys.PROJECT);
     if (project == null) {
       return;
     }
+    presentation.setEnabledAndVisible(false);
+    if (!CCUtils.isCourseCreator(project)) {
+      return;
+    }
     final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
     if (view == null) {
       return;
@@ -45,45 +45,24 @@ public class CCChangeCourseInfo extends DumbAwareAction {
     if (directories.length == 0) {
       return;
     }
-    final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
-    if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) {
-      return;
-    }
-    presentation.setVisible(true);
-    presentation.setEnabled(true);
-
+    presentation.setEnabledAndVisible(true);
   }
 
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
-    if (!CCProjectService.setCCActionAvailable(e)) {
-      return;
-    }
-    final Project project = e.getProject();
+    Project project = e.getProject();
     if (project == null) {
       return;
     }
-    Course course = CCProjectService.getInstance(project).getCourse();
+    Course course = StudyTaskManager.getInstance(project).getCourse();
     if (course == null) {
       return;
     }
-    final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
-    if (view == null) {
-      return;
-    }
-    final PsiDirectory[] directories = view.getDirectories();
-    if (directories.length == 0) {
-      return;
-    }
-    final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
-    if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) {
-      return;
-    }
-    CCNewProjectPanel panel = new CCNewProjectPanel(course.getName(), Course.getAuthorsString(course.getAuthors()), course.getDescription());
-    ChangeCourseInfoDialog changeCourseInfoDialog =
-      new ChangeCourseInfoDialog(project, panel);
-    changeCourseInfoDialog.show();
-    if (changeCourseInfoDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+
+    CCNewProjectPanel panel =
+      new CCNewProjectPanel(course.getName(), Course.getAuthorsString(course.getAuthors()), course.getDescription());
+    DialogBuilder builder = createChangeInfoDialog(project, panel);
+    if (builder.showAndGet()) {
       course.setAuthors(panel.getAuthors());
       course.setName(panel.getName());
       course.setDescription(panel.getDescription());
@@ -91,24 +70,14 @@ public class CCChangeCourseInfo extends DumbAwareAction {
     }
   }
 
-  static class ChangeCourseInfoDialog extends DialogWrapper {
+  private static DialogBuilder createChangeInfoDialog(Project project, @NotNull CCNewProjectPanel panel) {
+    DialogBuilder builder = new DialogBuilder(project);
 
-    private final JPanel myMainPanel;
+    builder.setTitle(ACTION_TEXT);
+    JPanel changeInfoPanel = panel.getMainPanel();
+    changeInfoPanel.setMinimumSize(JBUI.size(400, 300));
+    builder.setCenterPanel(changeInfoPanel);
 
-    public ChangeCourseInfoDialog(@Nullable Project project, CCNewProjectPanel panel) {
-      super(project);
-      setTitle("Change Course Information");
-      myMainPanel = panel.getMainPanel();
-      init();
-    }
-
-    @Nullable
-    @Override
-    protected JComponent createCenterPanel() {
-      myMainPanel.setPreferredSize(new Dimension(400, 300));
-      myMainPanel.setSize(new Dimension(400, 300));
-      myMainPanel.setMaximumSize(new Dimension(400, 300));
-      return myMainPanel;
-    }
+    return builder;
   }
 }
index 486f3b247c5dc83407f98dbb46bfc8d28009453e..bbef6bc15515ac198da960d5a73799e9ec4eff1e 100644 (file)
@@ -7,6 +7,7 @@ import com.intellij.ide.projectView.ProjectView;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
@@ -20,6 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.VirtualFileManager;
 import com.intellij.util.containers.HashMap;
 import com.intellij.util.io.ZipUtil;
+import com.jetbrains.edu.learning.StudyTaskManager;
 import com.jetbrains.edu.learning.core.EduNames;
 import com.jetbrains.edu.learning.core.EduUtils;
 import com.jetbrains.edu.learning.courseFormat.Course;
@@ -27,7 +29,6 @@ import com.jetbrains.edu.learning.courseFormat.Lesson;
 import com.jetbrains.edu.learning.courseFormat.Task;
 import com.jetbrains.edu.learning.courseFormat.TaskFile;
 import com.jetbrains.edu.coursecreator.CCLanguageManager;
-import com.jetbrains.edu.coursecreator.CCProjectService;
 import com.jetbrains.edu.coursecreator.CCUtils;
 import com.jetbrains.edu.coursecreator.ui.CreateCourseArchiveDialog;
 import org.jetbrains.annotations.NotNull;
@@ -56,7 +57,9 @@ public class CCCreateCourseArchive extends DumbAwareAction {
 
   @Override
   public void update(@NotNull AnActionEvent e) {
-    CCProjectService.setCCActionAvailable(e);
+    Presentation presentation = e.getPresentation();
+    Project project = e.getProject();
+    presentation.setEnabledAndVisible(project != null && CCUtils.isCourseCreator(project));
   }
 
   @Override
@@ -70,8 +73,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
   }
 
   private void createCourseArchive(final Project project, Module module) {
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final Course course = service.getCourse();
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
     if (course == null) return;
     CreateCourseArchiveDialog dlg = new CreateCourseArchiveDialog(project, this);
     dlg.show();
@@ -195,8 +197,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
 
   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
   private static void generateJson(@NotNull final Project project, VirtualFile parentDir) {
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final Course course = service.getCourse();
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
     final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
     final String json = gson.toJson(course);
     final File courseJson = new File(parentDir.getPath(), EduNames.COURSE_META_FILE);
index 520ce0961a6a13356c97dc421ffca64c3dc4af85..45310c7c0e8fe6959ec354846da78a94374f235a 100644 (file)
@@ -14,12 +14,13 @@ import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiDirectory;
 import com.intellij.util.Function;
+import com.jetbrains.edu.coursecreator.CCUtils;
+import com.jetbrains.edu.coursecreator.ui.CCCreateStudyItemDialog;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.core.EduUtils;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.StudyItem;
-import com.jetbrains.edu.coursecreator.CCProjectService;
-import com.jetbrains.edu.coursecreator.CCUtils;
-import com.jetbrains.edu.coursecreator.ui.CCCreateStudyItemDialog;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -33,18 +34,16 @@ public abstract class CCCreateStudyItemActionBase extends DumbAwareAction {
     super(text, description, icon);
   }
 
-
   @Override
   public void actionPerformed(AnActionEvent e) {
     final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
-    final Project project = e.getData(CommonDataKeys.PROJECT);
+    final Project project = e.getProject();
     if (view == null || project == null) {
       return;
     }
     final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
     if (directory == null) return;
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final Course course = service.getCourse();
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
     if (course == null) {
       return;
     }
@@ -54,47 +53,45 @@ public abstract class CCCreateStudyItemActionBase extends DumbAwareAction {
 
   @Override
   public void update(@NotNull AnActionEvent event) {
-    if (!CCProjectService.setCCActionAvailable(event)) {
-      return;
-    }
     final Presentation presentation = event.getPresentation();
+    presentation.setEnabledAndVisible(false);
     final Project project = event.getData(CommonDataKeys.PROJECT);
     final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
     if (project == null || view == null) {
       presentation.setEnabledAndVisible(false);
       return;
     }
+    if (!StudyUtils.isStudyProject(project)) {
+      return;
+    }
     final PsiDirectory[] directories = view.getDirectories();
     if (directories.length == 0) {
-      presentation.setEnabledAndVisible(false);
       return;
     }
     final PsiDirectory sourceDirectory = DirectoryChooserUtil.getOrChooseDirectory(view);
-    final CCProjectService service = CCProjectService.getInstance(project);
-    final Course course = service.getCourse();
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
     if (course == null || sourceDirectory == null) {
-      presentation.setEnabledAndVisible(false);
       return;
     }
-    if (!isAddedAsLast(sourceDirectory, project, course) &&
-        getThresholdItem(course, sourceDirectory) == null) {
-      presentation.setEnabledAndVisible(false);
+    if (!isAddedAsLast(sourceDirectory, project, course) && getThresholdItem(course, sourceDirectory) == null) {
+      return;
     }
     if (CommonDataKeys.PSI_FILE.getData(event.getDataContext()) != null) {
-      presentation.setEnabledAndVisible(false);
+      return;
     }
+    presentation.setEnabledAndVisible(true);
   }
 
 
   @Nullable
   protected abstract PsiDirectory getParentDir(@NotNull final Project project,
-                                          @NotNull final Course course,
-                                          @NotNull final PsiDirectory directory);
+                                               @NotNull final Course course,
+                                               @NotNull final PsiDirectory directory);
 
 
   @Nullable
   public PsiDirectory createItem(@Nullable final IdeView view, @NotNull final Project project,
-                                             @NotNull final PsiDirectory sourceDirectory, @NotNull final Course course) {
+                                 @NotNull final PsiDirectory sourceDirectory, @NotNull final Course course) {
     StudyItem parentItem = getParentItem(course, sourceDirectory);
     final StudyItem item = getItem(sourceDirectory, project, course, view, parentItem);
     if (item == null) {