summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-07-16 19:12:10 -0700
committerTor Norbye <tnorbye@google.com>2014-07-16 19:12:10 -0700
commita8218d5392f624b0497645a14c978e8faa946a31 (patch)
tree8b11c743aa1cc0ab2caca62c4f8b73d393b43ea6
parent3827bb9f227f90806560251c7dd048d30c081c25 (diff)
parent65f60eb9011bb2c549a6d83ae31257480368ddc5 (diff)
downloadidea-a8218d5392f624b0497645a14c978e8faa946a31.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into merge
Conflicts: .idea/modules.xml build/scripts/common_tests.gant build/scripts/dist.gant build/scripts/layouts.gant build/scripts/utils.gant Change-Id: I2bdcfaa02c8c63585eb6a56020dd3dbe0be90119
-rw-r--r--.idea/inspectionProfiles/idea_default.xml8
-rw-r--r--.idea/inspectionProfiles/idea_default_no_spellchecker.xml8
-rw-r--r--.idea/libraries/Guava.xml4
-rw-r--r--.idea/libraries/JaCoCo.xml17
-rw-r--r--.idea/libraries/Netty.xml4
-rw-r--r--.idea/libraries/nekohtml.xml9
-rw-r--r--.idea/modules.xml11
-rw-r--r--.idea/runConfigurations/IDEA.xml4
-rw-r--r--.idea/runConfigurations/IDEA_with_Python_plugin.xml4
-rw-r--r--.idea/runConfigurations/PyCharm.xml4
-rwxr-xr-xbin/mac/fsnotifierbin13984 -> 13984 bytes
-rw-r--r--build/build.iml2
-rw-r--r--build/conf/mac/Contents/Info.plist4
-rwxr-xr-xbuild/conf/mac/Contents/MacOS/ideabin85548 -> 85564 bytes
-rw-r--r--build/conf/mac/Contents/_CodeSignature/CodeResources21
-rw-r--r--build/conf/nsis/idea.nsi99
-rw-r--r--build/gant.xml2
-rw-r--r--build/lib/jps/antlayout.jarbin22226 -> 22248 bytes
-rw-r--r--build/lib/jps/groovy-jps-plugin.jarbin37122 -> 37218 bytes
-rw-r--r--build/lib/jps/groovy_rt.jarbin33228 -> 33243 bytes
-rw-r--r--build/lib/jps/jps-builders.jarbin1496212 -> 1500322 bytes
-rw-r--r--build/lib/jps/jps-model.jarbin430385 -> 431932 bytes
-rw-r--r--build/lib/jps/ui-designer-jps-plugin.jarbin32656 -> 32685 bytes
-rw-r--r--build/lib/jps/util.jarbin2183123 -> 2189527 bytes
-rw-r--r--build/scripts/common_tests.gant60
-rw-r--r--build/scripts/dist.gant4
-rw-r--r--build/scripts/layouts.gant71
-rw-r--r--build/scripts/libLicenses.gant13
-rw-r--r--build/scripts/utils.gant55
-rw-r--r--community-main.iml5
-rw-r--r--community-tests/src/tests/testGroups.properties3
-rw-r--r--images/src/META-INF/ImagesPlugin.xml2
-rw-r--r--images/src/org/intellij/images/editor/impl/ImageEditorUI.java29
-rw-r--r--java/compiler/forms-compiler/forms-compiler.iml2
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java26
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java4
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java8
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java8
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java2
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java38
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java6
-rw-r--r--java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java4
-rw-r--r--java/compiler/impl/compiler-impl.iml2
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java2
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java5
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java2
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/context/TargetType.java11
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java3
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java2
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java7
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java29
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java2
-rw-r--r--java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java17
-rw-r--r--java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java17
-rw-r--r--java/compiler/instrumentation-util/instrumentation-util.iml2
-rw-r--r--java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java10
-rw-r--r--java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java2
-rw-r--r--java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java16
-rw-r--r--java/compiler/javac2/javac2.iml2
-rw-r--r--java/compiler/javac2/src/com/intellij/ant/Javac2.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java20
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java9
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java86
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java13
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java20
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java9
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java8
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java6
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java93
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java15
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java126
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java6
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java24
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java13
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java59
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java61
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java82
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java94
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java109
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java36
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java23
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java17
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java8
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java40
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java28
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java6
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java6
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java17
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java6
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java16
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java19
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java3
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java15
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java33
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java8
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java8
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java9
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java44
-rw-r--r--java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java77
-rw-r--r--java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java39
-rw-r--r--java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java26
-rw-r--r--java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java20
-rw-r--r--java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java11
-rw-r--r--java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java5
-rw-r--r--java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java36
-rw-r--r--java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java14
-rw-r--r--java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java2
-rw-r--r--java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java32
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java12
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java24
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java28
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java2
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java2
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelInClasspathAction.java10
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java13
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java8
-rw-r--r--java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java8
-rw-r--r--java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java27
-rw-r--r--java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java14
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java3
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaBatchLocalInspectionTool.java14
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java6
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaBatchInspectionTool.java12
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java16
-rw-r--r--java/java-analysis-api/src/com/intellij/codeInspection/SuppressManager.java2
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java3
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java14
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java6
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInsight/intention/EmptyQuickFixFactory.java6
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java1
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java24
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java5
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java84
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java9
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StringExpressionHelper.java26
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java5
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspectionBase.java4
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java12
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java25
-rw-r--r--java/java-impl/java-impl.iml3
-rw-r--r--java/java-impl/src/com/intellij/application/options/editor/JavaCodeFoldingOptionsProvider.java1
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java8
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java24
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java12
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java7
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java41
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java162
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModuleDependencyFix.java14
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java13
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java11
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java3
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/SwapIfStatementsIntentionAction.java75
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java6
-rw-r--r--java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java9
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/RemoveAssignmentFix.java2
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java16
-rw-r--r--java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java3
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/FindThrowUsagesDialog.java17
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java6
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java14
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java2
-rw-r--r--java/java-impl/src/com/intellij/find/findUsages/JavaThrowFindUsagesOptions.java24
-rw-r--r--java/java-impl/src/com/intellij/jarFinder/FindJarFix.java24
-rw-r--r--java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java2
-rw-r--r--java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java4
-rw-r--r--java/java-impl/src/com/intellij/psi/codeStyle/arrangement/FieldDependenciesManager.java56
-rw-r--r--java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java83
-rw-r--r--java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java30
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateBeanPropertyFix.java6
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/search/ThrowSearchUtil.java19
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java52
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java5
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PackagePrefixFileSystemItemImpl.java9
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java16
-rw-r--r--java/java-impl/src/com/intellij/psi/impl/source/tree/injected/MyTestInjector.java8
-rw-r--r--java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java5
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineLocalDialog.java6
-rw-r--r--java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java24
-rw-r--r--java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java4
-rw-r--r--java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java2
-rw-r--r--java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java11
-rw-r--r--java/java-impl/src/com/intellij/slicer/SliceUtil.java30
-rw-r--r--java/java-impl/src/com/intellij/spellchecker/JavaSpellcheckingStrategy.java17
-rw-r--r--java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java6
-rw-r--r--java/java-indexing-api/src/com/intellij/psi/search/searches/AllClassesSearch.java4
-rw-r--r--java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java1
-rw-r--r--java/java-psi-api/src/com/intellij/codeInsight/folding/JavaCodeFoldingSettings.java3
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java4
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java1
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiParameter.java2
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java1
-rw-r--r--java/java-psi-api/src/com/intellij/psi/search/PackageScope.java4
-rw-r--r--java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java14
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/IsConstantExpressionVisitor.java8
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java4
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java10
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java14
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java18
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java16
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java4
-rw-r--r--java/java-psi-api/src/com/intellij/util/VisibilityIcons.java5
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java11
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java72
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java80
-rw-r--r--java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java7
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/ClassFileViewProviderFactory.java1
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java31
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java12
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java130
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/file/impl/JavaFileManager.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java40
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java15
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java72
-rw-r--r--java/java-psi-impl/src/messages/JavaErrorMessages.properties1
-rw-r--r--java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java51
-rw-r--r--java/java-tests/java-tests.iml2
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/ArrayInitializerRBracket_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/BraceFixeNewLine_after.java1
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/CdrEndlessLoop_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/FollowedByComment_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/IDEA22125_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/IDEADEV40479_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/IncompleteCall_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/NewInParentheses_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/Parenthesized_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completeStatement/StringLiteral_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/CharsetName.java7
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/DeepInner.java13
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/DeepInner_after.java13
-rw-r--r--java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java3
-rw-r--r--java/java-tests/testData/codeInsight/completion/normalSorting/HonorFirstLetterCase.java11
-rw-r--r--java/java-tests/testData/codeInsight/completion/normalSorting/PreferAnnotationsToInterfaceKeyword.java4
-rw-r--r--java/java-tests/testData/codeInsight/completion/normalSorting/PreferThrownExceptionsInCatch.java15
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartType/ConstructorArgsSmartEnter-out.java3
-rw-r--r--java/java-tests/testData/codeInsight/completion/smartType/SmartFinish-out.java3
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/IllegalForwardReference.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java32
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java48
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg7.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA111420.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA124363.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA125423.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126633.java15
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126697.java8
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParent.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParentArrayType.java14
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Intersection.java4
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/RecursiveAccess.java2
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA119003.java30
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124961.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA125254.java103
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126109.java26
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126809.java27
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java25
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/MissedApplicableMemberContainingClassSubstitution.java54
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/RejectReceiverTypesForConstructorRefs.java21
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/Constructor.java26
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixAfter.java20
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixBefore.java20
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NestedMethod.java36
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NonStaticMethod.java26
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticInitializer.java26
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticMethod.java26
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeSelfReference.java9
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterInsideNestedInner.java18
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideAnonymous.java17
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideNestedInner.java18
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterBase.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterManyStatements.java20
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterWithoutBrackets.java12
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeBase.java16
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeManyStatements.java20
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeNotAvailable.java10
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeWithoutBrackets.java12
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/afterCallAsArgument.java11
-rw-r--r--java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/beforeCallAsArgument.java11
-rw-r--r--java/java-tests/testData/codeInsight/javadocIG/annotations.html3
-rw-r--r--java/java-tests/testData/codeInsight/javadocIG/annotations.java5
-rw-r--r--java/java-tests/testData/codeInsight/slice/backward/VarArgsAsAWhole.java12
-rw-r--r--java/java-tests/testData/codeInsight/slice/backward/VarArgsPartial.java14
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/AssertTrueNotComplex.java17
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java14
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java16
-rw-r--r--java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java16
-rw-r--r--java/java-tests/testData/inspection/offline/project/src/Test.java52
-rw-r--r--java/java-tests/testData/inspection/offline/res/UnusedAssignment.xml130
-rw-r--r--java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/expected.xml2
-rw-r--r--java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/src/Test.java11
-rw-r--r--java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml2
-rw-r--r--java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java10
-rw-r--r--java/java-tests/testData/inspection/suspiciousCalls/RemoveAll14.java14
-rw-r--r--java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt1470
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java13
-rw-r--r--java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java.after9
-rw-r--r--java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/after/Outer.java10
-rw-r--r--java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/before/Outer.java9
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy13
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java1
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy13
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy17
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java3
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java16
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java12
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddMethodQualifierTest.java104
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy220
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/intention/SwapIfStatementsTest.java34
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy49
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java194
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java1
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java2
-rw-r--r--java/java-tests/testSrc/com/intellij/codeInspection/SuspiciousCollectionMethodCalls14Test.java44
-rw-r--r--java/java-tests/testSrc/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenterTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/find/FindManagerTest.java22
-rw-r--r--java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy60
-rw-r--r--java/java-tests/testSrc/com/intellij/openapi/editor/impl/FoldingExceptionTest.java14
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java103
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java46
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java26
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java3
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy8
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy52
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java101
-rw-r--r--java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy26
-rw-r--r--java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java12
-rw-r--r--java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java4
-rw-r--r--java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java41
-rw-r--r--java/java-tests/testSrc/com/intellij/slicer/SliceBackwardTest.java4
-rw-r--r--java/jdkAnnotations/java/awt/annotations.xml15
-rw-r--r--java/mockJDK-1.7/jre/lib/rt.jarbin795414 -> 822033 bytes
-rw-r--r--java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy4
-rw-r--r--java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java4
-rw-r--r--java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java53
-rw-r--r--java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java15
-rw-r--r--java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java27
-rw-r--r--java/testFramework/src/com/intellij/testFramework/CompilerTester.java3
-rw-r--r--java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java12
-rw-r--r--jps/jps-builders/jps-builders.iml2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java40
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Difference.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/AsmUtil.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFileIndexer.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndexWriter.java3
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndicesBuilder.java14
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/MethodsUsageIndexer.java9
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java5
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java20
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java42
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java10
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java6
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuilderStatisticsMessage.java38
-rw-r--r--jps/model-api/src/org/jetbrains/jps/model/JpsProject.java4
-rw-r--r--jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java6
-rw-r--r--jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java2
-rw-r--r--jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java11
-rw-r--r--jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsUnknownRunConfigurationType.java37
-rw-r--r--jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java18
-rw-r--r--jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java8
-rw-r--r--lib/asm-all.jarbin384557 -> 384844 bytes
-rw-r--r--lib/freemarker.jarbin0 -> 879259 bytes
-rw-r--r--lib/guava-14.0.1.jarbin2189117 -> 0 bytes
-rw-r--r--lib/guava-17.0.jarbin0 -> 2243036 bytes
-rw-r--r--lib/netty-all-4.1.0.Alpha1.jarbin1769863 -> 0 bytes
-rw-r--r--lib/netty-all-4.1.0.Beta1.jarbin0 -> 1997099 bytes
-rw-r--r--lib/required_for_dist.txt5
-rw-r--r--lib/src/guava-14.0.1-sources.jarbin1170076 -> 0 bytes
-rw-r--r--lib/src/guava-17.0-sources.jarbin0 -> 1272791 bytes
-rw-r--r--lib/src/netty-all-4.1.0.Alpha1-sources.jarbin1490753 -> 0 bytes
-rw-r--r--lib/src/netty-all-4.1.0.Beta1-sources.jarbin0 -> 1646796 bytes
-rw-r--r--native/MacLauncher/Launcher.m24
-rw-r--r--native/fsNotifier/mac/fsnotifier.c14
-rw-r--r--platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java24
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java82
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/InspectionSuppressor.java31
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/LanguageInspectionSuppressors.java12
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java5
-rw-r--r--platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java3
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java9
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java20
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/SuppressionUtil.java14
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java42
-rwxr-xr-xplatform/bootstrap/src/com/intellij/idea/Main.java4
-rw-r--r--platform/core-api/src/com/intellij/concurrency/JobScheduler.java6
-rw-r--r--platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java9
-rw-r--r--platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java6
-rw-r--r--platform/core-api/src/com/intellij/openapi/application/CachedSingletonsRegistry.java8
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/Task.java3
-rw-r--r--platform/core-api/src/com/intellij/openapi/project/DumbModeTask.java6
-rw-r--r--platform/core-api/src/com/intellij/openapi/project/DumbService.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/ActionCallback.java10
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/AsyncResult.java9
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/CollectingAsyncResult.java62
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/CompositeModificationTracker.java31
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java66
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java15
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/InvalidVirtualFileAccessException.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java9
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/impl/ArchiveHandler.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileContentChangeEvent.java1
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCopyEvent.java14
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java9
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileDeleteEvent.java6
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileEvent.java5
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileMoveEvent.java12
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFilePropertyChangeEvent.java2
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java6
-rw-r--r--platform/core-api/src/com/intellij/patterns/ElementPatternBean.java (renamed from platform/lang-api/src/com/intellij/patterns/ElementPatternBean.java)2
-rw-r--r--platform/core-api/src/com/intellij/patterns/compiler/PatternCompiler.java (renamed from platform/lang-api/src/com/intellij/patterns/compiler/PatternCompiler.java)2
-rw-r--r--platform/core-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java (renamed from platform/lang-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java)2
-rw-r--r--platform/core-api/src/com/intellij/psi/FileResolveScopeProvider.java4
-rw-r--r--platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java1
-rw-r--r--platform/core-api/src/com/intellij/psi/MultiRangeReference.java4
-rw-r--r--platform/core-api/src/com/intellij/psi/PackagePrefixFileSystemItem.java5
-rw-r--r--platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java18
-rw-r--r--platform/core-api/src/com/intellij/psi/PsiReferenceProviderBean.java (renamed from platform/lang-api/src/com/intellij/psi/PsiReferenceProviderBean.java)2
-rw-r--r--platform/core-api/src/com/intellij/psi/PsiReferenceService.java3
-rw-r--r--platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java5
-rw-r--r--platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java27
-rw-r--r--platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java5
-rw-r--r--platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoriesScope.java (renamed from platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoryScope.java)27
-rw-r--r--platform/core-api/src/com/intellij/psi/search/SearchScope.java4
-rw-r--r--platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java21
-rw-r--r--platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java9
-rw-r--r--platform/core-api/src/com/intellij/util/FileIconKey.java7
-rw-r--r--platform/core-api/src/com/intellij/util/IconUtil.java11
-rw-r--r--platform/core-api/src/com/intellij/util/PlatformUtilsCore.java5
-rw-r--r--platform/core-api/src/com/intellij/util/QueryFactory.java5
-rw-r--r--platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java54
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java18
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java5
-rw-r--r--platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java33
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockDumbService.java7
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockFileDocumentManagerImpl.java32
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockReferenceProvidersRegistry.java38
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java6
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java2
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java17
-rw-r--r--platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java (renamed from platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java)2
-rw-r--r--platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java (renamed from platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java)2
-rw-r--r--platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java362
-rw-r--r--platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java5
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java7
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java1
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java14
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/progress/util/TooManyUsagesStatus.java15
-rw-r--r--platform/core-impl/src/com/intellij/openapi/vfs/impl/CoreVirtualFilePointerManager.java7
-rw-r--r--platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java3
-rw-r--r--platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java6
-rw-r--r--platform/core-impl/src/com/intellij/psi/PsiAnchor.java13
-rw-r--r--platform/core-impl/src/com/intellij/psi/PsiReferenceServiceImpl.java3
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java11
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java20
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java5
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiFileFactoryImpl.java3
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java28
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java)6
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java)2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java)2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java)2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java17
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java)10
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java)2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java7
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/RecursiveTreeElementWalkingVisitor.java4
-rw-r--r--platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java3
-rw-r--r--platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java51
-rw-r--r--platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java19
-rw-r--r--platform/core-impl/src/com/intellij/psi/text/BlockSupport.java4
-rw-r--r--platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java30
-rw-r--r--platform/duplicates-analysis/duplicates-analysis.iml19
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/AbstractMatchingVisitor.java119
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DefaultDuplocatorState.java65
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DupInfo.java27
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DupLocatorBundle.java32
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfile.java104
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfileCache.java76
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocateVisitor.java37
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorSettings.java64
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorState.java12
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/ExternalizableDuplocatorState.java14
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java90
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/NodeSpecificHasher.java57
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/PsiElementRole.java5
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/TreeComparator.java45
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/TreeHasher.java27
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/_DupInfo.java25
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptor.java18
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorBuilder.java111
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorProvider.java42
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/MultiChildDescriptor.java35
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/SingleChildDescriptor.java38
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java217
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java134
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/index/TracingData.java103
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/ArrayBackedNodeIterator.java43
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/CountingNodeIterator.java44
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/FilteringNodeIterator.java61
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/NodeIterator.java30
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/SiblingNodeIterator.java38
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/AbstractTreeHasher.java209
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesMatchingVisitor.java228
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesProfileBase.java55
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java383
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/FragmentsCollector.java11
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/GroupNodeDescription.java34
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/NodeSpecificHasherBase.java145
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashResult.java30
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHasherBase.java378
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashingUtils.java80
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreePsiFragment.java41
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/treeView/NodeMatcher.java14
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/util/DuplocatorUtil.java317
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/util/NodeFilter.java10
-rw-r--r--platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java253
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacade.java3
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacadeImpl.java7
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java2
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/ui/RootAction.java3
-rw-r--r--platform/dvcs/testFramework/com/intellij/dvcs/test/DvcsTestPlatformFacade.java147
-rw-r--r--platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java10
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java12
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java2
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsUtil.java67
-rw-r--r--platform/editor-ui-ex/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java6
-rw-r--r--platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java3
-rw-r--r--platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java5
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/execution/ExternalSystemExecutionConsoleManager.java3
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java17
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ContentRootData.java2
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java2
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java8
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallback.java26
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallbackAdapter.java28
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java18
-rw-r--r--platform/external-system-impl/external-system-impl.iml1
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java22
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/DefaultExternalSystemExecutionConsoleManager.java6
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java8
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java5
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java2
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java135
-rw-r--r--platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java446
-rw-r--r--platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java443
-rw-r--r--platform/funcTests/config/disabled_plugins.txt3
-rwxr-xr-xplatform/icons/src/css/pseudo-class.pngbin0 -> 262 bytes
-rw-r--r--platform/icons/src/css/pseudo-class@2x.pngbin0 -> 634 bytes
-rw-r--r--[-rwxr-xr-x]platform/icons/src/css/pseudo-element.pngbin262 -> 276 bytes
-rw-r--r--platform/icons/src/css/pseudo-element@2x.pngbin634 -> 4544 bytes
-rw-r--r--platform/icons/src/nodes/desktop.pngbin0 -> 158 bytes
-rw-r--r--platform/icons/src/nodes/desktop@2x.pngbin0 -> 1130 bytes
-rw-r--r--platform/icons/src/nodes/pluginLogo.pngbin0 -> 945 bytes
-rw-r--r--platform/icons/src/nodes/ppWebLogo.pngbin0 -> 1760 bytes
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java4
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java3
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/PsiSearchRequest.java6
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/TextOccurenceProcessor.java5
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java8
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/IndexPatternSearch.java10
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java5
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java14
-rw-r--r--platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java2
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryScope.java4
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleScopeProviderImpl.java (renamed from platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java)28
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java7
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java79
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsTestScope.java40
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java4
-rw-r--r--platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java2
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java21
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java12
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java20
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java9
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java9
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/lookup/WeighingContext.java31
-rw-r--r--platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java115
-rw-r--r--platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java144
-rw-r--r--platform/lang-api/src/com/intellij/facet/ProjectFacetManager.java3
-rw-r--r--platform/lang-api/src/com/intellij/find/FindManager.java4
-rw-r--r--platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java36
-rw-r--r--platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java20
-rw-r--r--platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java3
-rw-r--r--platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java2
-rw-r--r--platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java25
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java2
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java8
-rw-r--r--platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java25
-rw-r--r--platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java20
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java6
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java93
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java13
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form10
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java4
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form35
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.java8
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java1
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java13
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java89
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java8
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java21
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java95
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java9
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java1
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java23
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java29
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java10
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java10
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java20
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java1
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/EncodingReference.java103
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java27
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java225
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java7
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java135
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectionQuotingTypedHandler.java149
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java323
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java27
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java14
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/ClassifierFactory.java21
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java10
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java39
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupOffsets.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java87
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java18
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java28
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoImplementationHandler.java11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java21
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java32
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java14
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSegments.java12
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java7
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java17
-rw-r--r--platform/lang-impl/src/com/intellij/execution/TerminateRemoteProcessDialog.java4
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java8
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java258
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java4
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java2
-rw-r--r--platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java5
-rw-r--r--platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java10
-rw-r--r--platform/lang-impl/src/com/intellij/facet/impl/FacetFinderImpl.java30
-rw-r--r--platform/lang-impl/src/com/intellij/facet/impl/FacetModificationTrackingServiceImpl.java32
-rw-r--r--platform/lang-impl/src/com/intellij/facet/impl/ProjectFacetManagerImpl.java17
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindProgressIndicator.java5
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindUtil.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java196
-rw-r--r--platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java105
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java3
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java6
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java11
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java79
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java27
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java5
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java15
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java4
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java12
-rw-r--r--platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java6
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/CloneElementAction.java53
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java98
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/GotoActionAction.java6
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java (renamed from platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java)2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/PowerSaveModeNotifier.java67
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java86
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java841
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/TogglePowerSaveAction.java4
-rw-r--r--platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java8
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java10
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java13
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java242
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadIconProvider.java38
-rw-r--r--platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java30
-rw-r--r--platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java16
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java3
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java16
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java14
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/EdtSortingModel.java26
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java109
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java14
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java3
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java10
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java6
-rw-r--r--platform/lang-impl/src/com/intellij/mock/MockFileManager.java16
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java4
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java13
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/HtmlTransferableData.java14
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java1
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java49
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdater.java40
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesCombobox.java75
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java28
-rw-r--r--platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java28
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooser.java2
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java116
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java49
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java15
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java12
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java11
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubProcessingHelper.java2
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java4
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java29
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java7
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/inline/AbstractInlineLocalDialog.java58
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java8
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java13
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java3
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java4
-rw-r--r--platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java8
-rw-r--r--platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java8
-rw-r--r--platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java3
-rw-r--r--platform/lang-impl/src/com/intellij/ui/debugger/extensions/PlaybackDebugger.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ui/tabs/FileColorsConfigurablePanel.java6
-rw-r--r--platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java3
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java22
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java13
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java40
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java34
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileId2ValueMapping.java60
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java2
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java14
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java3
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java12
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java20
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java201
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java13
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java117
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/containers/IdBitSet.java5
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/containers/IdSet.java5
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/containers/SortedFileIdSetIterator.java116
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/containers/SortedIdSet.java5
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atNextLine-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atNextLine.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atSameLine-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atSameLine.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/emptyLines-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/emptyLines.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/inText-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/inText.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/lastLine-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/lastLine.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/multilineSpace-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/multilineSpace.java5
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/plainText-after.txt2
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/plainText.txt2
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/selection-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/selection.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/targetLineStart-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/targetLineStart.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/textStart-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/textStart.java4
-rw-r--r--platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerTest.java49
-rw-r--r--platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerVirtualSpaceTest.java118
-rw-r--r--platform/platform-api/src/com/intellij/ide/util/treeView/NodeRenderer.java16
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java19
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java29
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java19
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java34
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java112
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java6
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java13
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java15
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java10
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java59
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java6
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java10
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java45
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Messages.java1
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/util/DefaultModificationTracker.java29
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java13
-rw-r--r--platform/platform-api/src/com/intellij/ui/EditorNotificationPanel.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/EditorNotifications.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java51
-rw-r--r--platform/platform-api/src/com/intellij/ui/SeparatorWithText.java13
-rw-r--r--platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java14
-rw-r--r--platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java203
-rw-r--r--platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java2
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java40
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java3
-rw-r--r--platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java1
-rw-r--r--platform/platform-api/src/com/intellij/util/Alarm.java2
-rw-r--r--platform/platform-api/src/com/intellij/util/PlatformUtils.java13
-rw-r--r--platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java19
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/FormBuilder.java1
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java16
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/StatusText.java25
-rw-r--r--platform/platform-impl/src/com/intellij/execution/process/ConsoleHistoryModel.java31
-rw-r--r--platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java27
-rw-r--r--platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java31
-rw-r--r--platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java28
-rw-r--r--platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java22
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java60
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java13
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/RefCardAction.java27
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java1
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java3
-rw-r--r--platform/platform-impl/src/com/intellij/ide/impl/ProjectNewWindowDoNotAskOption.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/impl/TypeSafeDataProviderAdapter.java7
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java11
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java125
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java19
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java167
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java46
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java47
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java153
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java95
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextBorder.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/IntelliJCheckBoxUI.java46
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/TipDialog.java8
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java7
-rw-r--r--platform/platform-impl/src/com/intellij/idea/IdeaApplication.java16
-rw-r--r--platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java21
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/AbbreviationManagerImpl.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java332
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java324
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java61
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java11
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java101
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java104
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java32
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java18
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java42
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapHelper.java14
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java33
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileChooser/actions/GotoDesktopDirAction.java52
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java10
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java11
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/impl/BackgroundableProcessIndicator.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java26
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java32
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java383
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/AbstractDialog.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/HeadlessDialog.java42
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java28
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java54
-rwxr-xr-xplatform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java171
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java132
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java154
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SubList.java79
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/UserDataInterner.java43
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java293
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java178
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java691
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java23
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java124
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java45
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java38
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java80
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/AbstractActionWithPanel.java27
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/CardActionsPanel.java40
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java4
-rw-r--r--platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java5
-rw-r--r--platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java94
-rw-r--r--platform/platform-impl/src/com/intellij/platform/FilesystemToolwindowOpener.java44
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java15
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteCredentialException.java25
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java6
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkConnectionAcceptor.java8
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java3
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java2
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java12
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsProducer.java (renamed from platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java)4
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java37
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java28
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AppUIUtil.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ui/ColorPicker.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java63
-rw-r--r--platform/platform-impl/src/com/intellij/ui/HideableDecorator.java13
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetController.java8
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java19
-rw-r--r--platform/platform-impl/src/com/intellij/util/SingleAlarm.java3
-rw-r--r--platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java2
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java4
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/FileResponses.java11
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java4
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/Responses.java4
-rw-r--r--platform/platform-resources-en/src/messages/ActionsBundle.properties10
-rw-r--r--platform/platform-resources-en/src/messages/ApplicationBundle.properties3
-rw-r--r--platform/platform-resources-en/src/messages/ExecutionBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/FindBundle.properties1
-rw-r--r--platform/platform-resources-en/src/messages/IdeBundle.properties8
-rw-r--r--platform/platform-resources-en/src/messages/UsageView.properties1
-rw-r--r--platform/platform-resources-en/src/messages/VcsBundle.properties6
-rw-r--r--platform/platform-resources-en/src/messages/XmlBundle.properties2
-rw-r--r--platform/platform-resources-en/src/misc/registry.properties11
-rw-r--r--platform/platform-resources/src/META-INF/LangExtensionPoints.xml6
-rw-r--r--platform/platform-resources/src/META-INF/LangExtensions.xml7
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml2
-rw-r--r--platform/platform-resources/src/META-INF/PlatformPlugin.xml3
-rw-r--r--platform/platform-resources/src/META-INF/XmlActions.xml4
-rw-r--r--platform/platform-resources/src/META-INF/XmlPlugin.xml1
-rw-r--r--platform/platform-resources/src/META-INF/mime.types1440
-rw-r--r--platform/platform-resources/src/brokenPlugins.txt9
-rw-r--r--platform/platform-resources/src/componentSets/Platform.xml4
-rw-r--r--platform/platform-resources/src/idea/Keymap_Default.xml7
-rw-r--r--platform/platform-resources/src/idea/Keymap_Netbeans.xml1
-rw-r--r--platform/platform-resources/src/idea/Keymap_VisualStudio.xml1
-rw-r--r--platform/platform-resources/src/idea/LangActions.xml5
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml4
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorDeleteLine-after.txt5
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt5
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt2
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt2
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt2
-rw-r--r--platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt2
-rw-r--r--platform/platform-tests/testData/editor/richcopy/BlockSelection.html4
-rw-r--r--platform/platform-tests/testData/editor/richcopy/NormalSelection.html9
-rw-r--r--platform/platform-tests/testSrc/com/intellij/application/options/codeInsight/editor/quotes/SelectionQuotingTypedHandlerTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java80
-rw-r--r--platform/platform-tests/testSrc/com/intellij/codeInsight/folding/impl/CompositeFoldingBuilderTest.java91
-rw-r--r--platform/platform-tests/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java8
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java15
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java33
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/richcopy/SyntaxInfoConstructionTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java24
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java92
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java8
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/JarFileSystemTest.java14
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java5
-rw-r--r--platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy15
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java5
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java5
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java22
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java12
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java18
-rw-r--r--platform/projectModel-impl/src/messages/ProjectBundle.properties2
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgent.java17
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentApplication.java24
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentBase.java30
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentDeployment.java5
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentWithDeployment.java2
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitAgent.java5
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitApplication.java2
-rw-r--r--platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudRemoteApplication.java (renamed from platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudApplication.java)2
-rw-r--r--platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java12
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java69
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java19
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java78
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java24
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java3
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntime.java31
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeBase.java55
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeImpl.java35
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudConnectionTask.java2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudDeploymentRuntime.java115
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudGitApplicationRuntime.java124
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudMultiSourceServerRuntimeInstance.java154
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRuntimeTask.java2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java98
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/HasUrl.java25
-rwxr-xr-xplatform/script-debugger/backend/src/org/jetbrains/debugger/Script.java2
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java9
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java2
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifierUtil.java53
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java9
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/values/PrimitiveValue.java3
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/rpc/CommandCallbackWithResponseBase.java2
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java5
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/rpc/MessageHandler.java22
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/rpc/NestedCommandCallbackWithResponse.java5
-rw-r--r--platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java6
-rw-r--r--platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.java3
-rw-r--r--platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java24
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonUtil.java52
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java5
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.java23
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/StringWriter.java81
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java20
-rw-r--r--platform/smRunner/testSrc/com/intellij/internal/statistic/beans/ConvertUsagesUtilTest.java12
-rw-r--r--platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java10
-rw-r--r--platform/testFramework/src/com/intellij/TestAll.java287
-rw-r--r--platform/testFramework/src/com/intellij/TestCaseLoader.java60
-rw-r--r--platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java14
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java23
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/FileEditorManagerTestCase.java8
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/LeakHunter.java3
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java28
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java3
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java14
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java11
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java37
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java107
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java28
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java82
-rw-r--r--platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java17
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java10
-rw-r--r--platform/usageView/src/com/intellij/usages/UsageInfoSearcherAdapter.java2
-rw-r--r--platform/usageView/src/com/intellij/usages/UsageView.java4
-rw-r--r--platform/usageView/src/com/intellij/usages/UsageViewManager.java4
-rw-r--r--platform/usageView/src/com/intellij/usages/UsageViewPresentation.java3
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/NullUsage.java55
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java478
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/UsageAdapter.java69
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java476
-rw-r--r--platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java5
-rw-r--r--platform/util/src/com/intellij/Patches.java8
-rw-r--r--platform/util/src/com/intellij/execution/process/UnixProcessManager.java13
-rw-r--r--platform/util/src/com/intellij/execution/process/WinProcessManager.java9
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java4
-rw-r--r--platform/util/src/com/intellij/ide/ClassUtilCore.java11
-rw-r--r--platform/util/src/com/intellij/openapi/util/SystemInfo.java1
-rw-r--r--platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java41
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java38
-rw-r--r--platform/util/src/com/intellij/openapi/util/text/StringUtil.java21
-rw-r--r--platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java29
-rw-r--r--platform/util/src/com/intellij/psi/codeStyle/NameUtil.java33
-rw-r--r--platform/util/src/com/intellij/ui/EngravedLabel.java19
-rw-r--r--platform/util/src/com/intellij/ui/EngravedTextGraphics.java4
-rw-r--r--platform/util/src/com/intellij/ui/mac/foundation/Foundation.java2
-rw-r--r--platform/util/src/com/intellij/util/PathMappingSettings.java20
-rw-r--r--platform/util/src/com/intellij/util/ReflectionUtil.java84
-rw-r--r--platform/util/src/com/intellij/util/Restarter.java2
-rw-r--r--platform/util/src/com/intellij/util/WaitFor.java4
-rw-r--r--platform/util/src/com/intellij/util/cls/BytePointer.java1
-rw-r--r--platform/util/src/com/intellij/util/cls/ClsUtil.java56
-rw-r--r--platform/util/src/com/intellij/util/cls/package.html20
-rw-r--r--platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java45
-rw-r--r--platform/util/src/com/intellij/util/containers/ConcurrentMultiMap.java1
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java4
-rw-r--r--platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java4
-rw-r--r--platform/util/src/com/intellij/util/containers/MultiMap.java23
-rw-r--r--platform/util/src/com/intellij/util/containers/WeakFactoryMap.java10
-rw-r--r--platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java65
-rw-r--r--platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java13
-rw-r--r--platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java2
-rw-r--r--platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java2
-rw-r--r--platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java50
-rw-r--r--platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java23
-rw-r--r--platform/util/src/com/intellij/util/lang/JarLoader.java11
-rw-r--r--platform/util/src/com/intellij/util/lang/JarMemoryLoader.java2
-rw-r--r--platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java17
-rw-r--r--platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java15
-rw-r--r--platform/util/src/com/intellij/util/ui/UIUtil.java64
-rw-r--r--platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java43
-rw-r--r--platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java109
-rw-r--r--platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java28
-rw-r--r--platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java4
-rw-r--r--platform/util/testSrc/com/intellij/util/pico/IdeaPicoContainerTest.java42
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java5
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/annotate/ShowAllAffectedGenericAction.java5
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutorBase.java23
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/versionBrowser/ChangeBrowserSettings.java86
-rw-r--r--platform/vcs-api/src/com/intellij/util/ui/ConfirmationDialog.java3
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java3
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java15
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java9
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java8
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java48
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java18
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java52
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java20
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java19
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java305
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java22
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java7
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java32
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java50
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java21
-rw-r--r--platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java7
-rw-r--r--platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java23
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsUserRegistry.java30
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java3
-rw-r--r--platform/vcs-log/impl/src/META-INF/vcs-log.xml1
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java7
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java2
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java10
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistry.java57
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java146
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java5
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java10
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java33
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java2
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java5
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManagerListener.java24
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XSuspendContext.java11
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/presentation/XValuePresentation.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java115
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/FocusOnBreakpointAction.java (renamed from java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java)2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ToggleBreakpointEnabledAction.java78
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java14
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionState.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java15
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XDebuggerTreeCreator.java27
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java28
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/ThreadComboBoxRenderer.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java76
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java12
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java10
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java7
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java7
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java10
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresentationUtil.java24
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java10
-rw-r--r--platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java10
-rw-r--r--platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java17
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml4
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties4
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspection.java67
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java3
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToCatchBlockParameterInspection.java57
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspection.java58
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToMethodParameterInspection.java135
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/BaseAssignmentToParameterInspection.java141
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java8
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ScopeUtils.java5
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java18
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java38
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java65
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoCommentInspection.java48
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoUtil.java42
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java14
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java14
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java4
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java6
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java16
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java2
-rw-r--r--plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToLambdaParameter.html9
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.after.java8
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.java9
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.after.java5
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.java5
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.after.java17
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.java16
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java6
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_lambda_parameter/AssignmentToLambdaParameter.java15
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/AssigmentToMethodParameterMissesCompoundAssign.java28
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/IgnoreTransformationOfParameter.java43
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/expected.xml9
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/A.java10
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/expected.xml9
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java12
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/expected.xml37
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/TypeParameterExtendsFinalClass.java10
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/expected.xml23
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/SimplifiableIfStatement.java20
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/expected.xml86
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java9
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java3
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspectionTest.java36
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToMethodParameterInspectionTest.java32
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspectionTest.java15
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/TooBroadScopeInspectionTest.java18
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java23
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/dataflow/TooBroadScopeInspectionFixTest.java3
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/TypeParameterExtendsFinalClassFixTest.java36
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/j2me/SimplifiableIfStatementFixTest.java36
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspectionTest.java24
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/j2me/SimplifiableIfStatementInspectionTest.java15
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldInspectionTest.java4
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassInspectionTest.java4
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java11
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java7
-rw-r--r--plugins/IntelliLang/IntelliLang-java.iml2
-rw-r--r--plugins/IntelliLang/IntelliLang-javaee.iml20
-rw-r--r--plugins/IntelliLang/IntelliLang-xml.iml2
-rw-r--r--plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java6
-rw-r--r--plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/InstrumentationAdapter.java12
-rw-r--r--plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java12
-rw-r--r--plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternValidatorBuilder.java4
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/LanguageReferenceProvider.java2
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/Instrumenter.java8
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/InstrumentationAdapter.java12
-rw-r--r--plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/PatternValidationInstrumenter.java8
-rw-r--r--plugins/IntelliLang/javaee-support/org/intellij/plugins/intelliLang/inject/config/JspSupportProxyImpl.java38
-rw-r--r--plugins/IntelliLang/src/META-INF/intellilang-javaee-support.xml9
-rw-r--r--plugins/IntelliLang/src/META-INF/intellilang-js-support.xml15
-rw-r--r--plugins/IntelliLang/src/META-INF/plugin.xml2
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java11
-rw-r--r--plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/CharToStringPredicate.java8
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/StringToCharPredicate.java14
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java6
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java4
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ConvertToNestedIfIntention.java14
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntention.java3
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside.java7
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside_after.java10
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside.java7
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside_after.java8
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis.java19
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis_after.java20
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow.java7
-rw-r--r--plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow_after.java10
-rw-r--r--plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ConvertToNestedIfIntentionTest.java3
-rw-r--r--plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java4
-rw-r--r--plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java5
-rw-r--r--plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java13
-rw-r--r--plugins/copyright/src/META-INF/java.xml2
-rw-r--r--plugins/copyright/src/META-INF/plugin.xml4
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProvider.java27
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProviders.java26
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/pattern/FileInfo.java19
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/pattern/JavaCopyrightVariablesProvider.java54
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java21
-rw-r--r--plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProjectConfigurable.java4
-rw-r--r--plugins/coverage-common/coverage-common.iml35
-rw-r--r--plugins/coverage-common/lib/coverage-agent.jarbin0 -> 33257 bytes
-rw-r--r--plugins/coverage-common/lib/coverage-src.zipbin0 -> 45363 bytes
-rw-r--r--plugins/coverage-common/lib/coverage-util.jarbin0 -> 21179 bytes
-rw-r--r--plugins/coverage-common/lib/instrumenter.jarbin0 -> 57181 bytes
-rw-r--r--plugins/coverage-common/src/META-INF/coverage-common-plugin.xml26
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/AbstractCoverageProvejctViewNodeDecorator.java26
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/BaseCoverageAnnotator.java63
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/BaseCoverageSuite.java277
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageAnnotator.java35
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageDataManager.java150
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageDataManagerImpl.java711
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageEngine.java360
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageExecutor.java69
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageFileProvider.java32
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageHelper.java51
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageLineMarkerRenderer.java429
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageOptions.java22
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.form80
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.java179
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsProvider.java55
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageProjectViewDirectoryNodeDecorator.java73
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageRunner.java44
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageRunnerData.java18
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageSuite.java46
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageSuiteListener.java26
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/CoverageSuitesBundle.java197
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/DefaultCoverageFileProvider.java56
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/SimpleCoverageAnnotator.java434
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/SrcFileAnnotator.java603
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java401
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/GenerateCoverageReportAction.java52
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/HideCoverageInfoAction.java34
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java184
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/SwitchCoverageSuiteAction.java25
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageAction.java167
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageActionProvider.java15
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageListNode.java159
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageListRootNode.java45
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageTableModel.java105
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageView.java345
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewBuilder.java143
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewDescriptor.java28
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewExtension.java82
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewManager.java128
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewSuiteListener.java42
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewTreeStructure.java80
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/DirectoryCoverageViewExtension.java113
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/ElementColumnInfo.java27
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/PercentageCoverageColumnInfo.java75
-rw-r--r--plugins/coverage-common/src/com/intellij/coverage/view/SelectInCoverageView.java59
-rw-r--r--plugins/coverage-common/src/com/intellij/execution/configurations/coverage/CoverageEnabledConfiguration.java246
-rw-r--r--plugins/coverage/coverage.iml36
-rw-r--r--plugins/coverage/covergae_rt/coverage_rt.iml24
-rw-r--r--plugins/coverage/covergae_rt/src/listeners/CoverageListener.java41
-rw-r--r--plugins/coverage/covergae_rt/src/listeners/IDEAJUnitCoverageListener.java21
-rw-r--r--plugins/coverage/covergae_rt/src/listeners/IDEATestNGCoverageListener.java55
-rw-r--r--plugins/coverage/lib/asm-all.jarbin0 -> 384844 bytes
-rw-r--r--plugins/coverage/lib/coverage-report-idea.jarbin0 -> 6813 bytes
-rw-r--r--plugins/coverage/lib/coverage-report.jarbin0 -> 86179 bytes
-rw-r--r--plugins/coverage/lib/finder.jarbin0 -> 54669 bytes
-rw-r--r--plugins/coverage/lib/jacoco_src.zipbin0 -> 2127576 bytes
-rw-r--r--plugins/coverage/lib/jacocoagent.jarbin0 -> 286396 bytes
-rw-r--r--plugins/coverage/lib/jacocoant.jarbin0 -> 692731 bytes
-rw-r--r--plugins/coverage/lib/trove4j.jarbin0 -> 390018 bytes
-rw-r--r--plugins/coverage/src/META-INF/junit-integration.xml5
-rw-r--r--plugins/coverage/src/META-INF/plugin.xml52
-rw-r--r--plugins/coverage/src/META-INF/testng-integration.xml5
-rw-r--r--plugins/coverage/src/com/intellij/coverage/CoberturaCoverageRunner.java63
-rw-r--r--plugins/coverage/src/com/intellij/coverage/CoveragePluginDataManagerImpl.java12
-rw-r--r--plugins/coverage/src/com/intellij/coverage/CoverageProjectViewClassNodeDecorator.java99
-rw-r--r--plugins/coverage/src/com/intellij/coverage/DefaultJavaCoverageRunner.java51
-rw-r--r--plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java76
-rw-r--r--plugins/coverage/src/com/intellij/coverage/IdeaClassFinder.java78
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java152
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java283
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java670
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JavaCoverageEngineExtension.java35
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java86
-rw-r--r--plugins/coverage/src/com/intellij/coverage/JavaCoverageSuite.java244
-rw-r--r--plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java454
-rw-r--r--plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java48
-rw-r--r--plugins/coverage/src/com/intellij/coverage/info/CoberturaLoaderUtil.java130
-rw-r--r--plugins/coverage/src/com/intellij/coverage/info/EmmaLoaderUtil.java13
-rw-r--r--plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java319
-rw-r--r--plugins/coverage/src/com/intellij/execution/configurations/coverage/CoverageConfigurable.java327
-rw-r--r--plugins/coverage/src/com/intellij/execution/configurations/coverage/JavaCoverageEnabledConfiguration.java224
-rw-r--r--plugins/coverage/src/com/intellij/execution/coverage/CoverageJavaRunConfigurationExtension.java275
-rw-r--r--plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties2
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsFilePath.java3
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsEntriesManager.java13
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java16
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/checkout/CvsCheckoutProvider.java4
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/CvsRootConfiguration.java41
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java7
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java10
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java11
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java7
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java10
-rw-r--r--plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java87
-rw-r--r--plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java7
-rw-r--r--plugins/devkit/devkit.iml2
-rw-r--r--plugins/devkit/src/dom/impl/I18nReferenceContributor.java4
-rw-r--r--plugins/devkit/src/inspections/internal/FileEqualsUsageInspection.java2
-rw-r--r--plugins/devkit/src/inspections/internal/UndesirableClassUsageInspection.java24
-rw-r--r--plugins/devkit/src/inspections/quickfix/PluginDescriptorChooser.java2
-rw-r--r--plugins/devkit/src/module/PluginModuleBuilder.java36
-rw-r--r--plugins/devkit/src/projectRoots/IdeaJdk.java56
-rw-r--r--plugins/devkit/src/references/IconsReferencesContributor.java2
-rw-r--r--plugins/devkit/src/run/PluginConfigurationType.java2
-rw-r--r--plugins/devkit/src/run/PluginRunConfiguration.java3
-rw-r--r--plugins/devkit/src/run/PluginRunConfigurationEditor.java4
-rw-r--r--plugins/devkit/src/testAssistant/TestDataGuessByExistingFilesUtil.java17
-rw-r--r--plugins/devkit/src/testAssistant/TestDataLineMarkerProvider.java43
-rw-r--r--plugins/devkit/src/testAssistant/TestDataReferenceContributor.java2
-rw-r--r--plugins/devkit/testSources/PluginProjectWizardTest.java13
-rw-r--r--plugins/devkit/testSources/inspections/internal/FileEqualsUsageInspectionTest.java69
-rw-r--r--plugins/devkit/testSources/inspections/internal/UndesirableClassUsageInspectionTest.java55
-rw-r--r--plugins/devkit/testSources/inspections/internal/UseVirtualFileEqualsInspectionTest.java58
-rw-r--r--plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileType.java3
-rw-r--r--plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileTypeFactory.java6
-rw-r--r--plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImportWizardTest.java6
-rw-r--r--plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java64
-rw-r--r--plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java11
-rw-r--r--plugins/git4idea/git4idea.iml11
-rw-r--r--plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r.jarbin1619515 -> 0 bytes
-rw-r--r--plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r_source.zipbin1660774 -> 0 bytes
-rw-r--r--plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java152
-rw-r--r--plugins/git4idea/src/META-INF/plugin.xml2
-rw-r--r--plugins/git4idea/src/git4idea/GitUtil.java76
-rw-r--r--plugins/git4idea/src/git4idea/GitVcs.java5
-rw-r--r--plugins/git4idea/src/git4idea/actions/GitMerge.java62
-rw-r--r--plugins/git4idea/src/git4idea/actions/GitMergeAction.java141
-rw-r--r--plugins/git4idea/src/git4idea/actions/GitPull.java90
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitBranchOperation.java51
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java16
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java88
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java6
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitDeleteRemoteBranchOperation.java13
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitMergeOperation.java5
-rw-r--r--plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java45
-rw-r--r--plugins/git4idea/src/git4idea/changes/GitChangeUtils.java32
-rw-r--r--plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java10
-rw-r--r--plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java116
-rw-r--r--plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java15
-rw-r--r--plugins/git4idea/src/git4idea/checkin/GitCommitAuthorCorrector.java55
-rw-r--r--plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java18
-rw-r--r--plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java3
-rw-r--r--plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java4
-rw-r--r--plugins/git4idea/src/git4idea/commands/Git.java4
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java109
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java27
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitImpl.java6
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java5
-rw-r--r--plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java525
-rw-r--r--plugins/git4idea/src/git4idea/jgit/GitHttpCredentialsProvider.java193
-rw-r--r--plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java507
-rw-r--r--plugins/git4idea/src/git4idea/merge/GitMergeDialog.java30
-rw-r--r--plugins/git4idea/src/git4idea/push/GitPusher.java39
-rw-r--r--plugins/git4idea/src/git4idea/rebase/GitRebaser.java8
-rw-r--r--plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java (renamed from plugins/git4idea/src/git4idea/jgit/GitHttpAuthDataProvider.java)4
-rw-r--r--plugins/git4idea/src/git4idea/repo/GitConfig.java2
-rw-r--r--plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java3
-rw-r--r--plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java2
-rw-r--r--plugins/git4idea/src/git4idea/ui/ChangesBrowserWithRollback.java67
-rw-r--r--plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java25
-rw-r--r--plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java27
-rw-r--r--plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesDialog.java45
-rw-r--r--plugins/git4idea/src/git4idea/update/GitFetcher.java28
-rw-r--r--plugins/git4idea/src/git4idea/update/GitMergeUpdater.java17
-rw-r--r--plugins/git4idea/src/git4idea/util/GitSimplePathsBrowser.java71
-rw-r--r--plugins/git4idea/src/git4idea/util/LocalChangesWouldBeOverwrittenHelper.java85
-rw-r--r--plugins/git4idea/src/git4idea/util/UntrackedFilesNotifier.java33
-rw-r--r--plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java11
-rw-r--r--plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy44
-rw-r--r--plugins/git4idea/tests/git4idea/checkin/GitCommitAuthorCorrectorTest.java56
-rw-r--r--plugins/git4idea/tests/git4idea/test/GitPlatformTest.java4
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java46
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java2
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java42
-rw-r--r--plugins/gradle/gradle.iml39
-rw-r--r--plugins/gradle/lib/gradle-2.0-src.zip (renamed from plugins/gradle/lib/gradle-1.12-src.zip)bin11742627 -> 11831042 bytes
-rw-r--r--plugins/gradle/lib/gradle-base-services-2.0.jar (renamed from plugins/gradle/lib/gradle-base-services-1.12.jar)bin166122 -> 173144 bytes
-rw-r--r--plugins/gradle/lib/gradle-base-services-groovy-2.0.jarbin0 -> 4910 bytes
-rw-r--r--plugins/gradle/lib/gradle-core-2.0.jar (renamed from plugins/gradle/lib/gradle-core-1.12.jar)bin1836426 -> 1840009 bytes
-rw-r--r--plugins/gradle/lib/gradle-messaging-2.0.jar (renamed from plugins/gradle/lib/gradle-messaging-1.12.jar)bin257836 -> 262131 bytes
-rw-r--r--plugins/gradle/lib/gradle-native-1.12.jarbin44738 -> 0 bytes
-rw-r--r--plugins/gradle/lib/gradle-native-2.0.jarbin0 -> 36418 bytes
-rw-r--r--plugins/gradle/lib/gradle-resources-2.0.jarbin0 -> 31389 bytes
-rw-r--r--plugins/gradle/lib/gradle-tooling-api-2.0.jar (renamed from plugins/gradle/lib/gradle-tooling-api-1.12.jar)bin203942 -> 192392 bytes
-rw-r--r--plugins/gradle/lib/gradle-wrapper-2.0.jar (renamed from plugins/gradle/lib/gradle-wrapper-1.12.jar)bin24041 -> 23994 bytes
-rw-r--r--plugins/gradle/lib/guava-jdk5-14.0.1.jarbin2003263 -> 0 bytes
-rw-r--r--plugins/gradle/lib/guava-jdk5-17.0.jarbin0 -> 2059438 bytes
-rw-r--r--plugins/gradle/lib/jna-posix-1.0.3.jarbin88886 -> 0 bytes
-rw-r--r--plugins/gradle/src/META-INF/gradle-javaee-plugin.xml9
-rw-r--r--plugins/gradle/src/META-INF/plugin.xml1
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java24
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java5
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleBuildClasspathResolveScopeEnlarger.java4
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java23
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/GradleTestsExecutionConsoleManager.java6
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/OpenGradleTestResultActionProvider.java16
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java6
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java2
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarDirectory.java58
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WebResource.java6
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java15
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java36
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java21
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectImportNotificationListener.java44
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java82
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java13
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java3
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java1
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java5
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java3
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java3
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java5
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java35
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleDependenciesImportingTest.java63
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java47
-rw-r--r--plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java173
-rw-r--r--plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml107
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-build-init-1.12.jarbin185571 -> 0 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.0.jarbin0 -> 173390 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-ide-1.12.jarbin900228 -> 0 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-ide-2.0.jarbin0 -> 817689 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-plugins-1.12.jarbin807264 -> 0 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.0.jarbin0 -> 760638 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-scala-1.12.jarbin125615 -> 0 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/lib/gradle-scala-2.0.jarbin0 -> 114257 bytes
-rw-r--r--plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java4
-rw-r--r--plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml122
-rw-r--r--plugins/gradle/tooling-extension-impl/lib/gradle-reporting-2.0.jar (renamed from plugins/gradle/tooling-extension-impl/lib/gradle-reporting-1.12.jar)bin34430 -> 32304 bytes
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java55
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.groovy159
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java140
-rw-r--r--plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ConfigurationDelegate.java318
-rw-r--r--plugins/gradle/tooling-extension-impl/testData/testDefaultWarModel/build.gradle39
-rw-r--r--plugins/gradle/tooling-extension-impl/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle2
-rw-r--r--plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/AbstractModelBuilderTest.java134
-rw-r--r--plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/WebConfigurationBuilderImplTest.java14
-rw-r--r--plugins/groovy/groovy-psi/resources/inspectionDescriptions/ClashingTraitMethods.html9
-rw-r--r--plugins/groovy/groovy-psi/src/META-INF/GroovyPlugin.xml1682
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java3
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/intentions/QuickfixUtil.java4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInsight/GroovyClsCustomNavigationPolicy.java8
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovySuppressableInspectionTool.java14
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrMethodCallInfo.java4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOverlyComplexArithmeticExpressionInspectionBase.java4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessChecker.java12
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java2
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java40
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java77
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java240
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java380
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java84
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java45
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java74
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java3
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStaticChecker.java (renamed from plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/StaticChecker.java)53
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ClosureMissingMethodContributor.java17
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java30
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyMethodArgumentReferenceContributor.java2
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java8
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java4
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/providers/GroovyReferenceContributor.java3
-rw-r--r--plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java4
-rw-r--r--plugins/groovy/jetgroovy.iml1
-rw-r--r--plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java5
-rw-r--r--plugins/groovy/src/META-INF/groovy-byte-code-viewer.xml5
-rw-r--r--plugins/groovy/src/META-INF/groovy-copyright.xml (renamed from plugins/groovy/groovy-psi/src/META-INF/groovy-copyright.xml)0
-rw-r--r--plugins/groovy/src/META-INF/intellilang-groovy-support.xml (renamed from plugins/groovy/groovy-psi/src/META-INF/intellilang-groovy-support.xml)0
-rw-r--r--plugins/groovy/src/META-INF/plugin.xml1687
-rw-r--r--plugins/groovy/src/META-INF/structuralsearch.xml6
-rw-r--r--plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrLanguageReferenceProvider.java2
-rw-r--r--plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/navigation/actions/GroovyGotoSuperHandler.java8
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionSuppressor.java34
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingTraitMethodsInspection.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/spellchecker/GroovySpellcheckingStrategy.java16
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java6
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellCompletionContributor.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java14
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java14
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/CompleteReferenceExpression.java16
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCliCommandExecutor.java46
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCommandExecutor.java69
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.form2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.java18
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTarget.java8
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.form2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.java16
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/util/ModuleCellRenderer.java39
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameAliasImportedFieldProcessor.java40
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameGrFieldProcessor.java107
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java5
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.form2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.java44
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunner.java5
-rw-r--r--plugins/groovy/structuralsearch-groovy/src/com/intellij/structuralsearch/GroovyStructuralSearchProfile.java85
-rw-r--r--plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml21
-rw-r--r--plugins/groovy/structuralsearch-groovy/testSrc/com/intellij/structuralsearch/GroovyStructuralSearchTest.java166
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy43
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/ClashingTraitMethodsQuickFixTest.groovy5
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy83
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy31
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy8
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy48
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java28
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java30
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgRefManager.java9
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java6
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java17
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java3
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java8
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java41
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java16
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java1
-rw-r--r--plugins/hg4idea/testData/repo/dot_hg/dirstatebin0 -> 352 bytes
-rw-r--r--plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java9
-rw-r--r--plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java10
-rw-r--r--plugins/hg4idea/testSrc/hg4idea/test/validator/HgReferenceValidatorTest.java4
-rw-r--r--plugins/java-decompiler/java-decompiler.iml28
-rw-r--r--plugins/java-decompiler/lib/fernflower.jarbin0 -> 273276 bytes
-rw-r--r--plugins/java-decompiler/src/META-INF/plugin.xml20
-rw-r--r--plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaDecompiler.java205
-rw-r--r--plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaLogger.java81
-rw-r--r--plugins/java-decompiler/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.java160
-rw-r--r--plugins/java-decompiler/testData/Anonymous$1.classbin0 -> 672 bytes
-rw-r--r--plugins/java-decompiler/testData/Anonymous.classbin0 -> 407 bytes
-rw-r--r--plugins/java-decompiler/testData/Anonymous.java13
-rw-r--r--plugins/java-decompiler/testData/Anonymous.txt24
-rw-r--r--plugins/java-decompiler/testData/Constants$A.classbin0 -> 273 bytes
-rw-r--r--plugins/java-decompiler/testData/Constants.classbin0 -> 1640 bytes
-rw-r--r--plugins/java-decompiler/testData/Constants.java47
-rw-r--r--plugins/java-decompiler/testData/Constants.txt82
-rw-r--r--plugins/java-decompiler/testData/Deprecations$ByAnno.classbin0 -> 347 bytes
-rw-r--r--plugins/java-decompiler/testData/Deprecations$ByComment.classbin0 -> 288 bytes
-rw-r--r--plugins/java-decompiler/testData/Deprecations.classbin0 -> 548 bytes
-rw-r--r--plugins/java-decompiler/testData/Deprecations.java19
-rw-r--r--plugins/java-decompiler/testData/Deprecations.txt42
-rw-r--r--plugins/java-decompiler/testData/Enum$1.classbin0 -> 335 bytes
-rw-r--r--plugins/java-decompiler/testData/Enum$2.classbin0 -> 392 bytes
-rw-r--r--plugins/java-decompiler/testData/Enum.classbin0 -> 1407 bytes
-rw-r--r--plugins/java-decompiler/testData/Enum.java19
-rw-r--r--plugins/java-decompiler/testData/Enum.txt33
-rw-r--r--plugins/java-decompiler/testData/ExtendsList.classbin0 -> 510 bytes
-rw-r--r--plugins/java-decompiler/testData/ExtendsList.java9
-rw-r--r--plugins/java-decompiler/testData/ExtendsList.txt19
-rw-r--r--plugins/java-decompiler/testData/Parameters$1Local.classbin0 -> 501 bytes
-rw-r--r--plugins/java-decompiler/testData/Parameters$C1.classbin0 -> 453 bytes
-rw-r--r--plugins/java-decompiler/testData/Parameters$C2.classbin0 -> 445 bytes
-rw-r--r--plugins/java-decompiler/testData/Parameters.classbin0 -> 563 bytes
-rw-r--r--plugins/java-decompiler/testData/Parameters.java23
-rw-r--r--plugins/java-decompiler/testData/Parameters.txt50
-rw-r--r--plugins/java-i18n/java-i18n.iml1
-rw-r--r--plugins/java-i18n/src/META-INF/plugin.xml2
-rw-r--r--plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentPropertiesEndsInspectionProvider.java3
-rw-r--r--plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java2
-rw-r--r--plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceContributor.java4
-rw-r--r--plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java18
-rw-r--r--plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/expected.xml16
-rw-r--r--plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/src/Test.java13
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/annotationArgument/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/annotationArgument/src/Foo.java11
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/src/Test.java14
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/src/Test.java6
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/enum/expected.xml14
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/enum/src/Test.java21
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/fields/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/fields/src/Test.java7
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/src/Test.form23
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/src/Foo.java5
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/expected.xml8
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/src/Test.java14
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/localVariables/expected.xml14
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/localVariables/src/Test.java11
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/nonNlsArray/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/nonNlsArray/src/Test.java9
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/nonNlsComment/expected.xml16
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/nonNlsComment/src/Foo.java12
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/src/Test.java11
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/src/Test.java17
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/expected.xml24
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/src/Test.java14
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/src/Test.java17
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/src/Bar.java12
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/src/Test.java8
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/expected.xml4
-rw-r--r--plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/src/Foo.java5
-rw-r--r--plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/expected.xml24
-rw-r--r--plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu.properties3
-rw-r--r--plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu_fr.properties3
-rw-r--r--plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/IBundle.java25
-rw-r--r--plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Test.java21
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/expected.xml3
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/src/Test.properties1
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/regexp/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/regexp/src/Test.properties2
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/simpleString/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/simpleString/src/Test.properties1
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/expected.xml9
-rw-r--r--plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/src/Test.properties1
-rw-r--r--plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/DuplicateStringLiteralInspectionTest.java24
-rw-r--r--plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/I18NInspectionTest.java62
-rw-r--r--plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspectionTest.java33
-rw-r--r--plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/UnusedMessageFormatParameterInspectionTest.java36
-rw-r--r--plugins/javaFX/FxBuilderEmbedder/lib/embedder.jarbin11698 -> 11711 bytes
-rw-r--r--plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java8
-rw-r--r--plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java4
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java8
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java4
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java8
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java2
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java3
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java7
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java27
-rw-r--r--plugins/javaFX/testData/highlighting/eventHandlers.fxml9
-rw-r--r--plugins/junit/src/com/intellij/execution/ConfigurationUtil.java13
-rw-r--r--plugins/junit/src/com/intellij/execution/junit/TestDirectory.java8
-rw-r--r--plugins/junit/src/com/intellij/execution/junit/TestsPattern.java3
-rw-r--r--plugins/junit/src/com/intellij/execution/junit2/FilterCache.java10
-rw-r--r--plugins/junit/src/com/intellij/execution/junit2/TestProxy.java19
-rw-r--r--plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java2
-rw-r--r--plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java2
-rw-r--r--plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java47
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java3
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java3
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenSmartCompletionContributor.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenVersionCompletionContributor.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyCompletionContributor.java3
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReferenceContributor.java5
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginParamReferenceContributor.java4
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenModificationTracker.java31
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java60
-rw-r--r--plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java11
-rw-r--r--plugins/maven/src/test/java/org/jetbrains/idea/maven/server/MavenServerManagerHelper.java13
-rw-r--r--plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties12
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java25
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java34
-rw-r--r--plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java18
-rw-r--r--plugins/properties/properties-psi-impl/src/META-INF/PropertiesPlugin.xml96
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java8
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java65
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java101
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java40
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java30
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java31
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java29
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java20
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java6
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java10
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java14
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java48
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java84
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java10
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java3
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesReferenceContributor.java2
-rw-r--r--plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java2
-rw-r--r--plugins/properties/properties.iml1
-rw-r--r--plugins/properties/src/META-INF/plugin.xml111
-rw-r--r--plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java8
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ChooseSubsequentPropertyValueEditorAction.java58
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java138
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java1
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java104
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java6
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java140
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java2
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java12
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java69
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java130
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java134
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java (renamed from plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java)40
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java120
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java65
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java152
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java74
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java64
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java4
-rw-r--r--plugins/properties/src/com/intellij/lang/properties/references/PropertiesCompletionContributor.java32
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeys/expected.xml13
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test1.properties2
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test2.properties2
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/expected.xml23
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test1.properties2
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test2.properties2
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/expected.xml13
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test1.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test2.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValues/expected.xml8
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValues/src/Test.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/expected.xml8
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test1.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test2.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/expected.xml13
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test1.properties3
-rw-r--r--plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test2.properties3
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/DuplicatePropertyInspectionTest.java72
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java25
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java51
-rw-r--r--plugins/properties/testSrc/com/intellij/lang/properties/xml/XmlPropertiesTest.java17
-rw-r--r--plugins/structuralsearch/build.xml53
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/DocumentBasedReplaceHandler.java55
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MalformedPatternException.java11
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MatchOptions.java334
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResult.java29
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResultSink.java35
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MatchVariableConstraint.java558
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/Matcher.java84
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/MatchingProcess.java13
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/NamedScriptableDefinition.java81
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/PredefinedConfigurationUtil.java34
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/ReplacementVariableDefinition.java14
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/SSRBundle.java32
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralReplaceHandler.java15
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchException.java13
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java281
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfileBase.java674
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java169
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/UnsupportedPatternException.java11
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/XmlStructuralSearchProfile.java229
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java182
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java16
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java319
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchConstraintsSink.java85
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchContext.java130
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchPredicateProvider.java16
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java207
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchUtils.java42
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java737
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImplUtil.java67
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/PatternTreeContext.java8
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlCompiledPattern.java22
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlMatchingVisitor.java130
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/CompileContext.java71
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/DeleteNodesAction.java59
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/FindInFilesOptimizingSearchHelper.java103
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/GlobalCompilingVisitor.java314
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelper.java27
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelperBase.java85
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java512
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformer.java436
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/TestModeOptimizingSearchHelper.java70
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/XmlCompilingVisitor.java53
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/CompositeFilter.java27
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/DefaultFilter.java16
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/LexicalNodesFilter.java51
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/TagValueFilter.java43
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/XmlLexicalNodesFilter.java19
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/DelegatingHandler.java8
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LightTopLevelMatchingHandler.java46
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LiteralWithSubstitutionHandler.java49
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchPredicate.java27
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchingHandler.java271
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SimpleHandler.java20
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java108
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java557
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SymbolHandler.java21
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java85
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TypedSymbolHandler.java21
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/XmlTextHandler.java23
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/iterators/SsrFilteringNodeIterator.java20
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/AbstractStringBasedPredicate.java22
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/BinaryPredicate.java38
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ContainsPredicate.java18
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/NotPredicate.java24
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ReferencePredicate.java31
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/RegExpPredicate.java175
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptPredicate.java28
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java91
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/WithinPredicate.java38
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategy.java13
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/XmlMatchingStrategy.java42
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java186
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java78
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java256
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralReplaceAction.java55
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchAction.java54
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchPlugin.java110
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplaceOptions.java177
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplacementInfo.java22
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java123
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java217
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementContext.java57
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementInfoImpl.java52
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/Replacer.java424
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacerUtil.java49
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceCommand.java48
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceConfiguration.java46
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java206
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java180
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplacementPreviewDialog.java132
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/Configuration.java87
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationCreator.java12
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java179
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java152
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java635
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java333
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java145
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchConfiguration.java39
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java59
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java1000
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchModel.java29
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java294
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java114
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java241
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java183
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/VarConstraints.form350
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/actions/DoSearchAction.java24
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/CollectingMatchResultSink.java40
-rw-r--r--plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/SmartPsiPointer.java56
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/AnonymToken.java34
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/IndentToken.java20
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/LanguageTokenizer.java14
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/PathMarkerToken.java41
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/PsiMarkerToken.java19
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/RecursiveTokenizingVisitor.java86
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/TextToken.java39
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/Token.java22
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndex.java187
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKey.java60
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKeyDescriptor.java43
-rw-r--r--plugins/structuralsearch/source/com/intellij/tokenindex/Tokenizer.java13
-rw-r--r--plugins/structuralsearch/source/inspectionDescriptions/SSBasedInspection.html9
-rw-r--r--plugins/structuralsearch/source/messages/SSRBundle.properties240
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/META-INF/java.xml6
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/META-INF/plugin.xml48
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaPredefinedConfigurations.java296
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java500
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java675
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaCompiledPattern.java90
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchPredicateProvider.java62
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java1640
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java589
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/BlockFilter.java42
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ClassFilter.java43
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/CommentFilter.java48
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ConstantFilter.java38
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/DeclarationFilter.java44
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ExpressionFilter.java39
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaDocFilter.java33
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java37
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/MethodFilter.java33
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java33
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/SymbolNodeFilter.java72
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeFilter.java42
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeParameterFilter.java43
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypedSymbolNodeFilter.java44
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/VariableFilter.java41
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DeclarationStatementHandler.java96
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DocDataHandler.java70
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/ExpressionHandler.java21
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/StatementHandler.java32
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/DocValuesIterator.java64
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/HierarchyNodeIterator.java128
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java95
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/FormalArgTypePredicate.java38
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ReadPredicate.java28
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/WritePredicate.java33
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/CommentMatchingStrategy.java37
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/ExprMatchingStrategy.java51
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/JavaDocMatchingStrategy.java32
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategyBase.java42
-rw-r--r--plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/SymbolMatchingStrategy.java54
-rw-r--r--plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml17
-rw-r--r--plugins/structuralsearch/structuralsearch-tests.iml18
-rw-r--r--plugins/structuralsearch/structuralsearch.iml28
-rw-r--r--plugins/structuralsearch/testData/java/DoNotFindReturn.java43
-rw-r--r--plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_pattern.java1
-rw-r--r--plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_replacement.java1
-rw-r--r--plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_result.java204
-rw-r--r--plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_source.java204
-rw-r--r--plugins/structuralsearch/testData/java/after1.java82
-rw-r--r--plugins/structuralsearch/testData/java/after2.java11
-rw-r--r--plugins/structuralsearch/testData/java/before1.java89
-rw-r--r--plugins/structuralsearch/testData/java/before2.java19
-rw-r--r--plugins/structuralsearch/testData/ssBased/ExpressionStatement.java8
-rw-r--r--plugins/structuralsearch/testData/ssBased/TwoStatementPattern.java13
-rw-r--r--plugins/structuralsearch/testData/ssBased/simple/expected.xml18
-rw-r--r--plugins/structuralsearch/testData/ssBased/simple/src/x/X.java10
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java22
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java47
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java75
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java2133
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java42
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java2938
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java98
-rw-r--r--plugins/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java128
-rw-r--r--plugins/svn4idea/lib/JAVAHL-LICENSE55
-rw-r--r--plugins/svn4idea/lib/javahl.jarbin168896 -> 0 bytes
-rw-r--r--plugins/svn4idea/lib/javahlsrc.zipbin210516 -> 0 bytes
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java8
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java2
-rw-r--r--plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java2
-rw-r--r--plugins/tasks/tasks-core/src/META-INF/plugin.xml1
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java28
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java382
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryEditor.java101
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryType.java54
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaTask.java102
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java56
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepositoryEditor.java118
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/model/RedmineProject.java7
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java2
-rw-r--r--plugins/tasks/tasks-core/src/icons/TasksIcons.java1
-rw-r--r--plugins/tasks/tasks-core/src/icons/bugzilla.pngbin0 -> 766 bytes
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java4
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/TestNGSuiteReferenceContributor.java5
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java2
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/model/TestData.java2
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java2
-rw-r--r--plugins/typeMigration/src/META-INF/plugin.xml39
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java101
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java61
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java124
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java218
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java145
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/AtomicConversionRule.java420
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/BoxingTypeConversionRule.java36
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ElementToArrayConversionRule.java36
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ListArrayConversionRule.java177
-rw-r--r--plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ThreadLocalConversionRule.java231
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/after.java.template10
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/before.java.template10
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/description.html5
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/after.java.template4
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/before.java.template3
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/description.html5
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/after.java.template15
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/before.java.template10
-rw-r--r--plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/description.html5
-rw-r--r--plugins/typeMigration/test/com/intellij/codeInsight/ConvertToAtomicIntentionTest.java30
-rw-r--r--plugins/typeMigration/test/com/intellij/codeInsight/ConvertToThreadLocalIntentionTest.java30
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/AllTypeMigrationTests.java26
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/ChangeTypeSignatureTest.java148
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/MigrateTypeSignatureTest.java561
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByAtomicRuleTest.java100
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByThreadLocalRuleTest.java44
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java883
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTestBase.java193
-rw-r--r--plugins/typeMigration/test/com/intellij/refactoring/WildcardTypeMigrationTest.java170
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after1.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after10.java10
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after12.java12
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after13.java6
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after14.java10
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after2.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after3.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after4.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after5.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after6.java6
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after7.java11
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after8.java11
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/after9.java15
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/afterExcl.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/afterTA1.java10
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before1.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before10.java8
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before11.java8
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before12.java10
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before13.java4
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before14.java8
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before2.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before3.java5
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before4.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before5.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before6.java4
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before7.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before8.java9
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/before9.java13
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/beforeExcl.java7
-rw-r--r--plugins/typeMigration/testData/intentions/atomic/beforeTA1.java9
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after1.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after2.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after3.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after4.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after5.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after6.java12
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after7.java15
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/after8.java9
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/afterTA1.java14
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before1.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before2.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before3.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before4.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before5.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before6.java7
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before7.java10
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/before8.java4
-rw-r--r--plugins/typeMigration/testData/intentions/threadLocal/beforeTA1.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java.after9
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java.after12
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java.after16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java17
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java.after17
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java.after4
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java.after16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java29
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java.after29
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java29
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java.after29
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java31
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java.after31
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java.after16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java.after20
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java.after12
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java.after14
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java.after15
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java.after14
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java.after18
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java19
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java.after19
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java.after18
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java.after15
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java.after16
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java.after9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.items33
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/before/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.items37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.java54
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/before/Expr.java54
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Ession.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Expr.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/before/Expr.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.items19
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.java26
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/before/Expr.java26
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/before/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/before/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.items30
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/before/Expr.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.items19
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/before/Expr.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/before/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.items58
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/before/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.items78
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.java42
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/before/Expr.java42
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.items98
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.java46
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/before/Expr.java46
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.items62
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/before/Expr.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/before/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/before/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.items23
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/before/Expr.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.items35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.items37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.items36
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/before/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/before/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/before/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/before/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/before/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/before/Expr.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/before/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.items36
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.items35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.items33
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.items34
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.items37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.items35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/before/Expr.java27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/before/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.items14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/before/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/before/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/before/Expr.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.items21
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/before/Expr.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.items34
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/before/Expr.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.items18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/before/Expr.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/before/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/before/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/before/Expr.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.items27
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.java21
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/before/Expr.java21
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/before/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/before/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/before/Expr.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Overriding.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Parent.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/before/Overriding.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Child.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Overriding.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/before/Overriding.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/before/Spec.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/before/Spec.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/before/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/before/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/before/Type.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/before/Type.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.items33
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.java40
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/before/Type.java40
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.items33
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.java37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/before/Type.java37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.items37
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.java39
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/before/Type.java39
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.items32
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/before/Type.java35
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/before/Type.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/before/Type.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.items26
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.items26
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.items26
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.items21
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.items23
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.items23
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.items24
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/before/Type.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/before/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/before/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/before/Type.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/before/Type.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t01/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t01/after/test.java39
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t01/before/test.java39
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t02/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t02/after/test.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t02/before/test.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t03/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t03/after/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t03/before/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t04/after/Test.items21
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t04/after/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t04/before/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t05/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t05/after/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t05/before/test.java22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t06/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t06/after/test.java25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t06/before/test.java25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t07/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t07/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t07/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t08/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t08/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t08/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t09/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t09/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t09/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t10/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t10/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t10/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t100/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t100/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t100/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t101/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t101/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t101/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t102/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t102/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t102/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t103/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t103/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t103/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t104/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t104/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t104/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t105/after/Test.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t105/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t105/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t106/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t106/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t106/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t107/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t107/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t107/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t108/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t108/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t108/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t109/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t109/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t109/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t11/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t11/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t11/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t110/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t110/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t110/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t111/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t111/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t111/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t112/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t112/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t112/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t113/after/Test.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t113/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t113/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t114/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t114/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t114/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t115/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t115/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t115/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t116/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t116/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t116/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t117/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t117/after/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t117/before/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t118/after/Test.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t118/after/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t118/before/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t119/after/Test.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t119/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t119/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t12/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t12/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t12/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t120/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t120/after/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t120/before/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t121/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t121/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t121/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t122/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t122/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t122/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t123/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t123/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t123/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t124/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t124/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t124/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t125/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t125/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t125/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t126/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t126/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t126/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t127/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t127/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t127/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t128/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t128/after/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t128/before/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t129/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t129/after/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t129/before/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t13/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t13/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t13/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t130/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t130/after/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t130/before/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t131/after/Test.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t131/after/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t131/before/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t132/after/Test.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t132/after/test.java25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t132/before/test.java25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t133/after/Test.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t133/after/test.java33
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t133/before/test.java33
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t134/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t134/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t134/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t135/after/Test.items16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t135/after/test.java19
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t135/before/test.java19
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t136/after/Test.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t136/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t136/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t137/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t137/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t137/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t138/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t138/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t138/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t139/after/Test.items7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t139/after/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t139/before/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t14/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t14/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t14/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t15/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t15/after/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t15/before/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t16/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t16/after/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t16/before/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t17/after/Test.items18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t17/after/test.java17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t17/before/test.java17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t18/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t18/after/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t18/before/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t19/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t19/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t19/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t20/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t20/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t20/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t21/after/Test.items14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t21/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t21/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t22/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t22/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t22/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t23/after/Test.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t23/after/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t23/before/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t24/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t24/after/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t24/before/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t25/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t25/after/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t25/before/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t26/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t26/after/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t26/before/test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t27/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t27/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t27/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t28/after/Test.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t28/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t28/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t29/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t29/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t29/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t30/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t30/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t30/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t31/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t31/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t31/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t32/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t32/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t32/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t33/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t33/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t33/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t34/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t34/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t34/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t35/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t35/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t35/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t36/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t36/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t36/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t37/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t37/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t37/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t38/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t38/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t38/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t39/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t39/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t39/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t40/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t40/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t40/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t41/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t41/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t41/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t42/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t42/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t42/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t43/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t43/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t43/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t44/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t44/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t44/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t45/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t45/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t45/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t46/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t46/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t46/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t47/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t47/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t47/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t48/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t48/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t48/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t49/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t49/after/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t49/before/test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t50/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t50/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t50/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t51/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t51/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t51/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t52/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t52/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t52/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t53/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t53/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t53/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t54/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t54/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t54/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t55/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t55/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t55/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t56/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t56/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t56/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t57/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t57/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t57/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t58/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t58/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t58/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t59/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t59/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t59/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t60/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t60/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t60/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t61/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t61/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t61/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t62/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t62/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t62/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t63/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t63/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t63/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t64/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t64/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t64/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t65/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t65/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t65/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t66/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t66/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t66/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t67/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t67/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t67/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t68/after/Test.items17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t68/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t68/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t69/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t69/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t69/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t70/after/Test.items18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t70/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t70/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t71/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t71/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t71/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t72/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t72/after/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t72/before/test.java3
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t73/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t73/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t73/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t74/after/Test.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t74/after/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t74/before/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t75/after/Test.items38
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t75/after/test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t75/before/test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t76/after/Test.items37
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t76/after/test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t76/before/test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t77/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t77/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t77/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t78/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t78/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t78/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t79/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t79/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t79/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t80/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t80/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t80/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t81/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t81/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t81/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t82/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t82/after/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t82/before/test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t83/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t83/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t83/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t84/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t84/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t84/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t85/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t85/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t85/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t86/after/Test.items18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t86/after/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t86/before/test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t87/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t87/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t87/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t88/after/Test.items15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t88/after/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t88/before/test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t89/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t89/after/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t89/before/test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t90/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t90/after/test.java24
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t90/before/test.java24
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t91/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t91/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t91/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t92/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t92/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t92/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t93/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t93/after/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t93/before/test.java8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t94/after/Test.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t94/after/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t94/before/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t95/after/Test.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t95/after/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t95/before/test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t96/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t96/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t96/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t97/after/Test.items8
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t97/after/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t97/before/test.java4
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t98/after/Test.items21
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t98/after/test.java17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t98/before/test.java17
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t99/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t99/after/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/t99/before/test.java6
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/before/test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.java16
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/before/Test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.items19
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/before/Test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/before/Test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/before/Test.java12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.items34
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.java20
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/before/Test.java18
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/before/Test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.items14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/before/Test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.items26
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/before/Test.java15
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.items26
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/before/Test.java14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.items13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/before/Test.java10
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.items25
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/before/Test.java13
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.items35
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.java19
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/before/Test.java19
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.items14
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/before/Test.java9
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.items22
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/before/Test.java11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/Test.items12
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getExtends/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getSuper/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/lengthSize/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtends/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerSuper/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/Test.items11
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/before/test.java5
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/Test.items9
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/before/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/Test.items10
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/test.java7
-rw-r--r--plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/before/test.java7
-rw-r--r--plugins/typeMigration/typeMigration.iml21
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/AbstractCreationTool.java4
-rw-r--r--plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java2
-rw-r--r--plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java2
-rw-r--r--plugins/ui-designer/jps-plugin/testSrc/org/jetbrains/jps/uiDesigner/build/FormsBuilderTest.java10
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java17
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateDialogAction.java2
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java2
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceContributor.java6
-rw-r--r--plugins/ui-designer/src/com/intellij/uiDesigner/make/PreviewNestedFormLoader.java11
-rw-r--r--plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java2
-rw-r--r--plugins/ui-designer/ui-designer.iml2
-rw-r--r--plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/FileAssociationsManager.java7
-rw-r--r--plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java20
-rw-r--r--plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java6
-rw-r--r--plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java2
-rw-r--r--plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java2
-rw-r--r--plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.form2
-rw-r--r--plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.java21
-rw-r--r--plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/SearchScope.java1
-rw-r--r--python/build/pycharm_community_build.gant18
-rw-r--r--python/build/python_plugin_build.gant1
-rw-r--r--python/gen/icons/PythonIcons.java1
-rw-r--r--python/helpers/packaging_tool.py14
-rw-r--r--python/helpers/pycharm_generator_utils/module_redeclarator.py6
-rw-r--r--python/helpers/pydev/pydevd.py2
-rw-r--r--python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.form2
-rw-r--r--python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java16
-rw-r--r--python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java15
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java4
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java8
-rw-r--r--python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java51
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectAction.java (renamed from images/src/org/intellij/images/actions/ColorPickerForImageAction.java)18
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectDialog.java70
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PythonBaseProjectGenerator.java82
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectAction.java105
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java303
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java408
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java37
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java47
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java54
-rw-r--r--python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java195
-rw-r--r--python/openapi/src/com/jetbrains/python/newProject/PyFrameworkProjectGenerator.java3
-rw-r--r--python/openapi/src/com/jetbrains/python/newProject/PythonProjectGenerator.java43
-rw-r--r--python/openapi/src/com/jetbrains/python/packaging/PyPackageManager.java7
-rw-r--r--python/openapi/src/com/jetbrains/python/packaging/PyPackageManagers.java4
-rw-r--r--python/openapi/src/com/jetbrains/python/templateLanguages/PyTemplatesUtil.java65
-rw-r--r--python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.form48
-rw-r--r--python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.java73
-rw-r--r--python/openapi/src/com/jetbrains/python/templateLanguages/TemplateSettingsHolder.java26
-rw-r--r--python/openapi/src/com/jetbrains/python/templateLanguages/TemplatesService.java9
-rw-r--r--python/pluginResources/META-INF/plugin.xml17
-rw-r--r--python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java2
-rw-r--r--python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java4
-rw-r--r--python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java4
-rw-r--r--python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form2
-rw-r--r--python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java12
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/Callable.java2
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyBinaryExpression.java2
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java2
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyCallSiteExpression.java24
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyFile.java1
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PyReferenceOwner.java4
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/PySubscriptionExpression.java2
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java1
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java2
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java4
-rw-r--r--python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java11
-rw-r--r--python/python-community.iml2
-rw-r--r--python/python-rest/src/com/jetbrains/rest/RestFileProviderFactory.java3
-rw-r--r--python/python-rest/src/com/jetbrains/rest/RestPythonUtil.java2
-rw-r--r--python/python-rest/src/com/jetbrains/rest/inspections/RestInspection.java11
-rw-r--r--python/resources/icons/com/jetbrains/python/python-logo.pngbin0 -> 1253 bytes
-rw-r--r--python/src/META-INF/pycharm-core.xml4
-rw-r--r--python/src/META-INF/python-core.xml3
-rw-r--r--python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java10
-rw-r--r--python/src/com/jetbrains/python/PyBundle.java1
-rw-r--r--python/src/com/jetbrains/python/PyBundle.properties4
-rw-r--r--python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/PyStdReferenceContributor.java4
-rw-r--r--python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java3
-rw-r--r--python/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java92
-rw-r--r--python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java2
-rw-r--r--python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java4
-rw-r--r--python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java2
-rw-r--r--python/src/com/jetbrains/python/console/PyOpenDebugConsoleAction.java2
-rw-r--r--python/src/com/jetbrains/python/console/PydevConsoleRunner.java20
-rw-r--r--python/src/com/jetbrains/python/console/PythonDebugLanguageConsoleView.java235
-rw-r--r--python/src/com/jetbrains/python/documentation/DocStringReferenceContributor.java5
-rw-r--r--python/src/com/jetbrains/python/documentation/doctest/PyDocReferenceExpression.java1
-rw-r--r--python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java4
-rw-r--r--python/src/com/jetbrains/python/findUsages/PyModuleFindUsagesHandler.java3
-rw-r--r--python/src/com/jetbrains/python/formatter/PyLanguageCodeStyleSettingsProvider.java7
-rw-r--r--python/src/com/jetbrains/python/formatter/PyPreFormatProcessor.java6
-rw-r--r--python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java12
-rw-r--r--python/src/com/jetbrains/python/inspections/PyDocstringInspection.java9
-rw-r--r--python/src/com/jetbrains/python/inspections/PyInspection.java18
-rw-r--r--python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java4
-rw-r--r--python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java7
-rw-r--r--python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java7
-rw-r--r--python/src/com/jetbrains/python/inspections/quickfix/PySuppressInspectionFix.java5
-rw-r--r--python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java7
-rw-r--r--python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralFindUsagesHandlerFactory.java17
-rw-r--r--python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java8
-rw-r--r--python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java6
-rw-r--r--python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java31
-rw-r--r--python/src/com/jetbrains/python/packaging/PyPackageManagersImpl.java2
-rw-r--r--python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java6
-rw-r--r--python/src/com/jetbrains/python/projectView/PyRemoteLibrariesNode.java60
-rw-r--r--python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java12
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java277
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java22
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java22
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyFileImpl.java1
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java36
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java16
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java3
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java9
-rw-r--r--python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java55
-rw-r--r--python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyBlockEvaluator.java314
-rw-r--r--python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationContext.java42
-rw-r--r--python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationResult.java26
-rw-r--r--python/src/com/jetbrains/python/psi/impl/blockEvaluator/package-info.java7
-rw-r--r--python/src/com/jetbrains/python/psi/impl/stubs/PyDecoratorCallElementType.java18
-rw-r--r--python/src/com/jetbrains/python/psi/stubs/PyDecoratorStubIndex.java24
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java4
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyFunctionType.java2
-rw-r--r--python/src/com/jetbrains/python/psi/types/PyTypeChecker.java13
-rw-r--r--python/src/com/jetbrains/python/remote/PySkeletonsPathAware.java13
-rw-r--r--python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java17
-rw-r--r--python/src/com/jetbrains/python/remote/RemoteProjectSettings.java4
-rw-r--r--python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java2
-rw-r--r--python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java2
-rw-r--r--python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java42
-rw-r--r--python/src/com/jetbrains/python/sdk/PySdkUtil.java8
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonEnvUtil.java5
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkType.java40
-rw-r--r--python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java107
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/IronPythonSdkFlavor.java15
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/JythonSdkFlavor.java10
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/PyPySdkFlavor.java50
-rw-r--r--python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java62
-rw-r--r--python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java2
-rw-r--r--python/src/com/jetbrains/python/spellchecker/python.dic2
-rw-r--r--python/src/com/jetbrains/python/spellchecker/pythonExtras.dic1
-rw-r--r--python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java14
-rw-r--r--python/src/com/jetbrains/python/testing/PyRerunFailedTestsAction.java14
-rw-r--r--python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java2
-rw-r--r--python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java2
-rw-r--r--python/testData/inspections/PyCallingNonCallableInspection/callDictSubscriptionExpression.py4
-rw-r--r--python/testData/inspections/PyCallingNonCallableInspection/localCallableClass.py7
-rw-r--r--python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/a.py4
-rw-r--r--python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/library.py1
-rw-r--r--python/testSrc/com/jetbrains/python/Py3CompletionTest.java14
-rw-r--r--python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java2
-rw-r--r--python/testSrc/com/jetbrains/python/PySdkFlavorTest.java96
-rw-r--r--python/testSrc/com/jetbrains/python/PythonAutoPopupTest.java3
-rw-r--r--python/testSrc/com/jetbrains/python/PythonCompletionTest.java9
-rw-r--r--python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java8
-rw-r--r--python/testSrc/com/jetbrains/python/inspections/PyCallingNonCallableInspectionTest.java10
-rw-r--r--python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java5
-rw-r--r--resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/after.java.template7
-rw-r--r--resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/before.java.template7
-rw-r--r--resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/description.html5
-rw-r--r--resources-en/src/messages/QuickFixBundle.properties4
-rw-r--r--resources-en/src/search/searchableOptions.xml3
-rw-r--r--resources/src/META-INF/IdeaPlugin.xml6
-rw-r--r--resources/src/idea/JavaActions.xml3
-rw-r--r--resources/src/idea/RichPlatformPlugin.xml1
-rw-r--r--spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java16
-rw-r--r--spellchecker/src/com/intellij/spellchecker/jetbrains.dic2
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java17
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/impl/DomCompletionContributor.java3
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java11
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/impl/DomReferenceContributor.java3
-rw-r--r--xml/dom-impl/src/com/intellij/util/xml/tree/actions/DeleteDomElement.java10
-rw-r--r--xml/dom-openapi/src/com/intellij/util/xml/DomManager.java11
-rw-r--r--xml/dom-openapi/src/com/intellij/util/xml/ParentScopeProvider.java4
-rw-r--r--xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManager.java5
-rw-r--r--xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java2
-rw-r--r--xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java3
-rw-r--r--xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form4
-rw-r--r--xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java38
-rw-r--r--xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form26
-rw-r--r--xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java50
-rw-r--r--xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java2
-rw-r--r--xml/impl/src/com/intellij/codeInsight/completion/XmlNoVariantsDelegator.java4
-rw-r--r--xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java77
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java26
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java17
-rw-r--r--xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java4
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewAction.java4
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java3
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewUtil.java2
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java19
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java12
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/CommentZenCodingFilter.java8
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/EscapeZenCodingFilter.java8
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java8
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/TrimZenCodingFilter.java22
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/XslZenCodingFilter.java10
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/filters/ZenCodingFilter.java15
-rw-r--r--xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java7
-rw-r--r--xml/impl/src/com/intellij/ide/actions/CreateHtmlFileAction.java4
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java22
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java29
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/actions/BaseOpenInBrowserAction.java7
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java12
-rw-r--r--xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java2
-rw-r--r--xml/impl/src/com/intellij/javaee/MapExternalResourceDialog.java4
-rw-r--r--xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java2
-rw-r--r--xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java70
-rw-r--r--xml/impl/src/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java2
-rw-r--r--xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java70
-rw-r--r--xml/relaxng/src/org/intellij/plugins/relaxNG/RelaxNGReferenceContributor.java3
-rw-r--r--xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncFileImpl.java1
-rw-r--r--xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java2
-rw-r--r--xml/xml-psi-api/src/com/intellij/codeInspection/XmlInspectionSuppressor.java31
-rw-r--r--xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressableInspectionTool.java87
-rw-r--r--xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressionProvider.java17
-rw-r--r--xml/xml-psi-api/src/com/intellij/javaee/ExternalResourceManager.java7
-rw-r--r--xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java7
-rw-r--r--xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java22
-rw-r--r--xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlFileImpl.java3
3331 files changed, 93799 insertions, 20512 deletions
diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 587a48c56c17..c9f9460658ff 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -415,13 +415,7 @@
<inspection_tool class="PyUnboundLocalVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnnecessaryBackslashInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnreachableCodeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
- <inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="ignoredIdentifiers">
- <value>
- <list size="0" />
- </value>
- </option>
- </inspection_tool>
+ <inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnusedLocalInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreTupleUnpacking" value="true" />
<option name="ignoreLambdaParameters" value="true" />
diff --git a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
index 1c1b7332bd49..32f8d3d65336 100644
--- a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
+++ b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
@@ -570,13 +570,7 @@
<inspection_tool class="PyUnboundLocalVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnnecessaryBackslashInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnreachableCodeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
- <inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="ignoredIdentifiers">
- <value>
- <list size="0" />
- </value>
- </option>
- </inspection_tool>
+ <inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnusedLocalInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreTupleUnpacking" value="true" />
<option name="ignoreLambdaParameters" value="true" />
diff --git a/.idea/libraries/Guava.xml b/.idea/libraries/Guava.xml
index ae7646c40e9d..5b480ad0d65a 100644
--- a/.idea/libraries/Guava.xml
+++ b/.idea/libraries/Guava.xml
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="Guava">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/guava-14.0.1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/guava-17.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$PROJECT_DIR$/lib/src/guava-14.0.1-sources.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/src/guava-17.0-sources.jar!/" />
</SOURCES>
</library>
</component> \ No newline at end of file
diff --git a/.idea/libraries/JaCoCo.xml b/.idea/libraries/JaCoCo.xml
new file mode 100644
index 000000000000..cbce4794ace4
--- /dev/null
+++ b/.idea/libraries/JaCoCo.xml
@@ -0,0 +1,17 @@
+<component name="libraryTable">
+ <library name="JaCoCo">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacocoant.jar!/" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacocoagent.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/org.jacoco.ant/src" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/org.jacoco.core/src" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/org.jacoco.agent/src" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/org.jacoco.report/src" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/jacoco-maven-plugin/src" />
+ <root url="jar://$PROJECT_DIR$/plugins/coverage/lib/jacoco_src.zip!/v0.5.6/org.jacoco.agent.rt/src" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/Netty.xml b/.idea/libraries/Netty.xml
index c79ce3e2cbe0..723ad4eef42d 100644
--- a/.idea/libraries/Netty.xml
+++ b/.idea/libraries/Netty.xml
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="Netty">
<CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/netty-all-4.1.0.Alpha1.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/netty-all-4.1.0.Beta1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$PROJECT_DIR$/lib/src/netty-all-4.1.0.Alpha1-sources.jar!/" />
+ <root url="jar://$PROJECT_DIR$/lib/src/netty-all-4.1.0.Beta1-sources.jar!/" />
</SOURCES>
</library>
</component> \ No newline at end of file
diff --git a/.idea/libraries/nekohtml.xml b/.idea/libraries/nekohtml.xml
new file mode 100644
index 000000000000..4817f403af21
--- /dev/null
+++ b/.idea/libraries/nekohtml.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="nekohtml">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/lib/nekohtml-1.9.14.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 600392beba22..c23fcc8c1df4 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -5,7 +5,6 @@
<module fileurl="file://$PROJECT_DIR$/plugins/ByteCodeViewer/ByteCodeViewer.iml" filepath="$PROJECT_DIR$/plugins/ByteCodeViewer/ByteCodeViewer.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-java.iml" group="plugins/IntelliLang" />
- <module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-javaee.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/python/IntelliLang-python/IntelliLang-python.iml" filepath="$PROJECT_DIR$/python/IntelliLang-python/IntelliLang-python.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-tests/IntelliLang-tests.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-tests/IntelliLang-tests.iml" group="plugins/IntelliLang" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-xml.iml" group="plugins/IntelliLang" />
@@ -41,6 +40,9 @@
<module fileurl="file://$PROJECT_DIR$/plugins/copyright/copyright.iml" filepath="$PROJECT_DIR$/plugins/copyright/copyright.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/core-api/core-api.iml" filepath="$PROJECT_DIR$/platform/core-api/core-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/core-impl/core-impl.iml" filepath="$PROJECT_DIR$/platform/core-impl/core-impl.iml" group="platform" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/coverage/coverage.iml" filepath="$PROJECT_DIR$/plugins/coverage/coverage.iml" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/coverage-common/coverage-common.iml" filepath="$PROJECT_DIR$/plugins/coverage-common/coverage-common.iml" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/coverage/covergae_rt/coverage_rt.iml" filepath="$PROJECT_DIR$/plugins/coverage/covergae_rt/coverage_rt.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/cucumber-jvm-formatter/cucumber-jvm-formatter.iml" filepath="$PROJECT_DIR$/plugins/cucumber-jvm-formatter/cucumber-jvm-formatter.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/build/cucumber-test-runner/cucumber-test-runner.iml" filepath="$PROJECT_DIR$/build/cucumber-test-runner/cucumber-test-runner.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" filepath="$PROJECT_DIR$/plugins/cvs/cvs-core/cvs-core.iml" group="plugins/VCS/cvs" />
@@ -54,6 +56,7 @@
<module fileurl="file://$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" filepath="$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/xml/dom-tests/dom-tests.iml" filepath="$PROJECT_DIR$/xml/dom-tests/dom-tests.iml" group="xml" />
<module fileurl="file://$PROJECT_DIR$/../base/draw9patch/draw9patch.iml" filepath="$PROJECT_DIR$/../base/draw9patch/draw9patch.iml" group="plugins/Android/android-sdk" />
+ <module fileurl="file://$PROJECT_DIR$/platform/duplicates-analysis/duplicates-analysis.iml" filepath="$PROJECT_DIR$/platform/duplicates-analysis/duplicates-analysis.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/dvcs/dvcs.iml" filepath="$PROJECT_DIR$/platform/dvcs/dvcs.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/../base/device_validator/dvlib/dvlib.iml" filepath="$PROJECT_DIR$/../base/device_validator/dvlib/dvlib.iml" group="plugins/Android/android-sdk" />
<module fileurl="file://$PROJECT_DIR$/plugins/eclipse/eclipse.iml" filepath="$PROJECT_DIR$/plugins/eclipse/eclipse.iml" group="plugins" />
@@ -91,6 +94,7 @@
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/intellilang-jps-plugin/intellilang-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/intellilang-jps-plugin/intellilang-jps-plugin.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/java/java-analysis-api/java-analysis-api.iml" filepath="$PROJECT_DIR$/java/java-analysis-api/java-analysis-api.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/java-analysis-impl/java-analysis-impl.iml" filepath="$PROJECT_DIR$/java/java-analysis-impl/java-analysis-impl.iml" group="java" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/java-decompiler/java-decompiler.iml" filepath="$PROJECT_DIR$/plugins/java-decompiler/java-decompiler.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/java-i18n/java-i18n.iml" filepath="$PROJECT_DIR$/plugins/java-i18n/java-i18n.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/java/java-impl/java-impl.iml" filepath="$PROJECT_DIR$/java/java-impl/java-impl.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/java/java-indexing-api/java-indexing-api.iml" filepath="$PROJECT_DIR$/java/java-indexing-api/java-indexing-api.iml" group="java" />
@@ -183,6 +187,10 @@
<module fileurl="file://$PROJECT_DIR$/platform/smRunner/smRunner.iml" filepath="$PROJECT_DIR$/platform/smRunner/smRunner.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" filepath="$PROJECT_DIR$/plugins/cvs/smartcvs-src/smartcvs-src.iml" group="plugins/VCS/cvs" />
<module fileurl="file://$PROJECT_DIR$/spellchecker/spellchecker.iml" filepath="$PROJECT_DIR$/spellchecker/spellchecker.iml" group="plugins" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/structuralsearch/structuralsearch.iml" filepath="$PROJECT_DIR$/plugins/structuralsearch/structuralsearch.iml" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml" filepath="$PROJECT_DIR$/plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml" filepath="$PROJECT_DIR$/plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/structuralsearch/structuralsearch-tests.iml" filepath="$PROJECT_DIR$/plugins/structuralsearch/structuralsearch-tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/structure-view-api/structure-view-api.iml" filepath="$PROJECT_DIR$/platform/structure-view-api/structure-view-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/structure-view-impl/structure-view-impl.iml" filepath="$PROJECT_DIR$/platform/structure-view-impl/structure-view-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" filepath="$PROJECT_DIR$/plugins/svn4idea/svn4idea.iml" group="plugins/VCS" />
@@ -199,6 +207,7 @@
<module fileurl="file://$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" filepath="$PROJECT_DIR$/plugins/testng_rt/testng_rt.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/bootstrap/tests_bootstrap.iml" filepath="$PROJECT_DIR$/platform/testFramework/bootstrap/tests_bootstrap.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/../base/testutils/testutils.iml" filepath="$PROJECT_DIR$/../base/testutils/testutils.iml" group="plugins/Android/android-sdk" />
+ <module fileurl="file://$PROJECT_DIR$/plugins/typeMigration/typeMigration.iml" filepath="$PROJECT_DIR$/plugins/typeMigration/typeMigration.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/ui-designer.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" filepath="$PROJECT_DIR$/plugins/ui-designer-core/ui-designer-core.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/ui-designer/jps-plugin/ui-designer-jps-plugin.iml" group="plugins" />
diff --git a/.idea/runConfigurations/IDEA.xml b/.idea/runConfigurations/IDEA.xml
index d201d0a92bd1..f916ac953ded 100644
--- a/.idea/runConfigurations/IDEA.xml
+++ b/.idea/runConfigurations/IDEA.xml
@@ -18,7 +18,9 @@
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
- <RunnerSettings RunnerId="Profile " />
+ <RunnerSettings RunnerId="Profile ">
+ <option name="myExternalizedOptions" />
+ </RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
diff --git a/.idea/runConfigurations/IDEA_with_Python_plugin.xml b/.idea/runConfigurations/IDEA_with_Python_plugin.xml
index b296725f24de..2dab1fe57edc 100644
--- a/.idea/runConfigurations/IDEA_with_Python_plugin.xml
+++ b/.idea/runConfigurations/IDEA_with_Python_plugin.xml
@@ -18,7 +18,9 @@
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
- <RunnerSettings RunnerId="Profile " />
+ <RunnerSettings RunnerId="Profile ">
+ <option name="myExternalizedOptions" />
+ </RunnerSettings>
<ConfigurationWrapper RunnerId="Debug" />
<method />
</configuration>
diff --git a/.idea/runConfigurations/PyCharm.xml b/.idea/runConfigurations/PyCharm.xml
index 36091229eaa4..aef88813d5b0 100644
--- a/.idea/runConfigurations/PyCharm.xml
+++ b/.idea/runConfigurations/PyCharm.xml
@@ -18,7 +18,9 @@
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
- <RunnerSettings RunnerId="Profile " />
+ <RunnerSettings RunnerId="Profile ">
+ <option name="myExternalizedOptions" />
+ </RunnerSettings>
<ConfigurationWrapper RunnerId="Debug" />
<method />
</configuration>
diff --git a/bin/mac/fsnotifier b/bin/mac/fsnotifier
index d69157acdb19..9bbf3898bb5d 100755
--- a/bin/mac/fsnotifier
+++ b/bin/mac/fsnotifier
Binary files differ
diff --git a/build/build.iml b/build/build.iml
index db115fb3dc9e..7486cf38b75d 100644
--- a/build/build.iml
+++ b/build/build.iml
@@ -10,7 +10,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="Groovy" level="project" />
<orderEntry type="library" exported="" name="Ant" level="project" />
- <orderEntry type="library" scope="RUNTIME" name="asm4" level="project" />
+ <orderEntry type="library" scope="RUNTIME" name="asm5" level="project" />
<orderEntry type="library" exported="" scope="RUNTIME" name="cli-parser" level="project" />
<orderEntry type="library" scope="RUNTIME" name="JDOM" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Netty" level="project" />
diff --git a/build/conf/mac/Contents/Info.plist b/build/conf/mac/Contents/Info.plist
index eb5a13153c05..4a9c7d117dce 100644
--- a/build/conf/mac/Contents/Info.plist
+++ b/build/conf/mac/Contents/Info.plist
@@ -79,13 +79,15 @@
<key>idea.java.redist</key>
<string>NoJavaDistribution</string>
+ <key>idea.home.path</key>
+ <string>$APP_PACKAGE/Contents</string>
</dict>
<key>VMOptions</key>
<string>@@vmoptions@@ -Xbootclasspath/a:../lib/boot.jar</string>
<key>WorkingDirectory</key>
- <string>$APP_PACKAGE/bin</string>
+ <string>$APP_PACKAGE/Contents/bin</string>
</dict>
</dict>
</plist>
diff --git a/build/conf/mac/Contents/MacOS/idea b/build/conf/mac/Contents/MacOS/idea
index 3f5d2c46a401..6ba553f866fd 100755
--- a/build/conf/mac/Contents/MacOS/idea
+++ b/build/conf/mac/Contents/MacOS/idea
Binary files differ
diff --git a/build/conf/mac/Contents/_CodeSignature/CodeResources b/build/conf/mac/Contents/_CodeSignature/CodeResources
new file mode 100644
index 000000000000..54901395f893
--- /dev/null
+++ b/build/conf/mac/Contents/_CodeSignature/CodeResources
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>rules</key>
+ <dict>
+ <key>^bin/</key>
+ <true/>
+ <key>^lib/</key>
+ <true/>
+ <key>^license/</key>
+ <true/>
+ <key>^MacOS/</key>
+ <true/>
+ <key>^plugins/</key>
+ <true/>
+ <key>^Resources/</key>
+ <true/>
+ </dict>
+ </dict>
+</plist> \ No newline at end of file
diff --git a/build/conf/nsis/idea.nsi b/build/conf/nsis/idea.nsi
index 850ac4b305f5..145d61d0624b 100644
--- a/build/conf/nsis/idea.nsi
+++ b/build/conf/nsis/idea.nsi
@@ -531,36 +531,36 @@ Function leaveUninstallOldVersionDialog
!insertmacro INSTALLOPTIONS_READ $2 "UninstallOldVersions.ini" "Settings" "State"
StrCmp $2 2 enable_disable
Goto done
-
+
enable_disable:
- !insertmacro INSTALLOPTIONS_READ $0 "UninstallOldVersions.ini" "Field 2" "State"
- StrCmp $0 1 enable disable
+ !insertmacro INSTALLOPTIONS_READ $0 "UninstallOldVersions.ini" "Field 2" "State"
+ StrCmp $0 1 enable disable
enable:
StrCpy $1 ""
Goto setFlag
disable:
- Call setState
+ Call setState
StrCpy $1 "DISABLED"
-setFlag:
+setFlag:
Push $1
Call setFlags
-done:
+done:
Pop $4
- Pop $1
+ Pop $1
StrCmp $2 0 skip_abort
Pop $2
Abort
-skip_abort:
+skip_abort:
StrCpy $2 "OK"
FunctionEnd
Function setFlags
- Pop $1
+ Pop $1
!insertmacro INSTALLOPTIONS_READ $max_fields "UninstallOldVersions.ini" "Settings" "NumFields"
StrCpy $4 3
- ; change flags of fields in according of master checkbox
-loop:
+ ; change flags of fields in according of master checkbox
+loop:
!insertmacro INSTALLOPTIONS_READ $1 "UninstallOldVersions.ini" "Field $4" "HWND"
EnableWindow $1 $0
!insertmacro INSTALLOPTIONS_WRITE "UninstallOldVersions.ini" "Field $4" "Flags" "$1"
@@ -573,7 +573,7 @@ FunctionEnd
Function setState
!insertmacro INSTALLOPTIONS_READ $max_fields "UninstallOldVersions.ini" "Settings" "NumFields"
StrCpy $4 3
- ; change state of fields in according of master checkbox
+ ; change state of fields in according of master checkbox
loop:
!insertmacro INSTALLOPTIONS_READ $1 "UninstallOldVersions.ini" "Field $4" "HWND"
SendMessage $1 ${BM_SETCHECK} 0 "0"
@@ -750,21 +750,28 @@ skip_quicklaunch_shortcut:
"${Index}-Skip:"
WriteRegStr HKCR "IntelliJIdeaProjectFile\shell\open\command" "" \
'$INSTDIR\bin\${PRODUCT_EXE_FILE} "%1"'
-
- ; back up old value of .java
- StrCmp "${PRODUCT_FULL_NAME}" "IntelliJ IDEA Community Edition" java_association
- StrCmp "${PRODUCT_FULL_NAME}" "IntelliJ IDEA" 0 skip_ipr
-java_association:
- ReadRegStr $1 HKCR ".java" ""
- StrCmp $1 "" skip_backup
- StrCmp $1 "IntelliJIdeaProjectFile" skip_backup
- WriteRegStr HKCR ".java" "backup_val" $1
-skip_backup:
- WriteRegStr HKCR ".java" "" "IntelliJIdeaProjectFile"
!undef Index
skip_ipr:
+StrCmp "${ASSOCIATION}" "NoAssociation" skip_association
+ ; back up old value of an association
+ ReadRegStr $1 HKCR ${ASSOCIATION} ""
+ StrCmp $1 "" skip_backup
+ StrCmp $1 ${PRODUCT_PATHS_SELECTOR} skip_backup
+ WriteRegStr HKCR ${ASSOCIATION} "backup_val" $1
+skip_backup:
+ WriteRegStr HKCR ${ASSOCIATION} "" "${PRODUCT_PATHS_SELECTOR}"
+ ReadRegStr $0 HKCR ${PRODUCT_PATHS_SELECTOR} ""
+ StrCmp $0 "" 0 command_exists
+ WriteRegStr HKCR ${PRODUCT_PATHS_SELECTOR} "" "${PRODUCT_FULL_NAME}"
+ WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\shell" "" "open"
+ WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\DefaultIcon" "" "$INSTDIR\bin\${PRODUCT_EXE_FILE},0"
+command_exists:
+ WriteRegStr HKCR "${PRODUCT_PATHS_SELECTOR}\shell\open\command" "" \
+ '$INSTDIR\bin\${PRODUCT_EXE_FILE} "%1"'
+
+skip_association:
; Rest of script
@@ -772,7 +779,7 @@ skip_ipr:
SectionIn RO
!include "idea_win.nsh"
- IntCmp $IS_UPGRADE_60 1 skip_properties
+ IntCmp $IS_UPGRADE_60 1 skip_properties
SetOutPath $INSTDIR\bin
File "${PRODUCT_PROPERTIES_FILE}"
File "${PRODUCT_VM_OPTIONS_FILE}"
@@ -851,6 +858,44 @@ FunctionEnd
;------------------------------------------------------------------------------
Function un.onInit
+ ;admin perm. is required to uninstall?
+ ${UnStrStr} $R0 $INSTDIR $PROGRAMFILES
+ StrCmp $R0 $INSTDIR requred_admin_perm UAC_Done
+
+requred_admin_perm:
+ ;the user has admin rights?
+ UserInfo::GetAccountType
+ Pop $R2
+ StrCmp $R2 "Admin" UAC_Admin uninstall_location
+
+uninstall_location:
+ ;check if the uninstallation is running from the product location
+ IfFileExists $APPDATA\${PRODUCT_PATHS_SELECTOR}_${VER_BUILD}_Uninstall.exe UAC_Elevate copy_uninstall
+
+copy_uninstall:
+ ;do copy for unistall.exe
+ CopyFiles "$OUTDIR\Uninstall.exe" "$APPDATA\${PRODUCT_PATHS_SELECTOR}_${VER_BUILD}_Uninstall.exe"
+ ExecWait '"$APPDATA\${PRODUCT_PATHS_SELECTOR}_${VER_BUILD}_Uninstall.exe" _?=$INSTDIR'
+ Delete "$APPDATA\${PRODUCT_PATHS_SELECTOR}_${VER_BUILD}_Uninstall.exe"
+ Quit
+
+UAC_Elevate:
+ !insertmacro UAC_RunElevated
+ StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? - continue install under user
+ StrCmp 0 $0 0 UAC_Err ; Error?
+ StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
+ Quit
+UAC_ElevationAborted:
+UAC_Err:
+ Abort
+UAC_Success:
+ StrCmp 1 $3 UAC_Admin ;Admin?
+ StrCmp 3 $1 0 UAC_ElevationAborted ;Try again?
+ goto UAC_Elevate
+UAC_Admin:
+ SetShellVarContext all
+ StrCpy $baseRegKey "HKLM"
+UAC_Done:
!insertmacro MUI_UNGETLANGUAGE
!insertmacro INSTALLOPTIONS_EXTRACT "DeleteSettings.ini"
FunctionEnd
@@ -1094,10 +1139,8 @@ clear_Registry:
StrCpy $2 "MenuFolder"
Call un.OMDeleteRegValue
- StrCmp "${PRODUCT_FULL_NAME}" "IntelliJ IDEA Community Edition" restore_java_association
- StrCmp "${PRODUCT_FULL_NAME}" "IntelliJ IDEA" 0 finish_uninstall
-restore_java_association:
- StrCpy $1 ".java"
+ StrCmp "${ASSOCIATION}" "NoAssociation" finish_uninstall
+ StrCpy $1 "${ASSOCIATION}"
StrCpy $2 "backup_val"
Call un.ReturnBackupRegValue
diff --git a/build/gant.xml b/build/gant.xml
index 672896d31364..416440b6aebd 100644
--- a/build/gant.xml
+++ b/build/gant.xml
@@ -22,7 +22,7 @@
<include name="groovy-all-*.jar"/>
<include name="protobuf*.jar"/>
<include name="netty*.jar"/>
- <include name="asm4-all.jar"/>
+ <include name="asm-all.jar"/>
<include name="asm-commons.jar"/>
<include name="jgoodies-forms.jar"/>
<include name="guava*.jar"/>
diff --git a/build/lib/jps/antlayout.jar b/build/lib/jps/antlayout.jar
index 8f6554dc67f3..ead2a804df0a 100644
--- a/build/lib/jps/antlayout.jar
+++ b/build/lib/jps/antlayout.jar
Binary files differ
diff --git a/build/lib/jps/groovy-jps-plugin.jar b/build/lib/jps/groovy-jps-plugin.jar
index 5166341eb156..43bac2049446 100644
--- a/build/lib/jps/groovy-jps-plugin.jar
+++ b/build/lib/jps/groovy-jps-plugin.jar
Binary files differ
diff --git a/build/lib/jps/groovy_rt.jar b/build/lib/jps/groovy_rt.jar
index 43d418bfe294..ea656c580ce2 100644
--- a/build/lib/jps/groovy_rt.jar
+++ b/build/lib/jps/groovy_rt.jar
Binary files differ
diff --git a/build/lib/jps/jps-builders.jar b/build/lib/jps/jps-builders.jar
index b02ac27bc085..05c199bfbb85 100644
--- a/build/lib/jps/jps-builders.jar
+++ b/build/lib/jps/jps-builders.jar
Binary files differ
diff --git a/build/lib/jps/jps-model.jar b/build/lib/jps/jps-model.jar
index e56a781f9006..0c57c42c6abc 100644
--- a/build/lib/jps/jps-model.jar
+++ b/build/lib/jps/jps-model.jar
Binary files differ
diff --git a/build/lib/jps/ui-designer-jps-plugin.jar b/build/lib/jps/ui-designer-jps-plugin.jar
index 69d7e02232b7..0050493f9385 100644
--- a/build/lib/jps/ui-designer-jps-plugin.jar
+++ b/build/lib/jps/ui-designer-jps-plugin.jar
Binary files differ
diff --git a/build/lib/jps/util.jar b/build/lib/jps/util.jar
index adef8f02bc9c..fad7e614bb49 100644
--- a/build/lib/jps/util.jar
+++ b/build/lib/jps/util.jar
Binary files differ
diff --git a/build/scripts/common_tests.gant b/build/scripts/common_tests.gant
index f13c342dd23b..a74f7d43a0b3 100644
--- a/build/scripts/common_tests.gant
+++ b/build/scripts/common_tests.gant
@@ -45,41 +45,43 @@ private pass(String prop) {
target('run_tests': 'Run java tests') {
depends([check, compile])
- ant.junit(fork: "yes", showoutput: "true", logfailedtests:false, printsummary: "true") {
- pass("idea.test.group")
- pass("idea.test.patterns")
- pass("idea.fast.only")
- pass("teamcity.build.tempDir")
- pass("teamcity.tests.recentlyFailedTests.file")
- jvmarg (value: "-Didea.platform.prefix=Idea")
- jvmarg (value: "-Djava.system.class.loader=com.intellij.util.lang.UrlClassLoader")
-
- System.getProperties().entrySet().each {
- if (it.key.startsWith("pass.")) {
- def trimmed = it.key.substring("pass.".length());
- jvmarg(value: "-D${trimmed}=${it.value}");
- };
- }
-
- commonJvmArgs().each { jvmarg(value: it) }
+ def classpathFile = "$home/junit.classpath"
+ List<String> testRuntimeClasspath = projectBuilder.moduleRuntimeClasspath(findModule("community-main"), true)
+ new File(classpathFile).text = testRuntimeClasspath.findAll({ new File((String)it).exists() }).join('\n')
+
+ testcases.each { testCase ->
+ ant.junit(fork: "yes", showoutput: "true", logfailedtests: false) {
+ jvmarg(value: "-Dclasspath.file=${classpathFile}")
+ pass("idea.test.group")
+ pass("idea.test.patterns")
+ pass("idea.fast.only")
+ pass("teamcity.build.tempDir")
+ pass("teamcity.tests.recentlyFailedTests.file")
+ jvmarg(value: "-Didea.platform.prefix=Idea")
+
+ System.getProperties().entrySet().each {
+ if (it.key.startsWith("pass.")) {
+ def trimmed = it.key.substring("pass.".length());
+ jvmarg(value: "-D${trimmed}=${it.value}");
+ };
+ }
+ commonJvmArgs().each { jvmarg(value: it) }
- if (isDefined("jvm_args")) {
- jvm_args.each { jvmarg(value: it) }
- }
+ jvmarg(value: "-Dbootstrap.testcases=$testCase")
- classpath {
- projectBuilder.moduleRuntimeClasspath(findModule("community-main"), true).each {
- pathelement(location: it)
+ if (isDefined("jvm_args")) {
+ jvm_args.each { jvmarg(value: it) }
}
- pathelement(location: "${jdkHome}/lib/tools.jar")
- }
- formatter(type: "plain")
- formatter(type: "xml")
+ classpath {
+ projectBuilder.moduleRuntimeClasspath(findModule("tests_bootstrap"), false).each {
+ pathelement(location: it)
+ }
+ pathelement(location: "${jdkHome}/lib/tools.jar")
+ }
- testcases.each {
- test (name: it)
+ test(name: 'com.intellij.tests.BootstrapTests')
}
}
}
diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant
index 17b20d79196c..a31b66f5a654 100644
--- a/build/scripts/dist.gant
+++ b/build/scripts/dist.gant
@@ -144,8 +144,8 @@ def layoutAll(Map args, String home, String out, Paths _paths = null, buildJps =
androidBuildNumber = p("buildNumber")
//def macAppRoot = isEap() ?
- // "IntelliJ IDEA ${p("component.version.major")} CE EAP.app" :
- // "IntelliJ IDEA ${p("component.version.major")} CE.app"
+ // "IntelliJ IDEA ${p("component.version.major")} CE EAP.app/Contents" :
+ // "IntelliJ IDEA ${p("component.version.major")} CE.app/Contents"
def winZip = "$paths.artifacts/android-studio-${androidBuildNumber}.win.zip"
def macZip = "$paths.artifacts/android-studio-${androidBuildNumber}.mac.zip"
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index 3d4a54fc8c93..7e17eedc4335 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -73,6 +73,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
"compiler-impl",
"debugger-impl",
"dom-impl",
+ "duplicates-analysis",
"execution-impl",
"external-system-impl",
"idea-ui",
@@ -242,7 +243,6 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
module("IntelliLang")
module("IntelliLang-java")
module("IntelliLang-xml")
- module("IntelliLang-javaee")
}
jar("intellilang-jps-plugin.jar") {
module("intellilang-jps-plugin")
@@ -262,7 +262,7 @@ public def layoutCommunityPlugins(String home) {
layoutCloud()
dir("plugins") {
- def simplePlugins = ["commander", "copyright", "java-i18n", "hg4idea", "github"] //, "tasks-time-tracking"]
+ def simplePlugins = ["commander", "copyright", "java-i18n", "hg4idea", "github", "typeMigration"] //, "tasks-time-tracking"]
simplePlugins.each {
layoutPlugin it
@@ -342,10 +342,6 @@ public def layoutCommunityPlugins(String home) {
}
layoutPlugin("gradle") {
- jar("gradle.jar") {
- module("gradle")
- }
-
jar("gradle-tooling-extension-api.jar") {
module("gradle-tooling-extension-api")
}
@@ -370,10 +366,6 @@ public def layoutCommunityPlugins(String home) {
include(name: "ini4j*.jar")
exclude(name: "ini4j*sources.jar")
}
- fileset(dir: "$home/plugins/git4idea/lib/jgit") {
- include(name: "org.eclipse.jgit*.jar")
- exclude(name: "*.zip")
- }
}
layoutPlugin("svn4idea") {
@@ -463,6 +455,7 @@ public def layoutCommunityPlugins(String home) {
module("groovy-psi") {
exclude(name: "standardDsls/**")
}
+ module("structuralsearch-groovy")
}
//layout of groovy jars must be consistent with GroovyBuilder.getGroovyRtRoot method
jar("groovy-jps-plugin.jar") {
@@ -521,14 +514,58 @@ public def layoutCommunityPlugins(String home) {
// }
layoutPlugin("terminal") {
- jar("terminal.jar") {
- module("terminal")
- }
fileset(dir: "$home/plugins/terminal/lib") {
include(name: "*.jar")
include(name: "*.in")
}
}
+
+ pluginDir("coverage") {
+ dir("lib") {
+ jar("coverage.jar") {
+ noResources("coverage-common")
+ noResources("coverage")
+ }
+
+ jar("coverage_rt.jar") {
+ noResources("coverage_rt")
+ }
+
+ jar("resources_en.jar") {
+ module("coverage-common") {
+ patternset(refid: "resources.included")
+ }
+ module("coverage") {
+ patternset(refid: "resources.included")
+ }
+ }
+
+ fileset(dir: "${home}/plugins/coverage-common/lib") {
+ exclude(name: "finder.jar")
+ exclude(name: "**/coverage-src.zip")
+ }
+
+ fileset(dir: "${home}/plugins/coverage/lib", excludes: "**/jacoco_src.zip")
+ }
+ }
+
+ pluginDir("structuralsearch") {
+ dir("lib") {
+ jar("structuralsearch.jar") {
+ module("structuralsearch")
+ module("structuralsearch-java")
+ }
+ }
+ }
+
+ pluginDir("java-decompiler") {
+ dir("lib") {
+ jar("java-decompiler.jar") {
+ module("java-decompiler")
+ }
+ fileset(file: "$home/plugins/java-decompiler/lib/fernflower.jar")
+ }
+ }
}
}
@@ -816,7 +853,7 @@ def layoutJps(String home, String targetDir, String buildNumber, Closure additio
include(name: "jdom.jar")
include(name: "jna.jar")
include(name: "trove4j.jar")
- include(name: "asm4-all.jar")
+ include(name: "asm-all.jar")
include(name: "nanoxml-*.jar")
include(name: "protobuf-*.jar")
include(name: "cli-parser-*.jar")
@@ -856,8 +893,12 @@ def layout_core(String home, String target) {
module("annotations")
}
+ jar("intellij-core-analysis-api.jar") {
+ analysisApiModules.each { module it; }
+ }
+
fileset(dir: "$home/lib") {
- include(name: "guava-14.0.1.jar")
+ include(name: "guava-17.0.jar")
include(name: "picocontainer.jar")
include(name: "trove4j.jar")
include(name: "asm.jar")
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
index 2e9691ea10f3..eaeb82e1c4b4 100644
--- a/build/scripts/libLicenses.gant
+++ b/build/scripts/libLicenses.gant
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -152,7 +152,7 @@ libraryLicense(name: "Alloy L&F", libraryName: "alloy.jar", version: "1.4.4", li
libraryLicense(name: "Ant", version: "1.7", license: "Apache 2.0", url: "http://ant.apache.org/", licenseUrl: "http://ant.apache.org/license.html")
libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm4", version: "4.0", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
-libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm5", version: "5.0.1", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
+libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm5", version: "5.0.3 (with patches by JetBrains)", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm-tools", version: "4.0", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://svn.jetbrains.org/idea/Trunk/bundled/WebServices/resources/lib/axis-1.4.0/axis.LICENSE")
libraryLicense(name: "CGLib", libraryName: "CGLIB", version: "2.2.2", license: "Apache", url: "http://cglib.sourceforge.net/", licenseUrl: "http://www.apache.org/foundation/licence-FAQ.html")
@@ -177,9 +177,8 @@ libraryLicense(name: "DTDParser", version: "1.13", license: "LGPL", url: "http:/
libraryLicense(name: "Gant", version: "1.9.8", libraryName: "gant_groovy2.0-1.9.8.jar", license: "Apache 2.0", url: "http://gant.codehaus.org/", licenseUrl: "http://gant.codehaus.org/Licence")
libraryLicense(name: "sqljet", version: "bundled with SVNKit", libraryName: "sqljet.jar", license: "link (commercial license)", url: "http://sqljet.com", licenseUrl: "http://svnkit.com/license.html")
libraryLicense(name: "svnkit-javahl", version: "bundled with SVNKit", libraryName: "svnkit-javahl.jar", license: "link (commercial license)", url: "http://www.svnkit.com/", licenseUrl: "http://svnkit.com/license.html")
-libraryLicense(name: "javahl", version: "1.7.2", libraryName: "javahl.jar", license: "Apache", url: "http://subversion.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Antlr", libraryName: "antlr.jar", version: "3.4", license: "BSD", url: "http://www.antlr.org", licenseUrl: "http://www.antlr.org/license.html")
-libraryLicense(name: "Guava", version: "14.0.1", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html")
+libraryLicense(name: "Guava", version: "17.0", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html")
libraryLicense(name: "Guava", libraryName: "guava-tools", version: "14.0.1", license: "Apache 2.0", url: "http://code.google.com/p/guava-libraries/", licenseUrl: "http://ant.apache.org/license.html")
libraryLicense(name: "Groovy", version: "2.2.1", license: "Apache 2.0", url: "http://groovy.codehaus.org/")
libraryLicense(name: "Gson", version: "2.2.4", libraryName: "gson", license: "Apache 2.0", url: "http://code.google.com/p/google-gson/")
@@ -191,7 +190,6 @@ libraryLicense(name: "Jaxen", version: "", license: "modified Apache", url: "htt
libraryLicense(name: "JavaHelp", version: "2.0_02", license: "included as license/javahelp_license.html in IntelliJ IDEA distribution", url: "http://java.sun.com/products/javahelp/")
libraryLicense(name: "JCIP Annotations", libraryName: "jcip", license: "Creative Commons Attribution License", url: "http://www.jcip.net", licenseUrl: "http://creativecommons.org/licenses/by/2.5")
libraryLicense(name: "JDOM", version: "1.1 (with patches by JetBrains)", license: "modified Apache", url: "http://www.jdom.org/", licenseUrl: "http://www.jdom.org/docs/faq.html#a0030")
-libraryLicense(name: "jgit-2.1.0", version: "2.1.0.201209190230", license: "EDL/BSD", url: "http://www.eclipse.org/jgit/", licenseUrl: "http://www.eclipse.org/org/documents/edl-v10.php", attachedTo: "git4idea")
libraryLicense(name: "javawriter", libraryName: "javawriter", license: "Apache 2.0", url: "https://github.com/square/javawriter")
libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "1.1-preview 2006-05-04 11:55:37", license: "BSD ", url: "http://www.jgoodies.com/freeware/forms/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
libraryLicense(name: "JGoodies Looks", libraryName: "jgoodies-looks", version: "2.4.2", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html")
@@ -252,7 +250,7 @@ libraryLicense(name: "XML-RPC", libraryName: "XmlRPC", version: "2.0", license:
libraryLicense(name: "XStream", version: "1.4.3", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
-libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Alpha2", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
+libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Beta1", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "2.22", license: "New BSD License", url: "https://github.com/EsotericSoftware/kryo", licenseUrl: "https://github.com/EsotericSoftware/kryo/blob/master/license.txt")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "0.3", license: "Apache 2.0", url: "https://github.com/dain/snappy", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.0.14", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
@@ -278,7 +276,10 @@ libraryLicense(name: "ANTLR 4 Runtime", libraryName: "antlr-runtime-4.1.jar", ve
libraryLicense(name: "minlog", libraryName: "minlog-1.2.jar", version: "1.2", license: "BSD", url: "https://github.com/EsotericSoftware/minlog", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
libraryLicense(name: "ReflectASM", libraryName: "reflectasm-1.0.7.jar", version: "1.0.7", license: "BSD", url: "https://github.com/EsotericSoftware/reflectasm", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
libraryLicense(name: "Objenesis", libraryName: "objenesis-1.2.jar", version: "1.2", license: "Apache 2.0", url: "http://objenesis.org/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
+jetbrainsLibrary("Coverage")
+jetbrainsLibrary("CoverageReport")
jetbrainsLibrary("JPS")
jetbrainsLibrary("Maven Embedder")
jetbrainsLibrary("tcServiceMessages")
jetbrainsLibrary("optimizedFileManager.jar")
+jetbrainsLibrary("fernflower.jar")
diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index 5853eaeea32a..580d63d0bb53 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -231,6 +231,7 @@ binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
binding.setVariable("commonJvmArgs", {
return [
"-ea",
+ "-server",
"-Didea.home.path=$home",
"-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
"-XX:+HeapDumpOnOutOfMemoryError",
@@ -316,7 +317,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
}
ant.copy(todir: path) {
- fileset(dir: "$ch/build/conf/mac")
+ fileset(dir: "$ch/build/conf/mac/Contents")
}
ant.tstamp() {
@@ -326,22 +327,19 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase()
String helpId = args.help_id != null ? args.help_id : "IJ"
String icns = "idea.icns"
- String helpIcns = "$path/Contents/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
+ String helpIcns = "$path/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
if (args.icns != null) {
- ant.delete(file: "$path/Contents/Resources/idea.icns")
- ant.copy(file: args.icns, todir: "$path/Contents/Resources")
+ ant.delete(file: "$path/Resources/idea.icns")
+ ant.copy(file: args.icns, todir: "$path/Resources")
ant.copy(file: args.icns, tofile: helpIcns)
icns = new File((String)args.icns).getName();
} else {
- ant.copy(file: "$path/Contents/Resources/idea.icns", tofile: helpIcns)
+ ant.copy(file: "$path/Resources/idea.icns", tofile: helpIcns)
}
String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none"
- if (isEap() && !args.mac_no_yjp) {
- vmOptions += " ${yjpOptions(args.system_selector)}"
- }
String minor = p("component.version.minor")
String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"
@@ -360,9 +358,13 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
}
new File("$path/bin/idea.properties").text = effectiveProperties.toString()
- new File("$path/bin/idea.vmoptions").text = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
+ String ideaVmOptions = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
+ if (isEap() && !args.mac_no_yjp) {
+ ideaVmOptions += " ${yjpOptions(args.system_selector)}"
+ }
+ new File("$path/bin/idea.vmoptions").text = ideaVmOptions
- String classPath = classPathLibs.collect {"\$APP_PACKAGE/lib/${it}" }.join(":")
+ String classPath = classPathLibs.collect {"\$APP_PACKAGE/Contents/lib/${it}" }.join(":")
String archs = """
<key>LSArchitecturePriority</key>
@@ -395,7 +397,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
"""
}
- ant.replace(file: "$path/Contents/Info.plist") {
+ ant.replace(file: "$path/Info.plist") {
replacefilter(token: "@@build@@", value: args.buildNumber)
replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, ""))
replacefilter(token: "@@executable@@", value: executable)
@@ -417,7 +419,7 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
}
if (executable != "idea") {
- ant.move(file: "$path/Contents/MacOS/idea", tofile: "$path/Contents/MacOS/$executable")
+ ant.move(file: "$path/MacOS/idea", tofile: "$path/MacOS/$executable")
}
ant.replace(file: "$path/bin/inspect.sh") {
@@ -725,7 +727,7 @@ binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths,
exclude(name: "bin/*.py")
exclude(name: "bin/fsnotifier")
exclude(name: "bin/restarter")
- exclude(name: "Contents/MacOS/*")
+ exclude(name: "MacOS/*")
extraBins.each {
exclude(name: it)
}
@@ -739,7 +741,7 @@ binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths,
include(name: "bin/*.py")
include(name: "bin/fsnotifier")
include(name: "bin/restarter")
- include(name: "Contents/MacOS/*")
+ include(name: "MacOS/*")
extraBins.each {
include(name: it)
}
@@ -914,3 +916,28 @@ binding.setVariable("reassignAltClickToMultipleCarets", {String communityHome ->
patchedKeymapFile = new File("${paths.sandbox}/classes/production/platform-resources/idea/Keymap_Default.xml")
patchedKeymapFile.write(defaultKeymapContent)
})
+
+// modules used in Upsource and in Kotlin as an API to IDEA
+binding.setVariable("analysisApiModules", [
+ "analysis-api",
+ "boot",
+ "core-api",
+ "duplicates-analysis",
+ "editor-ui-api",
+ "editor-ui-ex",
+ "extensions",
+ "indexing-api",
+ "java-analysis-api",
+ "java-indexing-api",
+ "java-psi-api",
+ "java-structure-view",
+ "jps-model-api",
+ "jps-model-serialization",
+ "projectModel-api",
+ "structure-view-api",
+ "util",
+ "util-rt",
+ "xml-analysis-api",
+ "xml-psi-api",
+ "xml-structure-view-api",
+])
diff --git a/community-main.iml b/community-main.iml
index a56cb309b19f..d46c797fbaeb 100644
--- a/community-main.iml
+++ b/community-main.iml
@@ -104,6 +104,11 @@
<orderEntry type="module" module-name="community-tests" scope="TEST" />
<orderEntry type="module" module-name="google-cloud-tools" />
<orderEntry type="module" module-name="jira" />
+ <orderEntry type="module" module-name="java-decompiler" />
+ <orderEntry type="module" module-name="structuralsearch" />
+ <orderEntry type="module" module-name="structuralsearch-java" />
+ <orderEntry type="module" module-name="structuralsearch-tests" scope="TEST" />
+ <orderEntry type="module" module-name="structuralsearch-groovy" />
</component>
</module>
diff --git a/community-tests/src/tests/testGroups.properties b/community-tests/src/tests/testGroups.properties
index 5941b527969f..8aa168501144 100644
--- a/community-tests/src/tests/testGroups.properties
+++ b/community-tests/src/tests/testGroups.properties
@@ -3,3 +3,6 @@
org.jetbrains.idea.svn.*
org.jetbrains.idea.svn16.*
com.intellij.util.net.ssl.*
+
+[DECOMPILER_TESTS]
+org.jetbrains.java.decompiler.*
diff --git a/images/src/META-INF/ImagesPlugin.xml b/images/src/META-INF/ImagesPlugin.xml
index 120b85c9bfc2..2c234ffe0e34 100644
--- a/images/src/META-INF/ImagesPlugin.xml
+++ b/images/src/META-INF/ImagesPlugin.xml
@@ -70,6 +70,7 @@
<keyboard-shortcut first-keystroke="control DIVIDE" keymap="$default"/>
<keyboard-shortcut first-keystroke="control SLASH" keymap="$default"/>
</action>
+ <reference id="ShowColorPicker" />
</group>
<group id="Images.EditorPopupMenu">
<reference id="CutCopyPasteGroup"/>
@@ -85,7 +86,6 @@
<separator/>
<reference id="VersionControlsGroup"/>
<separator/>
- <reference id="ShowColorPicker" />
<reference id="Images.EditExternally"/>
<reference id="ExternalToolsGroup"/>
</group>
diff --git a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java
index dff37a26ba31..f3d920d3d3c3 100644
--- a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java
+++ b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java
@@ -24,9 +24,11 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
+import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLayeredPane;
+import com.intellij.ui.components.Magnificator;
import com.intellij.util.ui.UIUtil;
import org.intellij.images.ImagesBundle;
import org.intellij.images.editor.ImageDocument;
@@ -37,6 +39,7 @@ import org.intellij.images.options.*;
import org.intellij.images.ui.ImageComponent;
import org.intellij.images.ui.ImageComponentDecorator;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -49,6 +52,7 @@ import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
+import java.util.Locale;
/**
* Image editor UI
@@ -142,6 +146,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(toolbarPanel, BorderLayout.WEST);
infoLabel = new JLabel((String)null, SwingConstants.RIGHT);
+ infoLabel.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 2));
topPanel.add(infoLabel, BorderLayout.EAST);
add(topPanel, BorderLayout.NORTH);
@@ -159,7 +164,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
if (format == null) {
format = ImagesBundle.message("unknown.format");
} else {
- format = format.toUpperCase();
+ format = format.toUpperCase(Locale.ENGLISH);
}
VirtualFile file = editor.getFile();
infoLabel.setText(
@@ -191,12 +196,24 @@ final class ImageEditorUI extends JPanel implements DataProvider {
return zoomModel;
}
- private static final class ImageContainerPane extends JBLayeredPane {
+ private final class ImageContainerPane extends JBLayeredPane {
private final ImageComponent imageComponent;
- public ImageContainerPane(ImageComponent imageComponent) {
+ public ImageContainerPane(final ImageComponent imageComponent) {
this.imageComponent = imageComponent;
add(imageComponent);
+
+ putClientProperty(Magnificator.CLIENT_PROPERTY_KEY, new Magnificator() {
+ @Override
+ public Point magnify(double scale, Point at) {
+ Point locationBefore = imageComponent.getLocation();
+ ImageZoomModel model = editor.getZoomModel();
+ double factor = model.getZoomFactor();
+ model.setZoomFactor(scale * factor);
+ return new Point(((int)((at.x - Math.max(scale > 1.0 ? locationBefore.x : 0, 0)) * scale)),
+ ((int)((at.y - Math.max(scale > 1.0 ? locationBefore.y : 0, 0)) * scale)));
+ }
+ });
}
private void centerComponents() {
@@ -217,7 +234,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
}
@Override
- protected void paintComponent(Graphics g) {
+ protected void paintComponent(@NotNull Graphics g) {
super.paintComponent(g);
if (UIUtil.isUnderDarcula()) {
g.setColor(UIUtil.getControlColor().brighter());
@@ -322,7 +339,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
}
private class DocumentChangeListener implements ChangeListener {
- public void stateChanged(ChangeEvent e) {
+ public void stateChanged(@NotNull ChangeEvent e) {
ImageDocument document = imageComponent.getDocument();
BufferedImage value = document.getValue();
@@ -337,7 +354,7 @@ final class ImageEditorUI extends JPanel implements DataProvider {
}
private class FocusRequester extends MouseAdapter {
- public void mousePressed(MouseEvent e) {
+ public void mousePressed(@NotNull MouseEvent e) {
requestFocus();
}
}
diff --git a/java/compiler/forms-compiler/forms-compiler.iml b/java/compiler/forms-compiler/forms-compiler.iml
index 1a851bf7859f..7b957e27ad00 100644
--- a/java/compiler/forms-compiler/forms-compiler.iml
+++ b/java/compiler/forms-compiler/forms-compiler.iml
@@ -10,7 +10,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="module" module-name="forms_rt" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit3" level="project" />
<orderEntry type="library" name="jgoodies-forms" level="project" />
<orderEntry type="module" module-name="instrumentation-util" exported="" />
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java
index 22ab2a7f8bd6..62f2eef28ff4 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java
@@ -19,10 +19,10 @@ import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.lw.*;
import com.intellij.uiDesigner.shared.BorderType;
-import org.jetbrains.asm4.*;
-import org.jetbrains.asm4.Label;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.*;
+import org.jetbrains.org.objectweb.asm.Label;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
import javax.swing.border.Border;
@@ -235,7 +235,7 @@ public class AsmCodeGenerator {
private final boolean myExplicitSetupCall;
public FormClassVisitor(final ClassVisitor cv, final boolean explicitSetupCall) {
- super(Opcodes.ASM4, cv);
+ super(Opcodes.ASM5, cv);
myExplicitSetupCall = explicitSetupCall;
}
@@ -307,7 +307,7 @@ public class AsmCodeGenerator {
if (haveCustomCreateComponents && myHaveCreateComponentsMethod) {
generator.visitVarInsn(Opcodes.ALOAD, 0);
int opcode = myCreateComponentsAccess == Opcodes.ACC_PRIVATE ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL;
- generator.visitMethodInsn(opcode, myClassName, CREATE_COMPONENTS_METHOD_NAME, "()V");
+ generator.visitMethodInsn(opcode, myClassName, CREATE_COMPONENTS_METHOD_NAME, "()V", false);
}
buildSetupMethod(generator);
@@ -902,7 +902,7 @@ public class AsmCodeGenerator {
private boolean mySuperCalled = false;
public FormConstructorVisitor(final MethodVisitor mv, final String className, final String superName) {
- super(Opcodes.ASM4, mv);
+ super(Opcodes.ASM5, mv);
myClassName = className;
mySuperName = superName;
}
@@ -914,7 +914,7 @@ public class AsmCodeGenerator {
super.visitFieldInsn(opcode, owner, name, desc);
}
- public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+ public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, boolean itf) {
if (opcode == Opcodes.INVOKESPECIAL && name.equals(CONSTRUCTOR_NAME)) {
if (owner.equals(myClassName)) {
callsSelfConstructor = true;
@@ -929,7 +929,7 @@ public class AsmCodeGenerator {
else if (mySuperCalled) {
callSetupUI();
}
- super.visitMethodInsn(opcode, owner, name, desc);
+ super.visitMethodInsn(opcode, owner, name, desc, itf);
}
public void visitJumpInsn(final int opcode, final Label label) {
@@ -942,7 +942,7 @@ public class AsmCodeGenerator {
private void callSetupUI() {
if (!mySetupCalled) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, myClassName, SETUP_METHOD_NAME, "()V");
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, myClassName, SETUP_METHOD_NAME, "()V", false);
mySetupCalled = true;
}
}
@@ -959,7 +959,7 @@ public class AsmCodeGenerator {
private boolean myExplicitSetupCall = false;
public FirstPassClassVisitor() {
- super(Opcodes.ASM4, new ClassVisitor(Opcodes.ASM4){});
+ super(Opcodes.ASM5, new ClassVisitor(Opcodes.ASM5){});
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
@@ -975,10 +975,10 @@ public class AsmCodeGenerator {
private class FirstPassConstructorVisitor extends MethodVisitor {
public FirstPassConstructorVisitor() {
- super(Opcodes.ASM4, new MethodVisitor(Opcodes.ASM4){});
+ super(Opcodes.ASM5, new MethodVisitor(Opcodes.ASM5){});
}
- public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (name.equals(SETUP_METHOD_NAME)) {
myExplicitSetupCall = true;
}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java
index 86b6e42c09b2..7dc880559e17 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java
@@ -17,9 +17,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.lw.LwComponent;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java
index 8443020bfc37..6e0161c2edff 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java
@@ -16,9 +16,9 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.ColorDescriptor;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java
index 7a0fd4f9ec86..632c4ef4008b 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java
@@ -15,9 +15,9 @@
*/
package com.intellij.uiDesigner.compiler;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java
index 720d4c01582b..27d354c6898e 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java
@@ -16,8 +16,8 @@
package com.intellij.uiDesigner.compiler;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
/**
* @author yole
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java
index 34a41d89eb22..a2448632656c 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java
@@ -18,9 +18,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java
index f15a8d4c314f..a8306b91d6d4 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java
@@ -19,9 +19,9 @@ import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.uiDesigner.lw.FontDescriptor;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java
index a30061f0c784..f83d2d54d15b 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java
@@ -21,10 +21,10 @@ import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
-import org.jetbrains.asm4.Opcodes;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java
index 711d2c44726e..2435e902e5c5 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java
@@ -18,9 +18,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.core.Spacer;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java
index 954f166bb42e..86839ec49203 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java
@@ -19,9 +19,9 @@ import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
/**
* @author yole
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java
index c435704a0144..d966a6838b2d 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java
@@ -16,9 +16,9 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.IconDescriptor;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java
index fb516ca430b3..347eb205a849 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java
@@ -15,9 +15,9 @@
*/
package com.intellij.uiDesigner.compiler;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java
index f5d2594c3b99..e3e4e7953ff8 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java
@@ -17,10 +17,10 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
-import org.jetbrains.asm4.Opcodes;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java
index 93ed130f6fbb..01c14d9782c6 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java
@@ -16,9 +16,9 @@
package com.intellij.uiDesigner.compiler;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
/**
* @author yole
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java
index b3c1aeb94d87..16cb0790f8f6 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java
@@ -18,7 +18,7 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
import java.io.IOException;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java
index fb86b0833ddf..2a559d6747b6 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java
@@ -15,9 +15,9 @@
*/
package com.intellij.uiDesigner.compiler;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import java.awt.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java
index 68725007cf43..061308c51c83 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java
@@ -17,9 +17,9 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java
index 5836b6ca29d7..388fa192605f 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java
@@ -18,9 +18,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
/**
* Layout code generator shared between BorderLayout and CardLayout.
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java
index 28533f4776b4..765815682311 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java
@@ -17,9 +17,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwSplitPane;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java
index 4438fd0c4f76..94dffc379ed0 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java
@@ -20,12 +20,12 @@ import com.intellij.uiDesigner.core.SupportCode;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
import com.intellij.uiDesigner.lw.StringDescriptor;
-import org.jetbrains.asm4.Label;
-import org.jetbrains.asm4.MethodVisitor;
-import org.jetbrains.asm4.Opcodes;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Label;
+import org.jetbrains.org.objectweb.asm.MethodVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
import java.io.IOException;
@@ -164,7 +164,7 @@ public class StringPropertyCodeGenerator extends PropertyCodeGenerator implement
mv.visitCode();
mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
mv.visitInsn(DUP);
- mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V", false);
mv.visitVarInsn(ASTORE, 3);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 4);
@@ -178,19 +178,19 @@ public class StringPropertyCodeGenerator extends PropertyCodeGenerator implement
mv.visitLabel(l0);
mv.visitVarInsn(ILOAD, 7);
mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I", false);
Label l1 = new Label();
mv.visitJumpInsn(IF_ICMPGE, l1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
mv.visitIntInsn(BIPUSH, 38);
Label l2 = new Label();
mv.visitJumpInsn(IF_ICMPNE, l2);
mv.visitIincInsn(7, 1);
mv.visitVarInsn(ILOAD, 7);
mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I", false);
Label l3 = new Label();
mv.visitJumpInsn(IF_ICMPNE, l3);
mv.visitJumpInsn(GOTO, l1);
@@ -199,42 +199,42 @@ public class StringPropertyCodeGenerator extends PropertyCodeGenerator implement
mv.visitJumpInsn(IFNE, l2);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
mv.visitIntInsn(BIPUSH, 38);
mv.visitJumpInsn(IF_ICMPEQ, l2);
mv.visitInsn(ICONST_1);
mv.visitVarInsn(ISTORE, 4);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
mv.visitVarInsn(ISTORE, 5);
mv.visitVarInsn(ALOAD, 3);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "length", "()I");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "length", "()I", false);
mv.visitVarInsn(ISTORE, 6);
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(C)Ljava/lang/StringBuffer;");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C", false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(C)Ljava/lang/StringBuffer;", false);
mv.visitInsn(POP);
mv.visitIincInsn(7, 1);
mv.visitJumpInsn(GOTO, l0);
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 3);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
- mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setText", "(Ljava/lang/String;)V");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setText", "(Ljava/lang/String;)V", false);
mv.visitVarInsn(ILOAD, 4);
Label l4 = new Label();
mv.visitJumpInsn(IFEQ, l4);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 5);
- mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, setMnemonicMethodName, "(C)V");
+ mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, setMnemonicMethodName, "(C)V", false);
if (myHaveSetDisplayedMnemonicIndex) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 6);
- mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setDisplayedMnemonicIndex", "(I)V");
+ mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setDisplayedMnemonicIndex", "(I)V", false);
}
mv.visitLabel(l4);
mv.visitInsn(RETURN);
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java
index ee867bf21a56..94d6093b05cd 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java
@@ -17,9 +17,9 @@ package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwTabbedPane;
-import org.jetbrains.asm4.Type;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.Type;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
import javax.swing.*;
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java
index b90a778cbed9..53feecc7d09e 100644
--- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java
@@ -17,8 +17,8 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
-import org.jetbrains.asm4.commons.GeneratorAdapter;
-import org.jetbrains.asm4.commons.Method;
+import org.jetbrains.org.objectweb.asm.commons.GeneratorAdapter;
+import org.jetbrains.org.objectweb.asm.commons.Method;
/**
* @author yole
diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml
index 8a42f6d5b8ab..08d3ca179fc0 100644
--- a/java/compiler/impl/compiler-impl.iml
+++ b/java/compiler/impl/compiler-impl.iml
@@ -16,7 +16,7 @@
<orderEntry type="library" name="Trove4j" level="project" />
<orderEntry type="module" module-name="java-runtime" />
<orderEntry type="module" module-name="instrumentation-util" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="library" name="Eclipse" level="project" />
<orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="lang-impl" />
diff --git a/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java b/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java
index 61d1e05e6663..ce315be023ad 100644
--- a/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java
+++ b/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java
@@ -27,7 +27,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.ClassUtil;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.asm4.ClassWriter;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
/**
* @author yole
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java
index c7596e5cbaa4..f0c390d31459 100644
--- a/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java
@@ -19,7 +19,6 @@ import com.intellij.history.LocalHistory;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileStatusNotification;
@@ -31,7 +30,9 @@ public class CompileProjectAction extends CompileActionBase {
protected void doAction(DataContext dataContext, final Project project) {
CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() {
public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
- if (aborted) return;
+ if (aborted || project.isDisposed()) {
+ return;
+ }
String text = getTemplatePresentation().getText();
LocalHistory.getInstance().putSystemLabel(project, errors == 0
diff --git a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java
index 5a8539629fb5..d96d6dfe0f83 100644
--- a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java
@@ -40,7 +40,7 @@ public class MethodsChainsCompletionContributor extends CompletionContributor {
private final static int FILTER_RATIO = 10;
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getInvocationCount() >= INVOCATIONS_THRESHOLD &&
ClassFilesIndexFeaturesHolder.getInstance(parameters.getPosition().getProject())
.enableFeatureIfNeed(ClassFilesIndexFeature.METHOD_CHAINS_COMPLETION)) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/context/TargetType.java b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/context/TargetType.java
index 6c6897a21665..16c7f309a6f4 100644
--- a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/context/TargetType.java
+++ b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/context/TargetType.java
@@ -15,14 +15,11 @@
*/
package com.intellij.compiler.classFilesIndex.chainsSearch.context;
-import com.intellij.psi.*;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiType;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.Type;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
/**
* @author Dmitry Batkovich
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
index 17e2dfed1dee..c9e9ce31020a 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
@@ -24,6 +24,7 @@ package com.intellij.compiler.impl;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerMessageImpl;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.ProblemsView;
import com.intellij.compiler.progress.CompilerTask;
import com.intellij.execution.impl.ExecutionManagerImpl;
import com.intellij.openapi.application.ApplicationManager;
@@ -156,7 +157,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myTask.addMessage(msg);
}
if (myShouldUpdateProblemsView && msg.getCategory() == CompilerMessageCategory.ERROR) {
- ProblemsViewImpl.SERVICE.getInstance(myProject).addMessage(msg, mySessionId);
+ ProblemsView.SERVICE.getInstance(myProject).addMessage(msg, mySessionId);
}
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index f50fa0ad68bb..46584ef9c8bf 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -261,7 +261,7 @@ public class CompileDriver {
@Override
public void sessionTerminated(final UUID sessionId) {
if (compileContext.shouldUpdateProblemsView()) {
- final ProblemsView view = ProblemsViewImpl.SERVICE.getInstance(myProject);
+ final ProblemsView view = ProblemsView.SERVICE.getInstance(myProject);
view.clearProgress();
view.clearOldMessages(compileContext.getCompileScope(), compileContext.getSessionId());
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
index 216f03b750d6..68dce61619cb 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
@@ -157,9 +157,10 @@ public class ProblemsViewImpl extends ProblemsView{
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- final ToolWindowManager twManager = ToolWindowManager.getInstance(myProject);
- final ToolWindow tw = twManager.getToolWindow(PROBLEMS_TOOLWINDOW_ID);
- tw.setIcon(active ? myActiveIcon : myPassiveIcon);
+ final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
+ if (tw != null) {
+ tw.setIcon(active ? myActiveIcon : myPassiveIcon);
+ }
}
}, myProject.getDisposed());
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
index 710baf36f29b..395a7a711398 100644
--- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
+++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -120,15 +120,18 @@ public class CompilerTask extends Task.Backgroundable {
mySessionId = sessionId;
}
+ @Override
public String getProcessId() {
return "compilation";
}
+ @NotNull
@Override
public DumbModeAction getDumbModeAction() {
return DumbModeAction.WAIT;
}
+ @Override
public boolean shouldStartInBackground() {
return true;
}
@@ -137,6 +140,7 @@ public class CompilerTask extends Task.Backgroundable {
return myIndicator;
}
+ @Override
@Nullable
public NotificationInfo getNotificationInfo() {
return new NotificationInfo(myErrorCount > 0? "Compiler (errors)" : "Compiler (success)", "Compilation Finished", myErrorCount + " Errors, " + myWarningCount + " Warnings", true);
@@ -144,6 +148,7 @@ public class CompilerTask extends Task.Backgroundable {
private CloseListener myCloseListener;
+ @Override
public void run(@NotNull final ProgressIndicator indicator) {
myIndicator = indicator;
@@ -197,6 +202,7 @@ public class CompilerTask extends Task.Backgroundable {
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
final Project project = myProject;
if (project == null || project.isDisposed()) {
@@ -218,12 +224,14 @@ public class CompilerTask extends Task.Backgroundable {
if (!(indicator instanceof ProgressIndicatorEx)) return;
((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
+ @Override
public void cancel() {
super.cancel();
closeUI();
stopAppIconProgress();
}
+ @Override
public void stop() {
super.stop();
if (!isCanceled()) {
@@ -234,6 +242,7 @@ public class CompilerTask extends Task.Backgroundable {
private void stopAppIconProgress() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
AppIcon appIcon = AppIcon.getInstance();
if (appIcon.hideProgress(myProject, APP_ICON_ID)) {
@@ -249,26 +258,31 @@ public class CompilerTask extends Task.Backgroundable {
});
}
+ @Override
public void setText(final String text) {
super.setText(text);
updateProgressText();
}
+ @Override
public void setText2(final String text) {
super.setText2(text);
updateProgressText();
}
+ @Override
public void setFraction(final double fraction) {
super.setFraction(fraction);
updateProgressText();
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
AppIcon.getInstance().setProgress(myProject, APP_ICON_ID, AppIconScheme.Progress.BUILD, fraction, true);
}
});
}
+ @Override
protected void onProgressChange() {
prepareMessageView();
}
@@ -301,6 +315,7 @@ public class CompilerTask extends Task.Backgroundable {
final Window window = getWindow();
final ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL;
ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
public void run() {
if (!myProject.isDisposed()) {
openMessageView();
@@ -409,10 +424,12 @@ public class CompilerTask extends Task.Backgroundable {
);
myErrorTreeView.setProcessController(new NewErrorTreeViewPanel.ProcessController() {
+ @Override
public void stopProcess() {
cancel();
}
+ @Override
public boolean isProcessStopped() {
return !myIndicator.isRunning();
}
@@ -485,6 +502,7 @@ public class CompilerTask extends Task.Backgroundable {
ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL;
final Application application = ApplicationManager.getApplication();
application.invokeLater(new Runnable() {
+ @Override
public void run() {
synchronized (myMessageViewLock) {
if (myErrorTreeView != null) {
@@ -508,6 +526,7 @@ public class CompilerTask extends Task.Backgroundable {
return null;
}
+ @Override
public boolean isHeadless() {
return myHeadlessMode && !myForceAsyncExecution;
}
@@ -542,6 +561,7 @@ public class CompilerTask extends Task.Backgroundable {
private boolean myIsApplicationExitingOrProjectClosing = false;
private boolean myUserAcceptedCancel = false;
+ @Override
public boolean canCloseProject(final Project project) {
assert project != null;
if (!project.equals(myProject)) {
@@ -561,6 +581,7 @@ public class CompilerTask extends Task.Backgroundable {
final MessageBusConnection connection = project.getMessageBus().connect();
connection.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusAdapter() {
+ @Override
public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
connection.disconnect();
ProjectUtil.closeAndDispose(project);
@@ -578,6 +599,7 @@ public class CompilerTask extends Task.Backgroundable {
contentManager.addContentManagerListener(this);
}
+ @Override
public void contentRemoved(ContentManagerEvent event) {
if (event.getContent() == myContent) {
synchronized (myMessageViewLock) {
@@ -598,6 +620,7 @@ public class CompilerTask extends Task.Backgroundable {
}
}
+ @Override
public void contentRemoveQuery(ContentManagerEvent event) {
if (event.getContent() == myContent) {
if (!myIndicator.isCanceled() && shouldAskUser()) {
@@ -620,15 +643,18 @@ public class CompilerTask extends Task.Backgroundable {
return !myUserAcceptedCancel && !myIsApplicationExitingOrProjectClosing && myIndicator.isRunning();
}
+ @Override
public void projectOpened(Project project) {
}
+ @Override
public void projectClosed(Project project) {
if (project.equals(myProject) && myContent != null) {
myContentManager.removeContent(myContent, true);
}
}
+ @Override
public void projectClosing(Project project) {
if (project.equals(myProject)) {
myIsApplicationExitingOrProjectClosing = true;
@@ -643,6 +669,7 @@ public class CompilerTask extends Task.Backgroundable {
myDisplayName = displayName;
}
+ @Override
public String toString() {
return myDisplayName;
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index cb01abba6015..c32d9ecda313 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -611,7 +611,7 @@ public class BuildManager implements ApplicationComponent{
data = new ProjectData(new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE));
myProjectDataMap.put(projectPath, data);
}
- if (isRebuild) {
+ if (isRebuild || (isAutomake && Registry.is("compiler.automake.force.fs.rescan", false))) {
data.dropChanges();
}
if (IS_UNIT_TEST_MODE) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
index 80c2aaf72fac..e4df975348d9 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +30,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.*;
import com.intellij.util.SmartList;
-import com.intellij.util.cls.ClsUtil;
import com.intellij.util.concurrency.SequentialTaskExecutor;
import io.netty.channel.Channel;
import org.jetbrains.annotations.NotNull;
@@ -38,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.PooledThreadExecutor;
import org.jetbrains.jps.api.CmdlineProtoUtil;
import org.jetbrains.jps.api.CmdlineRemoteProto;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -177,7 +177,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
}
else {
for (final PsiField changedField : changedFields) {
- if (!accessChanged && ClsUtil.isPrivate(accessFlags)) {
+ if (!accessChanged && isPrivate(accessFlags)) {
// optimization: don't need to search, cause may be used only in this class
continue;
}
@@ -291,7 +291,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
private SearchScope getSearchScope(PsiClass aClass, int fieldAccessFlags) {
SearchScope searchScope = GlobalSearchScope.projectScope(myProject);
- if (aClass != null && ClsUtil.isPackageLocal(fieldAccessFlags)) {
+ if (aClass != null && isPackageLocal(fieldAccessFlags)) {
final PsiFile containingFile = aClass.getContainingFile();
if (containingFile instanceof PsiJavaFile) {
final String packageName = ((PsiJavaFile)containingFile).getPackageName();
@@ -308,7 +308,7 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
private static boolean processIdentifiers(PsiSearchHelper helper, @NotNull final PsiElementProcessor<PsiIdentifier> processor, @NotNull final String identifier, @NotNull SearchScope searchScope, short searchContext) {
TextOccurenceProcessor processor1 = new TextOccurenceProcessor() {
@Override
- public boolean execute(PsiElement element, int offsetInElement) {
+ public boolean execute(@NotNull PsiElement element, int offsetInElement) {
return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element);
}
};
@@ -386,4 +386,11 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler {
return null;
}
+ private static boolean isPackageLocal(int flags) {
+ return (Opcodes.ACC_PUBLIC & flags) == 0 && (Opcodes.ACC_PROTECTED & flags) == 0 && (Opcodes.ACC_PRIVATE & flags) == 0;
+ }
+
+ private static boolean isPrivate(int flags) {
+ return (Opcodes.ACC_PRIVATE & flags) != 0;
+ }
}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
index 39f9ec7936a6..3547d3847c25 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -24,10 +24,10 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
-import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser;
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.packaging.artifacts.*;
@@ -67,12 +67,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
private final DefaultPackagingElementResolvingContext myResolvingContext;
private boolean myInsideCommit = false;
private boolean myLoaded;
- private long myModificationCount;
- private final ModificationTracker myModificationTracker = new ModificationTracker() {
- public long getModificationCount() {
- return myModificationCount;
- }
- };
+ private final SimpleModificationTracker myModificationTracker = new SimpleModificationTracker();
private final Map<String, LocalFileSystem.WatchRequest> myWatchedOutputs = new HashMap<String, LocalFileSystem.WatchRequest>();
public ArtifactManagerImpl(Project project) {
@@ -355,7 +350,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
}
myModel.setArtifactsList(allArtifacts);
- myModificationCount++;
+ myModificationTracker.incModificationCount();
final ArtifactListener publisher = myProject.getMessageBus().syncPublisher(TOPIC);
hasChanges = !removed.isEmpty() || !added.isEmpty() || !changed.isEmpty();
ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
@@ -389,7 +384,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
@NotNull
public Artifact addArtifact(@NotNull final String name, @NotNull final ArtifactType type, final CompositePackagingElement<?> root) {
return new WriteAction<Artifact>() {
- protected void run(final Result<Artifact> result) {
+ protected void run(@NotNull final Result<Artifact> result) {
final ModifiableArtifactModel model = createModifiableModel();
final ModifiableArtifact artifact = model.addArtifact(name, type);
if (root != null) {
@@ -413,7 +408,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
final CompositePackagingElement<?> root = model.getOrCreateModifiableArtifact(artifact).getRootElement();
PackagingElementFactory.getInstance().getOrCreateDirectory(root, relativePath).addOrFindChildren(elements);
new WriteAction() {
- protected void run(final Result result) {
+ protected void run(@NotNull final Result result) {
model.commit();
}
}.execute();
diff --git a/java/compiler/instrumentation-util/instrumentation-util.iml b/java/compiler/instrumentation-util/instrumentation-util.iml
index 370070ea380b..5e45b771a830 100644
--- a/java/compiler/instrumentation-util/instrumentation-util.iml
+++ b/java/compiler/instrumentation-util/instrumentation-util.iml
@@ -7,7 +7,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
</component>
</module>
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java
index 3716f4d540ef..02f4ffcd5f37 100644
--- a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java
@@ -1,9 +1,9 @@
package com.intellij.compiler.instrumentation;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.MethodVisitor;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.MethodVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import sun.misc.Resource;
import java.io.*;
@@ -415,7 +415,7 @@ public class InstrumentationClassFinder {
private final List<PseudoMethod> myMethods = new ArrayList<PseudoMethod>();
private V() {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java
index b2f93c5e4603..0d1ec34ea176 100644
--- a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java
@@ -1,6 +1,6 @@
package com.intellij.compiler.instrumentation;
-import org.jetbrains.asm4.ClassWriter;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
/**
* @author Eugene Zhuravlev
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
index af36e512dd26..3bc0dc093fc8 100644
--- a/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
@@ -15,7 +15,7 @@
*/
package com.intellij.compiler.notNullVerification;
-import org.jetbrains.asm4.*;
+import org.jetbrains.org.objectweb.asm.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -50,7 +50,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
private RuntimeException myPostponedError;
private NotNullVerifyingInstrumenter(final ClassVisitor classVisitor, ClassReader reader) {
- super(Opcodes.ASM4, classVisitor);
+ super(Opcodes.ASM5, classVisitor);
myMethodParamNames = getAllParameterNames(reader);
}
@@ -63,7 +63,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
private static Map<String, Map<Integer, String>> getAllParameterNames(ClassReader reader) {
final Map<String, Map<Integer, String>> methodParamNames = new LinkedHashMap<String, Map<Integer, String>>();
- reader.accept(new ClassVisitor(Opcodes.ASM4) {
+ reader.accept(new ClassVisitor(Opcodes.ASM5) {
private String myClassName = null;
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
@@ -106,7 +106,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
final Type returnType = Type.getReturnType(desc);
final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
final Map<Integer, String> paramNames = myMethodParamNames.get(myClassName + '.' + name + desc);
- return new MethodVisitor(Opcodes.ASM4, v) {
+ return new MethodVisitor(Opcodes.ASM5, v) {
private final List<Integer> myNotNullParams = new ArrayList<Integer>();
private int mySyntheticCount = 0;
@@ -118,7 +118,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
AnnotationVisitor av = mv.visitParameterAnnotation(parameter, anno, visible);
if (isReferenceType(args[parameter]) && anno.equals(NOT_NULL_TYPE)) {
myNotNullParams.add(new Integer(parameter));
- av = new AnnotationVisitor(Opcodes.ASM4, av) {
+ av = new AnnotationVisitor(Opcodes.ASM5, av) {
@Override
public void visit(String methodName, Object o) {
if(ANNOTATION_DEFAULT_METHOD.equals(methodName)) {
@@ -144,7 +144,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
AnnotationVisitor av = mv.visitAnnotation(anno, isRuntime);
if (isReferenceType(returnType) && anno.equals(NOT_NULL_TYPE)) {
myIsNotNull = true;
- av = new AnnotationVisitor(Opcodes.ASM4, av) {
+ av = new AnnotationVisitor(Opcodes.ASM5, av) {
@Override
public void visit(String methodName, Object o) {
if(ANNOTATION_DEFAULT_METHOD.equals(methodName)) {
@@ -229,9 +229,9 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
}
//noinspection SpellCheckingInspection
- mv.visitMethodInsn(INVOKESTATIC, STRING_CLASS_NAME, "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
+ mv.visitMethodInsn(INVOKESTATIC, STRING_CLASS_NAME, "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", false);
- mv.visitMethodInsn(INVOKESPECIAL, exceptionClass, CONSTRUCTOR_NAME, EXCEPTION_INIT_SIGNATURE);
+ mv.visitMethodInsn(INVOKESPECIAL, exceptionClass, CONSTRUCTOR_NAME, EXCEPTION_INIT_SIGNATURE, false);
mv.visitInsn(ATHROW);
mv.visitLabel(end);
diff --git a/java/compiler/javac2/javac2.iml b/java/compiler/javac2/javac2.iml
index c44096e70df1..f41cc0db6970 100644
--- a/java/compiler/javac2/javac2.iml
+++ b/java/compiler/javac2/javac2.iml
@@ -10,7 +10,7 @@
<orderEntry type="library" name="Ant" level="project" />
<orderEntry type="module" module-name="forms-compiler" />
<orderEntry type="module" module-name="forms_rt" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="module" module-name="instrumentation-util" />
</component>
<component name="copyright">
diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
index cc8ab2c5ae2e..88095a9cdc36 100644
--- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java
+++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
@@ -25,10 +25,10 @@ import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.types.Path;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.ClassWriter;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.*;
import java.net.MalformedURLException;
@@ -462,7 +462,7 @@ public class Javac2 extends Javac {
private static int getClassFileVersion(ClassReader reader) {
final int[] classfileVersion = new int[1];
- reader.accept(new ClassVisitor(Opcodes.ASM4) {
+ reader.accept(new ClassVisitor(Opcodes.ASM5) {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
classfileVersion[0] = version;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
index 09be13076ca1..58134d49a138 100644
--- a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java
@@ -94,4 +94,24 @@ public class InstanceFilter implements JDOMExternalizable{
}
return cFilters;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ InstanceFilter filter = (InstanceFilter)o;
+
+ if (ID != filter.ID) return false;
+ if (ENABLED != filter.ENABLED) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int)(ID ^ (ID >>> 32));
+ result = 31 * result + (ENABLED ? 1 : 0);
+ return result;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java
index d2216191903a..86ddfaa5fc08 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java
@@ -123,14 +123,14 @@ public abstract class DebuggerAction extends AnAction {
return true;
}
};
- //listener.installOn(tree);
+ listener.installOn(tree);
final AnAction action = ActionManager.getInstance().getAction(actionName);
action.registerCustomShortcutSet(CommonShortcuts.getEditSource(), tree);
return new Disposable() {
public void dispose() {
- //listener.uninstall(tree);
+ listener.uninstall(tree);
action.unregisterCustomShortcutSet(tree);
}
};
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java
index 01e214091308..e127596ec3b5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java
@@ -15,13 +15,12 @@
*/
package com.intellij.debugger.actions;
-import com.intellij.debugger.impl.DebuggerContextUtil;
+import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
/**
@@ -38,7 +37,11 @@ public abstract class GotoFrameSourceAction extends DebuggerAction{
if(project == null) return;
StackFrameDescriptorImpl stackFrameDescriptor = getStackFrameDescriptor(dataContext);
if(stackFrameDescriptor != null) {
- DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getFrameProxy());
+ //DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getFrameProxy());
+ SourcePosition sourcePosition = stackFrameDescriptor.getSourcePosition();
+ if (sourcePosition != null) {
+ sourcePosition.navigate(true);
+ }
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
index 8904331bfaba..48efa9ac87dc 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java
@@ -80,7 +80,8 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
//noinspection unchecked
final List<SmartStepTarget> targets = new OrderedSet<SmartStepTarget>();
- final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(element.getTextOffset()), doc.getLineNumber(element.getTextOffset() + element.getTextLength()));
+ TextRange textRange = element.getTextRange();
+ final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(textRange.getStartOffset()), doc.getLineNumber(textRange.getEndOffset()));
final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() {
final Stack<PsiMethod> myContextStack = new Stack<PsiMethod>();
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java
deleted file mode 100644
index a57211b60ead..000000000000
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.debugger.actions;
-
-import com.intellij.debugger.DebuggerManagerEx;
-import com.intellij.debugger.engine.DebuggerUtils;
-import com.intellij.debugger.ui.breakpoints.Breakpoint;
-import com.intellij.debugger.ui.breakpoints.BreakpointManager;
-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.editor.Editor;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import org.jetbrains.annotations.Nullable;
-
-public class ToggleBreakpointEnabledAction extends AnAction {
-
- public void actionPerformed(AnActionEvent e) {
- final Project project = e.getData(CommonDataKeys.PROJECT);
- Breakpoint breakpoint = findBreakpoint(project);
- if (breakpoint != null) {
- final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.isEnabled());
- }
- }
-
- @Nullable
- private static Breakpoint findBreakpoint(final Project project) {
- Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
- if(editor == null) {
- return null;
- }
- BreakpointManager manager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- int offset = editor.getCaretModel().getOffset();
- return manager.findBreakpoint(editor.getDocument(), offset, null);
- }
-
- public void update(AnActionEvent event){
- final Presentation presentation = event.getPresentation();
- Project project = event.getData(CommonDataKeys.PROJECT);
- if (project == null) {
- presentation.setEnabled(false);
- return;
- }
-
- Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
- if (editor == null) {
- presentation.setEnabled(false);
- return;
- }
- PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
- if (file == null) {
- presentation.setEnabled(false);
- return;
- }
-
- if (DebuggerUtils.isBreakpointAware(file)) {
- Breakpoint breakpoint = findBreakpoint(project);
- if (breakpoint == null) {
- presentation.setEnabled(false);
- return;
- }
- presentation.setEnabled(true);
- }
- else {
- presentation.setEnabled(false);
- }
- }
-}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java
index 45e2cef4b883..4d77dda4b0ad 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java
@@ -17,6 +17,7 @@ package com.intellij.debugger.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.EditorTextField;
import com.intellij.xdebugger.impl.ui.TextViewer;
import com.intellij.xdebugger.impl.ui.tree.actions.XFetchValueActionBase;
@@ -33,7 +34,7 @@ public class ViewTextAction extends XFetchValueActionBase {
protected void handle(Project project, String value) {
final MyDialog dialog = new MyDialog(project);
dialog.setTitle("View Text");
- dialog.setText(value);
+ dialog.setText(StringUtil.unquoteString(value));
dialog.show();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
index 1e3fa9bcd452..50fafaf563cc 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
* @author Eugene Zhuravlev
* Date: 10/26/13
*/
-public class BasicStepMethodFilter implements MethodFilter {
+public class BasicStepMethodFilter implements NamedMethodFilter {
@NotNull
protected final JVMName myDeclaringClassName;
@NotNull
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java
index 127765ae9b1b..7e64da1a1bff 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java
@@ -26,6 +26,7 @@ import com.intellij.util.ThreeState;
import com.intellij.xdebugger.frame.XStackFrame;
import com.sun.jdi.Location;
import com.sun.jdi.ReferenceType;
+import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.request.ClassPrepareRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -60,6 +61,9 @@ public class CompoundPositionManager extends PositionManagerEx {
}
catch (NoDataException ignored) {
}
+ catch (VMDisconnectedException e) {
+ throw e;
+ }
catch (Exception e) {
LOG.error(e);
}
@@ -79,6 +83,9 @@ public class CompoundPositionManager extends PositionManagerEx {
}
catch (NoDataException ignored) {
}
+ catch (VMDisconnectedException e) {
+ throw e;
+ }
catch (Exception e) {
LOG.error(e);
}
@@ -98,6 +105,9 @@ public class CompoundPositionManager extends PositionManagerEx {
}
catch (NoDataException ignored) {
}
+ catch (VMDisconnectedException e) {
+ throw e;
+ }
catch (Exception e) {
LOG.error(e);
}
@@ -116,6 +126,9 @@ public class CompoundPositionManager extends PositionManagerEx {
}
catch (NoDataException ignored) {
}
+ catch (VMDisconnectedException e) {
+ throw e;
+ }
catch (Exception e) {
LOG.error(e);
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
index 2f41cb2288f1..1db0ed60774e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java
@@ -40,6 +40,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.sun.jdi.InternalException;
import com.sun.jdi.ThreadReference;
@@ -319,6 +321,12 @@ public class DebugProcessEvents extends DebugProcessImpl {
myDebugProcessDispatcher.getMulticaster().processAttached(this);
+ // breakpoints should be initialized after all processAttached listeners work
+ XDebugSession session = getSession().getXDebugSession();
+ if (session != null) {
+ session.initBreakpoints();
+ }
+
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(getConnection());
final String transportName = DebuggerBundle.getTransportName(getConnection());
showStatusText(DebuggerBundle.message("status.connected", addressDisplayName, transportName));
@@ -393,8 +401,8 @@ public class DebugProcessEvents extends DebugProcessImpl {
getSuspendManager().voteSuspend(suspendContext);
if (hint != null) {
final MethodFilter methodFilter = hint.getMethodFilter();
- if (methodFilter instanceof BasicStepMethodFilter && !hint.wasStepTargetMethodMatched()) {
- final String message = "Method <b>" + ((BasicStepMethodFilter)methodFilter).getMethodName() + "()</b> has not been called";
+ if (methodFilter instanceof NamedMethodFilter && !hint.wasStepTargetMethodMatched()) {
+ final String message = "Method <b>" + ((NamedMethodFilter)methodFilter).getMethodName() + "()</b> has not been called";
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(message, MessageType.INFO).notify(project);
}
}
@@ -451,7 +459,13 @@ public class DebugProcessEvents extends DebugProcessImpl {
if (requestHit && requestor instanceof Breakpoint) {
// if requestor is a breakpoint and this breakpoint was hit, no matter its suspend policy
- myBreakpointManager.processBreakpointHit((Breakpoint)requestor);
+ XDebugSession session = getSession().getXDebugSession();
+ if (session != null) {
+ XBreakpoint breakpoint = ((Breakpoint)requestor).getXBreakpoint();
+ if (breakpoint != null) {
+ ((XDebugSessionImpl)session).processDependencies(breakpoint);
+ }
+ }
}
if(!requestHit || resumePreferred) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
index f10491282d0e..613217f93ac2 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -1157,7 +1157,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
public ArrayReference newInstance(final ArrayType arrayType,
final int dimension)
throws EvaluateException {
- return arrayType.newInstance(dimension);
+ try {
+ return arrayType.newInstance(dimension);
+ }
+ catch (Exception e) {
+ throw EvaluateExceptionUtil.createEvaluateException(e);
+ }
}
@Override
@@ -1264,7 +1269,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
// for this refType and the refType is not visible to the loader.
// Attempt to evaluate method with this refType will yield ClassNotLoadedException.
// The only way to say for sure whether the class is _visible_ to the given loader, is to use the following API call
- return fromLoader == null || fromLoader.visibleClasses().contains(refType);
+ return fromLoader == null || fromLoader.equals(refType.classLoader()) || fromLoader.visibleClasses().contains(refType);
}
private static String reformatArrayName(String className) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
index 1050c99a34b1..ad2c881d1336 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java
@@ -49,6 +49,8 @@ public class JavaBreakpointHandler extends XBreakpointHandler {
if (javaBreakpoint != null) {
final Breakpoint bpt = javaBreakpoint;
BreakpointManager.addBreakpoint(bpt);
+ // must use invoke to stay in the current request,
+ // otherwise dependent breakpoints do not get enabled on not-suspending parents hit
myProcess.getManagerThread().invoke(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
@@ -62,6 +64,7 @@ public class JavaBreakpointHandler extends XBreakpointHandler {
public void unregisterBreakpoint(@NotNull final XBreakpoint breakpoint, boolean temporary) {
final Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
if (javaBreakpoint != null) {
+ // must use invoke to stay in the current request, see comment in registerBreakpoint
myProcess.getManagerThread().invoke(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java
index 166ec95e7aeb..37ee00b94eaf 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java
@@ -54,6 +54,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XValueMarkerProvider;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.ui.XDebugTabLayouter;
@@ -114,7 +115,7 @@ public class JavaDebugProcess extends XDebugProcess {
Breakpoint breakpoint = descriptors.get(0).getFirst();
XBreakpoint xBreakpoint = breakpoint.getXBreakpoint();
if (xBreakpoint != null) {
- getSession().breakpointReached(xBreakpoint, null, context);
+ ((XDebugSessionImpl)getSession()).breakpointReachedNoProcessing(xBreakpoint, context);
return;
}
}
@@ -130,9 +131,10 @@ public class JavaDebugProcess extends XDebugProcess {
myNodeManager = new NodeManagerImpl(session.getProject(), null) {
@Override
public DebuggerTreeNodeImpl createNode(final NodeDescriptor descriptor, EvaluationContext evaluationContext) {
- ((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext);
+ // value gathered here is required for correct renderers work. e.g. array renderer
+ //((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext);
final DebuggerTreeNodeImpl node = new DebuggerTreeNodeImpl(null, descriptor);
- ((NodeDescriptorImpl)descriptor).updateRepresentation((EvaluationContextImpl)evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
+ //((NodeDescriptorImpl)descriptor).updateRepresentation((EvaluationContextImpl)evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
return node;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
index 4104000a0b27..e37576bae8f4 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
@@ -20,7 +20,6 @@ import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.impl.EditorTextProvider;
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
-import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -61,6 +60,11 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator {
@Nullable XSourcePosition expressionPosition) {
myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) {
@Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
+ @Override
public void threadAction() {
WatchItemDescriptor descriptor = new WatchItemDescriptor(myDebugProcess.getProject(), TextWithImportsImpl.fromXExpression(
expression));
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
index 5d8f50c2a594..793438ebbe05 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
@@ -18,6 +18,8 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
+import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
+import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl;
@@ -31,8 +33,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
/**
* @author egor
@@ -69,7 +72,7 @@ public class JavaExecutionStack extends XExecutionStack {
}
@NotNull
- public ThreadReferenceProxyImpl getThreadProxy() {
+ ThreadReferenceProxyImpl getThreadProxy() {
return myThreadProxy;
}
@@ -101,6 +104,11 @@ public class JavaExecutionStack extends XExecutionStack {
else {
myDebugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
@Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
+
+ @Override
protected void action() throws Exception {
myTopFrame = calcTopFrame();
}
@@ -112,46 +120,81 @@ public class JavaExecutionStack extends XExecutionStack {
@Override
public void computeStackFrames(final int firstFrameIndex, final XStackFrameContainer container) {
- myDebugProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
+ myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) {
+ @Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
@Override
- protected void action() throws Exception {
- boolean showLibraryStackframes = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
- List<JavaStackFrame> frames = new ArrayList<JavaStackFrame>();
+ public void threadAction() {
if (!myThreadProxy.isCollected() && myDebugProcess.getSuspendManager().isSuspended(myThreadProxy)) {
int status = myThreadProxy.status();
if (!(status == ThreadReference.THREAD_STATUS_UNKNOWN) &&
!(status == ThreadReference.THREAD_STATUS_NOT_STARTED) &&
!(status == ThreadReference.THREAD_STATUS_ZOMBIE)) {
try {
- int framesToSkip = firstFrameIndex;
- boolean first = true;
- for (StackFrameProxyImpl stackFrame : myThreadProxy.frames()) {
- if (first && framesToSkip > 0) {
- framesToSkip--;
- first = false;
- continue;
- }
- JavaStackFrame frame = new JavaStackFrame(stackFrame, myDebugProcess, myTracker);
- if (showLibraryStackframes || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
- if (framesToSkip > 0) {
- framesToSkip--;
- continue;
- }
- frames.add(frame);
- }
+ int added = 0;
+ Iterator<StackFrameProxyImpl> iterator = myThreadProxy.frames().iterator();
+ if (iterator.hasNext() && firstFrameIndex > 0) {
+ iterator.next();
+ added++;
}
+ myDebugProcess.getManagerThread().schedule(new AppendFrameCommand(getSuspendContext(), iterator, container, added, firstFrameIndex));
}
catch (EvaluateException e) {
container.errorOccurred(e.getMessage());
- return;
}
}
}
- container.addStackFrames(frames, true);
+ else {
+ container.errorOccurred(DebuggerBundle.message("frame.panel.frames.not.available"));
+ }
}
});
}
+ private class AppendFrameCommand extends SuspendContextCommandImpl {
+ private final Iterator<StackFrameProxyImpl> myStackFramesIterator;
+ private final XStackFrameContainer myContainer;
+ private int myAdded;
+ private final int mySkip;
+
+ public AppendFrameCommand(SuspendContextImpl suspendContext,
+ Iterator<StackFrameProxyImpl> stackFramesIterator,
+ XStackFrameContainer container,
+ int added,
+ int skip) {
+ super(suspendContext);
+ myStackFramesIterator = stackFramesIterator;
+ myContainer = container;
+ myAdded = added;
+ mySkip = skip;
+ }
+
+ @Override
+ public Priority getPriority() {
+ return myAdded <= 10 ? Priority.NORMAL : Priority.LOW;
+ }
+
+ @Override
+ public void contextAction() throws Exception {
+ if (myStackFramesIterator.hasNext()) {
+ JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker);
+ if (DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
+ if (++myAdded > mySkip) {
+ myContainer.addStackFrames(Arrays.asList(frame), false);
+ }
+ }
+ myDebugProcess.getManagerThread().schedule(
+ new AppendFrameCommand(getSuspendContext(), myStackFramesIterator, myContainer, myAdded, mySkip));
+ }
+ else {
+ myContainer.addStackFrames(Collections.<JavaStackFrame>emptyList(), true);
+ }
+ }
+ }
+
private static String calcRepresentation(ThreadReferenceProxyImpl thread) {
DebuggerManagerThreadImpl.assertIsManagerThread();
String name = thread.name();
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
index 316c49201e4c..ed4d8296c381 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
@@ -151,6 +151,11 @@ public class JavaStackFrame extends XStackFrame {
}
myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) {
@Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
+ @Override
public void threadAction() {
XValueChildrenList children = new XValueChildrenList();
buildVariablesThreadAction(getFrameDebuggerContext(), children, node);
@@ -202,8 +207,13 @@ public class JavaStackFrame extends XStackFrame {
}
}
+ DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
+ if (debugProcess == null) {
+ return;
+ }
+
// add last method return value if any
- final Pair<Method, Value> methodValuePair = debuggerContext.getDebugProcess().getLastExecutedMethod();
+ final Pair<Method, Value> methodValuePair = debugProcess.getLastExecutedMethod();
if (methodValuePair != null) {
ValueDescriptorImpl returnValueDescriptor = myNodeManager.getMethodReturnValueDescriptor(stackDescriptor, methodValuePair.getFirst(), methodValuePair.getSecond());
children.add(JavaValue.create(returnValueDescriptor, evaluationContext, myNodeManager));
@@ -222,11 +232,10 @@ public class JavaStackFrame extends XStackFrame {
final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
if (classRenderer.SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) {
- if (thisObjectReference != null && evaluationContext.getDebugProcess().getVirtualMachineProxy().canGetSyntheticAttribute()) {
+ if (thisObjectReference != null && debugProcess.getVirtualMachineProxy().canGetSyntheticAttribute()) {
final ReferenceType thisRefType = thisObjectReference.referenceType();
if (thisRefType instanceof ClassType && thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only
final ClassType clsType = (ClassType)thisRefType;
- final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
final VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy();
for (Field field : clsType.fields()) {
if ((!vm.canGetSyntheticAttribute() || field.isSynthetic()) && StringUtil
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
index d1461961be00..6af021c0f9cc 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
@@ -29,10 +29,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.ui.impl.DebuggerTreeRenderer;
import com.intellij.debugger.ui.impl.watch.*;
import com.intellij.debugger.ui.tree.*;
-import com.intellij.debugger.ui.tree.render.ArrayRenderer;
-import com.intellij.debugger.ui.tree.render.ChildrenBuilder;
-import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
-import com.intellij.debugger.ui.tree.render.NodeRenderer;
+import com.intellij.debugger.ui.tree.render.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -69,17 +66,15 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
myNodeManager = nodeManager;
}
- private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) {
+ private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager, boolean init) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- valueDescriptor.setContext(evaluationContext);
- valueDescriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager);
}
static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager) {
- return create(null, valueDescriptor, evaluationContext, nodeManager);
+ return create(null, valueDescriptor, evaluationContext, nodeManager, true);
}
public JavaValue getParent() {
@@ -100,38 +95,95 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
if (myEvaluationContext.getSuspendContext().isResumed()) return;
myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) {
@Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
+ @Override
public void threadAction() {
- Icon nodeIcon = DebuggerTreeRenderer.getValueIcon(myValueDescriptor);
- final String[] strings = splitValue(myValueDescriptor.getValueLabel());
- String value = StringUtil.notNullize(strings[1]);
- XValuePresentation presentation = new XRegularValuePresentation(value, strings[0]);
- if (myValueDescriptor.isString()) {
- presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), strings[0]);
- }
- if (value.length() > XValueNode.MAX_VALUE_LENGTH) {
- node.setFullValueEvaluator(new XFullValueEvaluator() {
- @Override
- public void startEvaluation(@NotNull final XFullValueEvaluationCallback callback) {
- myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) {
+ myValueDescriptor.setContext(myEvaluationContext);
+ myValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() {
+ @Override
+ public void labelChanged() {
+ Icon nodeIcon = DebuggerTreeRenderer.getValueIcon(myValueDescriptor);
+ final String[] strings = splitValue(myValueDescriptor.getValueLabel());
+ final String value = StringUtil.notNullize(strings[1]);
+ String type = strings[0];
+ XValuePresentation presentation;
+ if (myValueDescriptor.isString()) {
+ presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), type);
+ }
+ else {
+ EvaluateException exception = myValueDescriptor.getEvaluateException();
+ if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer && exception == null) {
+ presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value), type);
+ }
+ else {
+ presentation = new JavaValuePresentation(value, type, exception != null ? exception.getMessage() : null);
+ }
+ }
+ if (value.length() > XValueNode.MAX_VALUE_LENGTH) {
+ node.setFullValueEvaluator(new XFullValueEvaluator() {
@Override
- public void threadAction() {
- final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(myEvaluationContext, myValueDescriptor.getValue());
- DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ public void startEvaluation(@NotNull final XFullValueEvaluationCallback callback) {
+ myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) {
+ @Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
@Override
- public void run() {
- callback.evaluated(valueAsString);
+ public void threadAction() {
+ final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(myEvaluationContext, myValueDescriptor.getValue());
+ DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ callback.evaluated(valueAsString);
+ }
+ });
}
});
}
});
}
- });
- }
- node.setPresentation(nodeIcon, presentation, myValueDescriptor.isExpandable());
+ node.setPresentation(nodeIcon, presentation, myValueDescriptor.isExpandable());
+ }
+ });
}
});
}
+ private static class JavaValuePresentation extends XValuePresentation {
+ private final String myValue;
+ private final String myType;
+ private final String myError;
+
+ public JavaValuePresentation(@NotNull String value, @Nullable String type, @Nullable String error) {
+ myValue = value;
+ myType = type;
+ myError = error;
+ }
+
+ @Nullable
+ @Override
+ public String getType() {
+ return myType;
+ }
+
+ @Override
+ public void renderValue(@NotNull XValueTextRenderer renderer) {
+ if (myError != null) {
+ if (myValue.endsWith(myError)) {
+ renderer.renderValue(myValue.substring(0, myValue.length() - myError.length()));
+ }
+ renderer.renderError(myError);
+ }
+ else {
+ renderer.renderValue(myValue);
+ }
+ }
+ }
+
String getValueString() {
return splitValue(myValueDescriptor.getValueLabel())[1];
}
@@ -168,6 +220,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
if (myEvaluationContext.getSuspendContext().isResumed()) return;
myEvaluationContext.getDebugProcess().getManagerThread().schedule(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) {
@Override
+ public Priority getPriority() {
+ return Priority.NORMAL;
+ }
+
+ @Override
public void contextAction() throws Exception {
final XValueChildrenList children = new XValueChildrenList();
final NodeRenderer renderer = myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess());
@@ -205,7 +262,8 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
for (DebuggerTreeNode node : nodes) {
final NodeDescriptor descriptor = node.getDescriptor();
if (descriptor instanceof ValueDescriptorImpl) {
- children.add(create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager));
+ // Value is calculated already in NodeManagerImpl
+ children.add(create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager, false));
}
else if (descriptor instanceof MessageDescriptor) {
children.add("", new XValue() {
@@ -272,6 +330,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess();
debugProcess.getManagerThread().schedule(new JumpToObjectAction.NavigateCommand(getDebuggerContext(), myValueDescriptor, debugProcess, null) {
@Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
+
+ @Override
protected void doAction(@Nullable final SourcePosition sourcePosition) {
if (sourcePosition != null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -301,6 +364,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider {
DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess();
debugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
@Override
+ public Priority getPriority() {
+ return Priority.HIGH;
+ }
+
+ @Override
protected void action() throws Exception {
evaluationExpression = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java
index 713b4c9b8dd6..c7e59106beb8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -45,6 +45,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
/*
* Class SetValueAction
* @author Jeka
@@ -231,7 +233,7 @@ public class JavaValueModifier extends XValueModifier {
}
private Value preprocessValue(EvaluationContextImpl context, Value value, Type varType) throws EvaluateException {
- if (value != null && "java.lang.String".equals(varType.name()) && !(value instanceof StringReference)) {
+ if (value != null && JAVA_LANG_STRING.equals(varType.name()) && !(value instanceof StringReference)) {
String v = DebuggerUtilsEx.getValueAsString(context, value);
if (v != null) {
value = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(v);
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java
new file mode 100644
index 000000000000..90a5aa2b4927
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine;
+
+/**
+ * Nikolay.Tropin
+ * 2014-06-10
+ */
+public interface NamedMethodFilter extends MethodFilter {
+ String getMethodName();
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
index 0e37ff354e47..2c31e75cc521 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
+import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import com.sun.jdi.AbsentInformationException;
@@ -192,6 +193,18 @@ public class PositionManagerImpl implements PositionManager {
final PsiElement element = psiClass.getNavigationElement();
return element.getContainingFile();
}
+ else {
+ // for now just take the first file with the required name
+ // TODO: if there are more than one, we can try matching package name and sourcePath if available
+ try {
+ PsiFile[] files = FilenameIndex.getFilesByName(project, refType.sourceName(), GlobalSearchScope.allScope(project));
+ if (files.length > 0) {
+ return files[0];
+ }
+ }
+ catch (AbsentInformationException ignore) {
+ }
+ }
return null;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java
index 6786078319a5..00aae83904ce 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java
@@ -33,9 +33,7 @@ import com.sun.jdi.request.EventRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -61,7 +59,7 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
private final HashSet<ObjectReference> myKeptReferences = new HashSet<ObjectReference>();
private EvaluationContextImpl myEvaluationContext = null;
- private JavaExecutionStack[] myExecutionStacks;
+ private JavaExecutionStack myActiveExecutionStack;
SuspendContextImpl(@NotNull DebugProcessImpl debugProcess, int suspendPolicy, int eventVotes, EventSet set) {
myDebugProcess = debugProcess;
@@ -231,27 +229,48 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
@Nullable
@Override
public XExecutionStack getActiveExecutionStack() {
- for (JavaExecutionStack stack : myExecutionStacks) {
- if (stack.getThreadProxy().equals(myThread)) {
- return stack;
- }
+ return myActiveExecutionStack;
+ }
+
+ public void initExecutionStacks(ThreadReferenceProxyImpl newThread) {
+ DebuggerManagerThreadImpl.assertIsManagerThread();
+ myThread = newThread;
+ if (newThread != null) {
+ myActiveExecutionStack = new JavaExecutionStack(newThread, myDebugProcess, true);
}
- return null;
}
@Override
- public XExecutionStack[] getExecutionStacks() {
- return myExecutionStacks;
+ public void computeExecutionStacks(final XExecutionStackContainer container) {
+ myDebugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(this) {
+ @Override
+ public void contextAction() throws Exception {
+ List<JavaExecutionStack> res = new ArrayList<JavaExecutionStack>();
+ Collection<ThreadReferenceProxyImpl> threads = getDebugProcess().getVirtualMachineProxy().allThreads();
+ JavaExecutionStack currentStack = null;
+ for (ThreadReferenceProxyImpl thread : threads) {
+ boolean current = thread == myThread;
+ JavaExecutionStack stack = new JavaExecutionStack(thread, myDebugProcess, current);
+ if (!current) {
+ res.add(stack);
+ }
+ else {
+ currentStack = stack;
+ }
+ }
+ Collections.sort(res, THREADS_COMPARATOR);
+ if (currentStack != null) {
+ res.add(0, currentStack);
+ }
+ container.addExecutionStack(res, true);
+ }
+ });
}
- public void initExecutionStacks(ThreadReferenceProxyImpl newThread) {
- DebuggerManagerThreadImpl.assertIsManagerThread();
- Collection<JavaExecutionStack> res = new ArrayList<JavaExecutionStack>();
- Collection<ThreadReferenceProxyImpl> threads = getDebugProcess().getVirtualMachineProxy().allThreads();
- for (ThreadReferenceProxyImpl thread : threads) {
- res.add(new JavaExecutionStack(thread, myDebugProcess, thread == myThread));
+ private static final Comparator<JavaExecutionStack> THREADS_COMPARATOR = new Comparator<JavaExecutionStack>() {
+ @Override
+ public int compare(JavaExecutionStack th1, JavaExecutionStack th2) {
+ return th1.getDisplayName().compareToIgnoreCase(th2.getDisplayName());
}
- myExecutionStacks = res.toArray(new JavaExecutionStack[res.size()]);
- myThread = newThread;
- }
+ };
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
index d6975e6d021a..45af0e10ac72 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
@@ -220,31 +220,11 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
@Override
public void visitForStatement(PsiForStatement statement) {
- PsiStatement initializer = statement.getInitialization();
- Evaluator initializerEvaluator = null;
- if(initializer != null){
- initializer.accept(this);
- initializerEvaluator = myResult;
- }
-
- PsiExpression condition = statement.getCondition();
- Evaluator conditionEvaluator = null;
- if(condition != null) {
- condition.accept(this);
- conditionEvaluator = myResult;
- }
-
- PsiStatement update = statement.getUpdate();
- Evaluator updateEvaluator = null;
- if(update != null){
- update.accept(this);
- updateEvaluator = myResult;
- }
-
- PsiStatement body = statement.getBody();
- if(body == null) return;
- body.accept(this);
- Evaluator bodyEvaluator = myResult;
+ Evaluator initializerEvaluator = accept(statement.getInitialization());
+ Evaluator conditionEvaluator = accept(statement.getCondition());
+ Evaluator updateEvaluator = accept(statement.getUpdate());
+ Evaluator bodyEvaluator = accept(statement.getBody());
+ if (bodyEvaluator == null) return;
String label = null;
if(statement.getParent() instanceof PsiLabeledStatement) {
@@ -254,6 +234,37 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
}
@Override
+ public void visitForeachStatement(PsiForeachStatement statement) {
+ try {
+ String iterationParameterName = statement.getIterationParameter().getName();
+ myCurrentFragmentEvaluator.setInitialValue(iterationParameterName, null);
+ SyntheticVariableEvaluator iterationParameterEvaluator = new SyntheticVariableEvaluator(myCurrentFragmentEvaluator, iterationParameterName);
+
+ Evaluator iteratedValueEvaluator = accept(statement.getIteratedValue());
+ Evaluator bodyEvaluator = accept(statement.getBody());
+ if (bodyEvaluator == null) return;
+
+ String label = null;
+ if(statement.getParent() instanceof PsiLabeledStatement) {
+ label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
+ }
+ myResult = new ForeachStatementEvaluator(iterationParameterEvaluator, iteratedValueEvaluator, bodyEvaluator, label);
+ }
+ catch (EvaluateException e) {
+ throw new EvaluateRuntimeException(e);
+ }
+ }
+
+ @Nullable
+ private Evaluator accept(@Nullable PsiElement element) {
+ if (element == null || element instanceof PsiEmptyStatement) {
+ return null;
+ }
+ element.accept(this);
+ return myResult;
+ }
+
+ @Override
public void visitIfStatement(PsiIfStatement statement) {
PsiStatement thenBranch = statement.getThenBranch();
if(thenBranch == null) return;
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java
index ff35ef7fe1dd..5914c878086e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java
@@ -16,87 +16,67 @@
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
-import com.intellij.openapi.util.Comparing;
-import com.sun.jdi.BooleanValue;
/**
* @author lex
*/
-public class ForStatementEvaluator implements Evaluator {
+public class ForStatementEvaluator extends ForStatementEvaluatorBase {
private final Evaluator myInitializationEvaluator;
private final Evaluator myConditionEvaluator;
private final Evaluator myUpdateEvaluator;
private final Evaluator myBodyEvaluator;
private Modifier myModifier;
- private final String myLabelName;
public ForStatementEvaluator(Evaluator initializationEvaluator,
Evaluator conditionEvaluator,
Evaluator updateEvaluator,
Evaluator bodyEvaluator,
String labelName) {
- myInitializationEvaluator = new DisableGC(initializationEvaluator);
- myConditionEvaluator = new DisableGC(conditionEvaluator);
- myUpdateEvaluator = new DisableGC(updateEvaluator);
- myBodyEvaluator = new DisableGC(bodyEvaluator);
- myLabelName = labelName;
+ super(labelName);
+ myInitializationEvaluator = initializationEvaluator != null ? new DisableGC(initializationEvaluator) : null;
+ myConditionEvaluator = conditionEvaluator != null ? new DisableGC(conditionEvaluator) : null;
+ myUpdateEvaluator = updateEvaluator != null ? new DisableGC(updateEvaluator) : null;
+ myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null;
}
public Modifier getModifier() {
return myModifier;
}
- public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
- Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
+ @Override
+ protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
+ if (myBodyEvaluator != null) {
+ myBodyEvaluator.evaluate(context);
+ }
+ }
+
+ @Override
+ protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException {
if (myInitializationEvaluator != null) {
value = myInitializationEvaluator.evaluate(context);
myModifier = myInitializationEvaluator.getModifier();
}
+ return value;
+ }
- while (true) {
- if (myConditionEvaluator != null) {
- value = myConditionEvaluator.evaluate(context);
- myModifier = myConditionEvaluator.getModifier();
- if (!(value instanceof BooleanValue)) {
- throw EvaluateExceptionUtil.BOOLEAN_EXPECTED;
- }
- else {
- if (!((BooleanValue)value).booleanValue()) {
- break;
- }
- }
- }
-
- try {
- myBodyEvaluator.evaluate(context);
- }
- catch (BreakException e) {
- if (Comparing.equal(e.getLabelName(), myLabelName)) {
- break;
- }
- else {
- throw e;
- }
- }
- catch (ContinueException e) {
- if (Comparing.equal(e.getLabelName(), myLabelName)) {
- //continue;
- }
- else {
- throw e;
- }
- }
-
- if (myUpdateEvaluator != null) {
- value = myUpdateEvaluator.evaluate(context);
- myModifier = myUpdateEvaluator.getModifier();
- }
+ @Override
+ protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException {
+ if (myConditionEvaluator != null) {
+ Object value = myConditionEvaluator.evaluate(context);
+ myModifier = myConditionEvaluator.getModifier();
+ return value;
}
+ return true;
+ }
+ @Override
+ protected Object evaluateUpdate(EvaluationContextImpl context, Object value) throws EvaluateException {
+ if (myUpdateEvaluator != null) {
+ value = myUpdateEvaluator.evaluate(context);
+ myModifier = myUpdateEvaluator.getModifier();
+ }
return value;
}
-
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java
new file mode 100644
index 000000000000..7af8c894e9b4
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation.expression;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.openapi.util.Comparing;
+import com.sun.jdi.BooleanValue;
+
+/**
+ * @author egor
+ */
+public abstract class ForStatementEvaluatorBase implements Evaluator {
+ private final String myLabelName;
+
+ public ForStatementEvaluatorBase(String labelName) {
+ myLabelName = labelName;
+ }
+
+ public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
+ Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
+ value = evaluateInitialization(context, value);
+
+ while (true) {
+ // condition
+ Object codition = evaluateCondition(context);
+ if (codition instanceof Boolean) {
+ if (!(Boolean)codition) break;
+ }
+ else if (codition instanceof BooleanValue) {
+ if (!((BooleanValue)codition).booleanValue()) break;
+ }
+ else {
+ throw EvaluateExceptionUtil.BOOLEAN_EXPECTED;
+ }
+
+ // body
+
+ try {
+ evaluateBody(context);
+ }
+ catch (BreakException e) {
+ if (Comparing.equal(e.getLabelName(), myLabelName)) {
+ break;
+ }
+ else {
+ throw e;
+ }
+ }
+ catch (ContinueException e) {
+ if (Comparing.equal(e.getLabelName(), myLabelName)) {
+ //continue;
+ }
+ else {
+ throw e;
+ }
+ }
+
+ // update
+ value = evaluateUpdate(context, value);
+ }
+
+ return value;
+ }
+
+ protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException {
+ return value;
+ }
+
+ protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException {
+ return true;
+ }
+
+ protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
+ }
+
+ protected Object evaluateUpdate(EvaluationContextImpl context, Object value) throws EvaluateException {
+ return value;
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java
new file mode 100644
index 000000000000..7b7b44856155
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.debugger.engine.evaluation.expression;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.sun.jdi.ArrayReference;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.Value;
+
+/**
+ * @author egor
+ */
+public class ForeachStatementEvaluator extends ForStatementEvaluatorBase {
+ private final Evaluator myIterationParameterEvaluator;
+ private final Evaluator myIterableEvaluator;
+ private final Evaluator myBodyEvaluator;
+
+ private Evaluator myConditionEvaluator;
+ private Evaluator myNextEvaluator;
+
+ private int myArrayLength = -1;
+ private int myCurrentIndex = 0;
+
+ private Modifier myModifier;
+
+ public ForeachStatementEvaluator(Evaluator iterationParameterEvaluator,
+ Evaluator iterableEvaluator,
+ Evaluator bodyEvaluator,
+ String labelName) {
+ super(labelName);
+ myIterationParameterEvaluator = iterationParameterEvaluator;
+ myIterableEvaluator = new DisableGC(iterableEvaluator);
+ myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null;
+ }
+
+ public Modifier getModifier() {
+ return myModifier;
+ }
+
+ @Override
+ protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException {
+ final Object iterable = myIterableEvaluator.evaluate(context);
+ if (!(iterable instanceof ObjectReference)) {
+ throw new EvaluateException("Unable to do foreach for" + iterable);
+ }
+ IdentityEvaluator iterableEvaluator = new IdentityEvaluator((Value)iterable);
+ if (iterable instanceof ArrayReference) {
+ myArrayLength = ((ArrayReference)iterable).length();
+ myNextEvaluator = new AssignmentEvaluator(myIterationParameterEvaluator,
+ new Evaluator() {
+ @Override
+ public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
+ return ((ArrayReference)iterable).getValue(myCurrentIndex++);
+ }
+
+ @Override
+ public Modifier getModifier() {
+ return null;
+ }
+ });
+ }
+ else {
+ Object iterator = new MethodEvaluator(iterableEvaluator, null, "iterator", null, new Evaluator[0]).evaluate(context);
+ IdentityEvaluator iteratorEvaluator = new IdentityEvaluator((Value)iterator);
+ myConditionEvaluator = new MethodEvaluator(iteratorEvaluator, null, "hasNext", null, new Evaluator[0]);
+ myNextEvaluator = new AssignmentEvaluator(myIterationParameterEvaluator,
+ new MethodEvaluator(iteratorEvaluator, null, "next", null, new Evaluator[0]));
+ }
+ return value;
+ }
+
+ private boolean isArray() {
+ return myArrayLength > -1;
+ }
+
+ @Override
+ protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException {
+ if (isArray()) {
+ return myCurrentIndex < myArrayLength;
+ }
+ else {
+ Object res = myConditionEvaluator.evaluate(context);
+ myModifier = myConditionEvaluator.getModifier();
+ return res;
+ }
+ }
+
+ @Override
+ protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
+ myNextEvaluator.evaluate(context);
+ if (myBodyEvaluator != null) {
+ myBodyEvaluator.evaluate(context);
+ }
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
index c404aef4004c..58296e2b7273 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java
@@ -392,42 +392,6 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque
public void processAttached(DebugProcessImpl process) {
myEventRequestManager = myDebugProcess.getVirtualMachineProxy().eventRequestManager();
- // invoke later, so that requests are for sure created only _after_ 'processAttached()' methods of other listeners are executed
- process.getManagerThread().schedule(new DebuggerCommandImpl() {
- protected void action() throws Exception {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- XDebugSession session = myDebugProcess.getSession().getXDebugSession();
- if (session != null) {
- session.initBreakpoints();
- }
- }
- });
- //Project project = myDebugProcess.getProject();
- //final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
- //for (final Breakpoint breakpoint : breakpointManager.getBreakpoints()) {
- // try {
- // breakpoint.createRequest(myDebugProcess);
- // } catch (Exception e) {
- // LOG.error(e);
- // }
- //}
-
- //AccessToken token = ReadAction.start();
- //try {
- // JavaBreakpointAdapter adapter = new JavaBreakpointAdapter(project);
- // for (XLineBreakpoint breakpoint : XDebuggerManager.getInstance(project).getBreakpointManager()
- // .getBreakpoints(JavaLineBreakpointType.class)) {
- // //new JavaLineBreakpointRequestor(breakpoint).createRequest(myDebugProcess);
- // //adapter.getOrCreate(breakpoint).createRequest(myDebugProcess);
- // }
- //}
- //finally {
- // token.finish();
- //}
- }
- });
}
public void processClassPrepared(final ClassPrepareEvent event) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
index c04c5e4e4817..11b077340eb7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java
@@ -84,10 +84,6 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
@Nullable
public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls) {
- if (!(element instanceof PsiIdentifier || element instanceof PsiKeyword)) {
- return null;
- }
-
PsiElement expression = null;
PsiElement parent = element.getParent();
if (parent instanceof PsiVariable) {
@@ -98,6 +94,12 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
if (pparent instanceof PsiCallExpression) {
parent = pparent;
}
+ else if (pparent instanceof PsiReferenceExpression) {
+ PsiElement resolve = ((PsiReferenceExpression)parent).resolve();
+ if (resolve instanceof PsiClass) {
+ parent = pparent;
+ }
+ }
if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) {
expression = parent;
}
@@ -105,6 +107,19 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
else if (parent instanceof PsiThisExpression) {
expression = parent;
}
+ else if (parent instanceof PsiInstanceOfExpression || parent instanceof PsiBinaryExpression || parent instanceof PsiPolyadicExpression) {
+ if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) {
+ expression = parent;
+ }
+ }
+ else if (allowMethodCalls) {
+ PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class, PsiMethod.class);
+ if (e instanceof PsiNewExpression) {
+ if (((PsiNewExpression)e).getAnonymousClass() == null) {
+ expression = e;
+ }
+ }
+ }
if (expression != null) {
try {
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
index 0f813d0bf167..e570b642b2bd 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java
@@ -25,12 +25,14 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.ui.DebuggerExpressionTextField;
import com.intellij.debugger.ui.JavaDebuggerSupport;
import com.intellij.debugger.ui.tree.render.*;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -141,10 +143,17 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
}
}
}, myProject);
- myClassNameField.getEditorTextField().addFocusListener(new FocusAdapter() {
+ final EditorTextField textField = myClassNameField.getEditorTextField();
+ final FocusAdapter updateContextListener = new FocusAdapter() {
public void focusLost(FocusEvent e) {
- final String qName = myClassNameField.getText();
- updateContext(qName);
+ updateContext(myClassNameField.getText());
+ }
+ };
+ textField.addFocusListener(updateContextListener);
+ Disposer.register(myClassNameField, new Disposable() {
+ @Override
+ public void dispose() {
+ textField.removeFocusListener(updateContextListener);
}
});
@@ -388,10 +397,12 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable {
myChildrenEditor.dispose();
myChildrenExpandedEditor.dispose();
myListChildrenEditor.dispose();
+ Disposer.dispose(myClassNameField);
myLabelEditor = null;
myChildrenEditor = null;
myChildrenExpandedEditor = null;
myListChildrenEditor = null;
+ myClassNameField = null;
myProject = null;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
index a43ca7e9eae3..e1d80414f0e6 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementFactory;
@@ -546,7 +547,12 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
}
static String constructLabelText(final String keylabel, final String valueLabel) {
- return keylabel + " -> " + valueLabel;
+ StringBuilder sb = new StringBuilder();
+ sb.append('\"').append(keylabel).append("\" -> ");
+ if (!StringUtil.isEmpty(valueLabel)) {
+ sb.append('\"').append(valueLabel).append('\"');
+ }
+ return sb.toString();
}
private static String getDescriptorLabel(final ValueDescriptorImpl keyDescriptor) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
index 3c78eaefaea5..6879407b3c9a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
@@ -502,19 +502,23 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
if (getProperties() == null) {
return false;
}
- return getProperties().COUNT_FILTER_ENABLED;
+ return getProperties().isCOUNT_FILTER_ENABLED();
}
public void setCountFilterEnabled(boolean enabled) {
- getProperties().COUNT_FILTER_ENABLED = enabled;
+ if (getProperties().setCOUNT_FILTER_ENABLED(enabled)) {
+ fireBreakpointChanged();
+ }
}
@Override
public int getCountFilter() {
- return getProperties().COUNT_FILTER;
+ return getProperties().getCOUNT_FILTER();
}
public void setCountFilter(int filter) {
- getProperties().COUNT_FILTER = filter;
+ if (getProperties().setCOUNT_FILTER(filter)) {
+ fireBreakpointChanged();
+ }
}
@Override
@@ -522,11 +526,13 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
if (getProperties() == null) {
return false;
}
- return getProperties().CLASS_FILTERS_ENABLED;
+ return getProperties().isCLASS_FILTERS_ENABLED();
}
public void setClassFiltersEnabled(boolean enabled) {
- getProperties().CLASS_FILTERS_ENABLED = enabled;
+ if (getProperties().setCLASS_FILTERS_ENABLED(enabled)) {
+ fireBreakpointChanged();
+ }
}
@Override
@@ -535,7 +541,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
public void setClassFilters(ClassFilter[] filters) {
- getProperties().setClassFilters(filters);
+ if (getProperties().setClassFilters(filters)) {
+ fireBreakpointChanged();
+ }
}
@Override
@@ -544,7 +552,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
protected void setClassExclusionFilters(ClassFilter[] filters) {
- getProperties().setClassExclusionFilters(filters);
+ if (getProperties().setClassExclusionFilters(filters)) {
+ fireBreakpointChanged();
+ }
}
@Override
@@ -552,11 +562,13 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
if (getProperties() == null) {
return false;
}
- return getProperties().INSTANCE_FILTERS_ENABLED;
+ return getProperties().isINSTANCE_FILTERS_ENABLED();
}
public void setInstanceFiltersEnabled(boolean enabled) {
- getProperties().INSTANCE_FILTERS_ENABLED = enabled;
+ if (getProperties().setINSTANCE_FILTERS_ENABLED(enabled)) {
+ fireBreakpointChanged();
+ }
}
@Override
@@ -565,7 +577,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
public void setInstanceFilters(InstanceFilter[] filters) {
- getProperties().setInstanceFilters(filters);
+ if (getProperties().setInstanceFilters(filters)) {
+ fireBreakpointChanged();
+ }
}
private static String getSuspendPolicy(XBreakpoint breakpoint) {
@@ -622,4 +636,8 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
protected void addInstanceFilter(long l) {
getProperties().addInstanceFilter(l);
}
+
+ protected void fireBreakpointChanged() {
+ ((XBreakpointBase)myXBreakpoint).fireBreakpointChanged();
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
index b8fa39e399c7..87453ef57f98 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java
@@ -689,34 +689,6 @@ public class BreakpointManager {
}
}
- // copied from XDebugSessionImpl processDependencies
- public void processBreakpointHit(@NotNull final Breakpoint breakpoint) {
- XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
- XBreakpoint xBreakpoint = breakpoint.myXBreakpoint;
- if (!dependentBreakpointManager.isMasterOrSlave(xBreakpoint)) {
- return;
- }
- List<XBreakpoint<?>> breakpoints = dependentBreakpointManager.getSlaveBreakpoints(xBreakpoint);
- for (final XBreakpoint<?> slaveBreakpoint : breakpoints) {
- DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
- @Override
- public void run() {
- slaveBreakpoint.setEnabled(true);
- }
- });
- }
-
- if (dependentBreakpointManager.getMasterBreakpoint(xBreakpoint) != null && !dependentBreakpointManager.isLeaveEnabled(xBreakpoint)) {
- DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
- @Override
- public void run() {
- breakpoint.setEnabled(false);
- }
- });
- //myDebuggerManager.getBreakpointManager().getLineBreakpointManager().queueBreakpointUpdate(breakpoint);
- }
- }
-
@Nullable
public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) {
XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java
index 4af7275d1258..0bd7d9fc9826 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java
@@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.ui.DialogUtil;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties;
@@ -107,7 +108,12 @@ public class ExceptionBreakpointPropertiesPanel extends XBreakpointCustomPropert
@Override
public void saveTo(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) {
+ boolean changed = breakpoint.getProperties().NOTIFY_CAUGHT != myNotifyCaughtCheckBox.isSelected();
breakpoint.getProperties().NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected();
+ changed = breakpoint.getProperties().NOTIFY_UNCAUGHT != myNotifyUncaughtCheckBox.isSelected() || changed;
breakpoint.getProperties().NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected();
+ if (changed) {
+ ((XBreakpointBase)breakpoint).fireBreakpointChanged();
+ }
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java
index 4d0bec2e165b..41f5417799b6 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java
@@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.ui.DialogUtil;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties;
@@ -100,7 +101,12 @@ public class FieldBreakpointPropertiesPanel extends XBreakpointCustomPropertiesP
@Override
public void saveTo(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) {
+ boolean changed = breakpoint.getProperties().WATCH_ACCESS != myWatchAccessCheckBox.isSelected();
breakpoint.getProperties().WATCH_ACCESS = myWatchAccessCheckBox.isSelected();
+ changed = breakpoint.getProperties().WATCH_MODIFICATION != myWatchModificationCheckBox.isSelected() || changed;
breakpoint.getProperties().WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected();
+ if (changed) {
+ ((XBreakpointBase)breakpoint).fireBreakpointChanged();
+ }
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java
index 8731329275e9..23b18cb4f306 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java
@@ -31,6 +31,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.impl.PositionUtil;
+import com.intellij.debugger.requests.Requestor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -146,7 +147,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
RequestManagerImpl requestManager = debugProcess.getRequestsManager();
if (isWatchEntry()) {
- MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class);
+ MethodEntryRequest entryRequest = findRequest(debugProcess, MethodEntryRequest.class, this);
if (entryRequest == null) {
entryRequest = requestManager.createMethodEntryRequest(this);
}
@@ -159,7 +160,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
debugProcess.getRequestsManager().enableRequest(entryRequest);
}
if (isWatchExit()) {
- MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class);
+ MethodExitRequest exitRequest = findRequest(debugProcess, MethodExitRequest.class, this);
if (exitRequest == null) {
exitRequest = requestManager.createMethodExitRequest(this);
}
@@ -353,15 +354,13 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
}
@Nullable
- private EventRequest findRequest(@NotNull DebugProcessImpl debugProcess, Class requestClass) {
- Set reqSet = debugProcess.getRequestsManager().findRequests(this);
- for (Iterator iterator = reqSet.iterator(); iterator.hasNext();) {
- EventRequest eventRequest = (EventRequest) iterator.next();
- if(eventRequest.getClass().equals(requestClass)) {
- return eventRequest;
+ static <T extends EventRequest> T findRequest(@NotNull DebugProcessImpl debugProcess, Class<T> requestClass, Requestor requestor) {
+ Set<EventRequest> requests = debugProcess.getRequestsManager().findRequests(requestor);
+ for (EventRequest eventRequest : requests) {
+ if (eventRequest.getClass().equals(requestClass)) {
+ return (T)eventRequest;
}
}
-
return null;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java
index bf7419264105..c9026d152e99 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java
@@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.ui.DialogUtil;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties;
@@ -100,7 +101,12 @@ public class MethodBreakpointPropertiesPanel extends XBreakpointCustomProperties
@Override
public void saveTo(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) {
+ boolean changed = breakpoint.getProperties().WATCH_ENTRY != myWatchEntryCheckBox.isSelected();
breakpoint.getProperties().WATCH_ENTRY = myWatchEntryCheckBox.isSelected();
+ changed = breakpoint.getProperties().WATCH_EXIT != myWatchExitCheckBox.isSelected() || changed;
breakpoint.getProperties().WATCH_EXIT = myWatchExitCheckBox.isSelected();
+ if (changed) {
+ ((XBreakpointBase)breakpoint).fireBreakpointChanged();
+ }
}
} \ No newline at end of file
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java
index 295fddbaf187..c106f65cab81 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java
@@ -135,7 +135,7 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro
try {
RequestManagerImpl requestManager = debugProcess.getRequestsManager();
if (isWatchEntry()) {
- MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class);
+ MethodEntryRequest entryRequest = MethodBreakpoint.findRequest(debugProcess, MethodEntryRequest.class, this);
if (entryRequest == null) {
entryRequest = requestManager.createMethodEntryRequest(this);
}
@@ -146,7 +146,7 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro
debugProcess.getRequestsManager().enableRequest(entryRequest);
}
if (isWatchExit()) {
- MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class);
+ MethodExitRequest exitRequest = MethodBreakpoint.findRequest(debugProcess, MethodExitRequest.class, this);
if (exitRequest == null) {
exitRequest = requestManager.createMethodExitRequest(this);
}
@@ -162,18 +162,6 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro
}
}
- private EventRequest findRequest(DebugProcessImpl debugProcess, Class requestClass) {
- Set reqSet = debugProcess.getRequestsManager().findRequests(this);
- for (Iterator iterator = reqSet.iterator(); iterator.hasNext();) {
- EventRequest eventRequest = (EventRequest) iterator.next();
- if(eventRequest.getClass().equals(requestClass)) {
- return eventRequest;
- }
- }
-
- return null;
- }
-
public void processClassPrepare(DebugProcess debugProcess, ReferenceType refType) {
// should be emty - does not make sense for this breakpoint
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java
index ae2f2c115d82..d72c967f67be 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java
@@ -22,15 +22,14 @@ import com.intellij.debugger.ui.impl.watch.*;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.icons.AllIcons;
import com.intellij.ide.highlighter.JavaHighlightingColors;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
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.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -119,18 +118,6 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
return nodeIcon;
}
- @NotNull
- public static EditorColorsScheme getColorScheme(@Nullable JComponent component) {
- EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
- if (component != null && ColorUtil.isDark(component.getBackground()) != ColorUtil.isDark(globalScheme.getDefaultBackground())) {
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME);
- if (scheme != null) {
- return scheme;
- }
- }
- return globalScheme;
- }
-
public static SimpleColoredText getDescriptorText(DebuggerContextImpl debuggerContext,
NodeDescriptorImpl descriptor,
EditorColorsScheme colorsScheme,
@@ -139,11 +126,11 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
}
public static SimpleColoredText getDescriptorText(final DebuggerContextImpl debuggerContext, NodeDescriptorImpl descriptor, boolean multiline) {
- return getDescriptorText(debuggerContext, descriptor, getColorScheme(null), multiline, true);
+ return getDescriptorText(debuggerContext, descriptor, DebuggerUIUtil.getColorScheme(null), multiline, true);
}
public static SimpleColoredText getDescriptorTitle(final DebuggerContextImpl debuggerContext, NodeDescriptorImpl descriptor) {
- return getDescriptorText(debuggerContext, descriptor, getColorScheme(null), false, false);
+ return getDescriptorText(debuggerContext, descriptor, DebuggerUIUtil.getColorScheme(null), false, false);
}
private static SimpleColoredText getDescriptorText(DebuggerContextImpl debuggerContext,
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java
index 554e5f117bcb..8cb6828d26e8 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java
@@ -273,6 +273,9 @@ public class FrameVariablesTree extends DebuggerTree {
}
catch (UnsupportedOperationException ignored) {
}
+ catch (InternalException e) {
+ LOG.info(e);
+ }
return Collections.emptyList();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java
index dd8f17895522..87b0275e9139 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.ui.SimpleColoredText;
import com.intellij.util.containers.HashMap;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import org.jetbrains.annotations.Nullable;
@@ -93,7 +94,7 @@ public class DebuggerTreeNodeImpl extends TreeBuilderNode implements DebuggerTre
final NodeDescriptorImpl descriptor = getDescriptor();
myIcon = DebuggerTreeRenderer.getDescriptorIcon(descriptor);
final DebuggerContextImpl context = getTree().getDebuggerContext();
- myText = DebuggerTreeRenderer.getDescriptorText(context, descriptor, DebuggerTreeRenderer.getColorScheme(myTree), false);
+ myText = DebuggerTreeRenderer.getDescriptorText(context, descriptor, DebuggerUIUtil.getColorScheme(myTree), false);
if (descriptor instanceof ValueDescriptor) {
final ValueMarkup markup = ((ValueDescriptor)descriptor).getMarkup(context.getDebugProcess());
myMarkupTooltipText = markup != null? markup.getToolTipText() : null;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java
index 8547e48d3a46..0662112bca6a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java
@@ -26,6 +26,7 @@ import java.util.Map;
*/
public class MethodsTracker {
private final Map<Method, Integer> myMethodToOccurrenceMap = new HashMap<Method, Integer>();
+ private final Map<Integer, MethodOccurrence> myOccurences = new HashMap<Integer, MethodOccurrence>();
public final class MethodOccurrence {
private final Method myMethod;
@@ -49,8 +50,13 @@ public class MethodsTracker {
}
}
- public MethodOccurrence getMethodOccurrence(Method method) {
- return new MethodOccurrence(method, assignOccurrenceIndex(method));
+ public MethodOccurrence getMethodOccurrence(int frameIndex, Method method) {
+ MethodOccurrence occurrence = myOccurences.get(frameIndex);
+ if (occurrence == null) {
+ occurrence = new MethodOccurrence(method, assignOccurrenceIndex(method));
+ myOccurences.put(frameIndex, occurrence);
+ }
+ return occurrence;
}
private int getOccurrenceCount(Method method) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java
index 28062f09c3d0..08f2e05c2835 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java
@@ -58,6 +58,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
private boolean myIsInLibraryContent;
private ObjectReference myThisObject;
private Color myBackgroundColor;
+ private SourcePosition mySourcePosition;
private Icon myIcon = AllIcons.Debugger.StackFrame;
@@ -68,13 +69,13 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
myUiIndex = frame.getFrameIndex();
myLocation = frame.location();
myThisObject = frame.thisObject();
- myMethodOccurrence = tracker.getMethodOccurrence(myLocation.method());
+ myMethodOccurrence = tracker.getMethodOccurrence(myUiIndex, myLocation.method());
myIsSynthetic = DebuggerUtils.isSynthetic(myMethodOccurrence.getMethod());
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
- final SourcePosition position = ContextUtil.getSourcePosition(StackFrameDescriptorImpl.this);
- final PsiFile file = position != null? position.getFile() : null;
+ mySourcePosition = ContextUtil.getSourcePosition(StackFrameDescriptorImpl.this);
+ final PsiFile file = mySourcePosition != null? mySourcePosition.getFile() : null;
if (file == null) {
myIsInLibraryContent = true;
}
@@ -91,14 +92,14 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
catch (InternalException e) {
LOG.info(e);
myLocation = null;
- myMethodOccurrence = tracker.getMethodOccurrence(null);
+ myMethodOccurrence = tracker.getMethodOccurrence(0, null);
myIsSynthetic = false;
myIsInLibraryContent = false;
}
catch (EvaluateException e) {
LOG.info(e);
myLocation = null;
- myMethodOccurrence = tracker.getMethodOccurrence(null);
+ myMethodOccurrence = tracker.getMethodOccurrence(0, null);
myIsSynthetic = false;
myIsInLibraryContent = false;
}
@@ -273,6 +274,10 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
return myLocation;
}
+ public SourcePosition getSourcePosition() {
+ return mySourcePosition;
+ }
+
private Icon calcIcon() {
try {
if(myFrame.isObsolete()) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index 403015474caa..abda6968def4 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -51,6 +51,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
NodeRenderer myAutoRenderer = null;
private Value myValue;
+ private boolean myValueReady;
+
private EvaluateException myValueException;
protected EvaluationContextImpl myStoredEvaluationContext = null;
@@ -69,38 +71,51 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
protected ValueDescriptorImpl(Project project, Value value) {
myProject = project;
myValue = value;
+ myValueReady = true;
}
protected ValueDescriptorImpl(Project project) {
myProject = project;
}
+ private void assertValueReady() {
+ if (!myValueReady) {
+ LOG.error("Value is not yet calculated for " + getClass());
+ }
+ }
+
@Override
public boolean isArray() {
+ assertValueReady();
return myValue instanceof ArrayReference;
}
- public boolean isDirty() {
+ public boolean isDirty() {
+ assertValueReady();
return myIsDirty;
}
@Override
public boolean isLvalue() {
+ assertValueReady();
return myIsLvalue;
}
@Override
public boolean isNull() {
+ assertValueReady();
return myValue == null;
}
@Override
public boolean isString() {
+ assertValueReady();
return myValue instanceof StringReference;
}
@Override
public boolean isPrimitive() {
+ assertValueReady();
return myValue instanceof PrimitiveValue;
}
@@ -147,7 +162,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
semaphore.waitFor();
}
}
-
+
+ assertValueReady();
return myValue;
}
@@ -190,6 +206,9 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
myValue = getTargetExceptionWithStackTraceFilled(evaluationContext, e);
myIsExpandable = false;
}
+ finally {
+ myValueReady = true;
+ }
myIsNew = false;
}
@@ -239,7 +258,11 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
public void setAncestor(NodeDescriptor oldDescriptor) {
super.setAncestor(oldDescriptor);
myIsNew = false;
- myValue = ((ValueDescriptorImpl)oldDescriptor).getValue();
+ ValueDescriptorImpl other = (ValueDescriptorImpl)oldDescriptor;
+ if (other.myValueReady) {
+ myValue = other.getValue();
+ myValueReady = true;
+ }
}
protected void setLvalue(boolean value) {
@@ -282,8 +305,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
private String getCustomLabel(String label) {
//translate only strings in quotes
String customLabel = null;
- final Value value = getValue();
- if(isShowIdLabel()) {
+ if(isShowIdLabel() && myValueReady) {
+ final Value value = getValue();
Renderer lastRenderer = getLastRenderer();
final EvaluationContextImpl evalContext = myStoredEvaluationContext;
final String idLabel = evalContext != null && lastRenderer != null && !evalContext.getSuspendContext().isResumed()?
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
index 38cba3c27981..9615aae98233 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
@@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.settings.ViewsGeneralSettings;
import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
@@ -126,7 +127,12 @@ public class ArrayRenderer extends NodeRendererImpl{
DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext);
if (arrayItemNode == null) continue;
- if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue;
+ if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS) {
+ // need to init value to be able to ask for null
+ ValueDescriptorImpl descriptor = (ValueDescriptorImpl)arrayItemNode.getDescriptor();
+ descriptor.setContext((EvaluationContextImpl)evaluationContext);
+ if (descriptor.isNull()) continue;
+ }
//if(added >= (ENTRIES_LIMIT + 1)/ 2) break;
children.add(arrayItemNode);
added++;
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java
index bdf89a5c79b9..bd14ef55b054 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java
@@ -110,9 +110,11 @@ public class ClassRenderer extends NodeRendererImpl{
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
try {
if (value instanceof StringReference) {
- buf.append('\"');
- buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value()));
- buf.append('\"');
+ // no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation
+ //buf.append('\"');
+ //buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value()));
+ //buf.append('\"');
+ buf.append(((StringReference)value).value());
}
else if (value instanceof ClassObjectReference) {
ReferenceType type = ((ClassObjectReference)value).reflectedType();
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java
index 6a967533f304..fd77aa900a7c 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -38,6 +38,8 @@ import org.jetbrains.annotations.NonNls;
import java.util.Iterator;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class ToStringRenderer extends NodeRendererImpl {
public static final @NonNls String UNIQUE_ID = "ToStringRenderer";
@@ -76,7 +78,8 @@ public class ToStringRenderer extends NodeRendererImpl {
BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) {
public void evaluationResult(String message) {
valueDescriptor.setValueLabel(
- message == null? "" : "\"" + DebuggerUtils.convertToPresentationString(DebuggerUtilsEx.truncateString(message)) + "\""
+ // no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation
+ message == null? "" : /*"\"" + DebuggerUtils.convertToPresentationString(*/DebuggerUtilsEx.truncateString(message)/*) + "\""*/
);
labelListener.labelChanged();
}
@@ -103,7 +106,7 @@ public class ToStringRenderer extends NodeRendererImpl {
return false;
}
- if(type.name().equals("java.lang.String")) {
+ if(JAVA_LANG_STRING.equals(type.name())) {
return false; // do not render 'String' objects for performance reasons
}
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java
index 2afcf0fd339f..a4bac85f4995 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java
@@ -28,6 +28,7 @@ import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
@@ -138,7 +139,7 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex
public boolean isVisibleOnPopup(@NotNull B breakpoint) {
JavaBreakpointProperties properties = breakpoint.getProperties();
if (properties != null) {
- return properties.COUNT_FILTER_ENABLED || properties.CLASS_FILTERS_ENABLED || properties.INSTANCE_FILTERS_ENABLED;
+ return properties.isCOUNT_FILTER_ENABLED() || properties.isCLASS_FILTERS_ENABLED() || properties.isINSTANCE_FILTERS_ENABLED();
}
return false;
}
@@ -150,27 +151,30 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex
return;
}
+ boolean changed = false;
try {
String text = myPassCountField.getText().trim();
- properties.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0;
- if (properties.COUNT_FILTER < 0) {
- properties.COUNT_FILTER = 0;
- }
+ int filter = !text.isEmpty() ? Integer.parseInt(text) : 0;
+ if (filter < 0) filter = 0;
+ changed = properties.setCOUNT_FILTER(filter);
}
catch (Exception ignored) {
}
- properties.COUNT_FILTER_ENABLED = properties.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected();
+ changed = properties.setCOUNT_FILTER_ENABLED(properties.getCOUNT_FILTER() > 0 && myPassCountCheckbox.isSelected()) || changed;
reloadInstanceFilters();
reloadClassFilters();
updateInstanceFilterEditor(true);
updateClassFilterEditor(true);
- properties.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected();
- properties.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected();
- properties.setClassFilters(myClassFilters);
- properties.setClassExclusionFilters(myClassExclusionFilters);
- properties.setInstanceFilters(myInstanceFilters);
+ changed = properties.setINSTANCE_FILTERS_ENABLED(myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected()) || changed;
+ changed = properties.setCLASS_FILTERS_ENABLED(myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected()) || changed;
+ changed = properties.setClassFilters(myClassFilters) || changed;
+ changed = properties.setClassExclusionFilters(myClassExclusionFilters) || changed;
+ changed = properties.setInstanceFilters(myInstanceFilters) || changed;
+ if (changed) {
+ ((XBreakpointBase)breakpoint).fireBreakpointChanged();
+ }
}
private static void insert(JPanel panel, JComponent component) {
@@ -182,24 +186,24 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex
public void loadFrom(@NotNull B breakpoint) {
JavaBreakpointProperties properties = breakpoint.getProperties();
if (properties != null) {
- if (properties.COUNT_FILTER > 0) {
- myPassCountField.setText(Integer.toString(properties.COUNT_FILTER));
+ if (properties.getCOUNT_FILTER() > 0) {
+ myPassCountField.setText(Integer.toString(properties.getCOUNT_FILTER()));
}
else {
myPassCountField.setText("");
}
- myPassCountCheckbox.setSelected(properties.COUNT_FILTER_ENABLED);
+ myPassCountCheckbox.setSelected(properties.isCOUNT_FILTER_ENABLED());
- myInstanceFiltersCheckBox.setSelected(properties.INSTANCE_FILTERS_ENABLED);
- myInstanceFiltersField.setEnabled(properties.INSTANCE_FILTERS_ENABLED);
- myInstanceFiltersField.getTextField().setEditable(properties.INSTANCE_FILTERS_ENABLED);
+ myInstanceFiltersCheckBox.setSelected(properties.isINSTANCE_FILTERS_ENABLED());
+ myInstanceFiltersField.setEnabled(properties.isINSTANCE_FILTERS_ENABLED());
+ myInstanceFiltersField.getTextField().setEditable(properties.isINSTANCE_FILTERS_ENABLED());
myInstanceFilters = properties.getInstanceFilters();
updateInstanceFilterEditor(true);
- myClassFiltersCheckBox.setSelected(properties.CLASS_FILTERS_ENABLED);
- myClassFiltersField.setEnabled(properties.CLASS_FILTERS_ENABLED);
- myClassFiltersField.getTextField().setEditable(properties.CLASS_FILTERS_ENABLED);
+ myClassFiltersCheckBox.setSelected(properties.isCLASS_FILTERS_ENABLED());
+ myClassFiltersField.setEnabled(properties.isCLASS_FILTERS_ENABLED());
+ myClassFiltersField.getTextField().setEditable(properties.isCLASS_FILTERS_ENABLED());
myClassFilters = properties.getClassFilters();
myClassExclusionFilters = properties.getClassExclusionFilters();
updateClassFilterEditor(true);
diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java
index daab63a93265..599aed3dd0dd 100644
--- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java
+++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java
@@ -16,6 +16,7 @@
package org.jetbrains.java.debugger.breakpoints.properties;
import com.intellij.debugger.InstanceFilter;
+import com.intellij.openapi.util.Comparing;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.OptionTag;
@@ -27,18 +28,14 @@ import org.jetbrains.annotations.Nullable;
* @author egor
*/
public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extends XBreakpointProperties<T> {
- @OptionTag("count-filter-enabled")
- public boolean COUNT_FILTER_ENABLED = false;
- @OptionTag("count-filter")
- public int COUNT_FILTER = 0;
+ private boolean COUNT_FILTER_ENABLED = false;
+ private int COUNT_FILTER = 0;
- @OptionTag("class-filters-enabled")
- public boolean CLASS_FILTERS_ENABLED = false;
+ private boolean CLASS_FILTERS_ENABLED = false;
private ClassFilter[] myClassFilters;
private ClassFilter[] myClassExclusionFilters;
- @OptionTag("instance-filters-enabled")
- public boolean INSTANCE_FILTERS_ENABLED = false;
+ private boolean INSTANCE_FILTERS_ENABLED = false;
private InstanceFilter[] myInstanceFilters;
@Tag("instance-filters")
@@ -47,8 +44,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend
return myInstanceFilters != null ? myInstanceFilters : InstanceFilter.EMPTY_ARRAY;
}
- public void setInstanceFilters(InstanceFilter[] instanceFilters) {
+ public boolean setInstanceFilters(InstanceFilter[] instanceFilters) {
+ boolean changed = !Comparing.equal(myInstanceFilters, instanceFilters);
myInstanceFilters = instanceFilters;
+ return changed;
}
public void addInstanceFilter(long l) {
@@ -64,8 +63,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend
return myClassFilters != null ? myClassFilters : ClassFilter.EMPTY_ARRAY;
}
- public final void setClassFilters(ClassFilter[] classFilters) {
+ public final boolean setClassFilters(ClassFilter[] classFilters) {
+ boolean changed = !Comparing.equal(myClassFilters, classFilters);
myClassFilters = classFilters;
+ return changed;
}
@Tag("class-exclusion-filters")
@@ -74,8 +75,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend
return myClassExclusionFilters != null ? myClassExclusionFilters : ClassFilter.EMPTY_ARRAY;
}
- public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) {
+ public boolean setClassExclusionFilters(ClassFilter[] classExclusionFilters) {
+ boolean changed = !Comparing.equal(myClassExclusionFilters, classExclusionFilters);
myClassExclusionFilters = classExclusionFilters;
+ return changed;
}
@Nullable
@@ -86,14 +89,58 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend
@Override
public void loadState(T state) {
- COUNT_FILTER_ENABLED = state.COUNT_FILTER_ENABLED;
- COUNT_FILTER = state.COUNT_FILTER;
+ setCOUNT_FILTER_ENABLED(state.isCOUNT_FILTER_ENABLED());
+ setCOUNT_FILTER(state.getCOUNT_FILTER());
- CLASS_FILTERS_ENABLED = state.CLASS_FILTERS_ENABLED;
+ setCLASS_FILTERS_ENABLED(state.isCLASS_FILTERS_ENABLED());
myClassFilters = state.getClassFilters();
myClassExclusionFilters = state.getClassExclusionFilters();
- INSTANCE_FILTERS_ENABLED = state.INSTANCE_FILTERS_ENABLED;
+ setINSTANCE_FILTERS_ENABLED(state.isINSTANCE_FILTERS_ENABLED());
myInstanceFilters = state.getInstanceFilters();
}
+
+ @OptionTag("count-filter-enabled")
+ public boolean isCOUNT_FILTER_ENABLED() {
+ return COUNT_FILTER_ENABLED;
+ }
+
+ public boolean setCOUNT_FILTER_ENABLED(boolean COUNT_FILTER_ENABLED) {
+ boolean changed = this.COUNT_FILTER_ENABLED != COUNT_FILTER_ENABLED;
+ this.COUNT_FILTER_ENABLED = COUNT_FILTER_ENABLED;
+ return changed;
+ }
+
+ @OptionTag("count-filter")
+ public int getCOUNT_FILTER() {
+ return COUNT_FILTER;
+ }
+
+ public boolean setCOUNT_FILTER(int COUNT_FILTER) {
+ boolean changed = this.COUNT_FILTER != COUNT_FILTER;
+ this.COUNT_FILTER = COUNT_FILTER;
+ return changed;
+ }
+
+ @OptionTag("class-filters-enabled")
+ public boolean isCLASS_FILTERS_ENABLED() {
+ return CLASS_FILTERS_ENABLED;
+ }
+
+ public boolean setCLASS_FILTERS_ENABLED(boolean CLASS_FILTERS_ENABLED) {
+ boolean changed = this.CLASS_FILTERS_ENABLED != CLASS_FILTERS_ENABLED;
+ this.CLASS_FILTERS_ENABLED = CLASS_FILTERS_ENABLED;
+ return changed;
+ }
+
+ @OptionTag("instance-filters-enabled")
+ public boolean isINSTANCE_FILTERS_ENABLED() {
+ return INSTANCE_FILTERS_ENABLED;
+ }
+
+ public boolean setINSTANCE_FILTERS_ENABLED(boolean INSTANCE_FILTERS_ENABLED) {
+ boolean changed = this.INSTANCE_FILTERS_ENABLED != INSTANCE_FILTERS_ENABLED;
+ this.INSTANCE_FILTERS_ENABLED = INSTANCE_FILTERS_ENABLED;
+ return changed;
+ }
}
diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
index 9da05817277c..ed150d588c3c 100644
--- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
+++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
@@ -291,30 +291,37 @@ public abstract class DebuggerUtils {
}
if (subType instanceof ClassType) {
- result = getSuperType(((ClassType)subType).superclass(), superType);
- if (result != null) {
- return result;
- }
+ try {
+ final ClassType clsType = (ClassType)subType;
+ result = getSuperType(clsType.superclass(), superType);
+ if (result != null) {
+ return result;
+ }
- List ifaces = ((ClassType)subType).allInterfaces();
- for (Object iface : ifaces) {
- InterfaceType interfaceType = (InterfaceType)iface;
- if (typeEquals(interfaceType, superType)) {
- return interfaceType;
+ for (InterfaceType iface : clsType.allInterfaces()) {
+ if (typeEquals(iface, superType)) {
+ return iface;
+ }
}
}
+ catch (ClassNotPreparedException e) {
+ LOG.info(e);
+ }
return null;
}
if (subType instanceof InterfaceType) {
- List ifaces = ((InterfaceType)subType).superinterfaces();
- for (Object iface : ifaces) {
- InterfaceType interfaceType = (InterfaceType)iface;
- result = getSuperType(interfaceType, superType);
- if (result != null) {
- return result;
+ try {
+ for (InterfaceType iface : ((InterfaceType)subType).superinterfaces()) {
+ result = getSuperType(iface, superType);
+ if (result != null) {
+ return result;
+ }
}
}
+ catch (ClassNotPreparedException e) {
+ LOG.info(e);
+ }
}
else if (subType instanceof ArrayType) {
if (superType.endsWith("[]")) {
@@ -324,7 +331,7 @@ public abstract class DebuggerUtils {
return instanceOf(subTypeItem, superTypeItem) ? subType : null;
}
catch (ClassNotLoadedException e) {
- LOG.debug(e);
+ LOG.info(e);
}
}
}
diff --git a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
index 605248782288..9891d983c328 100644
--- a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
+++ b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.TextComponentAccessor;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.GuiUtils;
@@ -33,6 +34,7 @@ import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.io.File;
import java.util.ArrayList;
/**
@@ -49,16 +51,34 @@ public class AlternativeJREPanel extends JPanel implements PanelWithAnchor {
myCbEnabled = new JBCheckBox(ExecutionBundle.message("run.configuration.use.alternate.jre.checkbox"));
myFieldWithHistory = new TextFieldWithHistory();
+ myFieldWithHistory.setHistorySize(-1);
final ArrayList<String> foundJDKs = new ArrayList<String>();
+ final Sdk[] allJDKs = ProjectJdkTable.getInstance().getAllJdks();
+
+ for (Sdk sdk : allJDKs) {
+ foundJDKs.add(sdk.getName());
+ }
+
for (JreProvider provider : JreProvider.EP_NAME.getExtensions()) {
String path = provider.getJrePath();
if (!StringUtil.isEmpty(path)) {
foundJDKs.add(path);
}
}
- final Sdk[] allJDKs = ProjectJdkTable.getInstance().getAllJdks();
+
for (Sdk jdk : allJDKs) {
- foundJDKs.add(jdk.getHomePath());
+ String homePath = jdk.getHomePath();
+
+ if (!SystemInfo.isMac) {
+ final File jre = new File(jdk.getHomePath(), "jre");
+ if (jre.isDirectory()) {
+ homePath = jre.getPath();
+ }
+ }
+
+ if (!foundJDKs.contains(homePath)) {
+ foundJDKs.add(homePath);
+ }
}
myFieldWithHistory.setHistory(foundJDKs);
myPathField = new ComponentWithBrowseButton<TextFieldWithHistory>(myFieldWithHistory, null);
diff --git a/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java b/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java
index 8abf465104dd..18aead7fe7f1 100644
--- a/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java
+++ b/java/execution/impl/src/com/intellij/execution/util/JavaParametersUtil.java
@@ -27,6 +27,8 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ex.PathUtilEx;
import com.intellij.openapi.roots.*;
@@ -36,6 +38,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import org.intellij.lang.annotations.MagicConstant;
+import java.io.File;
import java.util.List;
import java.util.Map;
@@ -128,6 +131,14 @@ public class JavaParametersUtil {
}
private static Sdk createAlternativeJdk(final String jreHome) throws CantRunException {
+ final Sdk configuredJdk = ProjectJdkTable.getInstance().findJdk(jreHome);
+ if (configuredJdk != null) {
+ return configuredJdk;
+ }
+ final boolean isJdk = JavaSdk.checkForJdk(new File(jreHome));
+ if (isJdk) {
+ throw new CantRunException("Jre expected but jdk found");
+ }
final Sdk jdk = JavaSdk.getInstance().createJdk("", jreHome);
if (jdk == null) throw CantRunException.noJdkConfigured();
return jdk;
@@ -135,11 +146,12 @@ public class JavaParametersUtil {
public static void checkAlternativeJRE(CommonJavaRunConfigurationParameters configuration) throws RuntimeConfigurationWarning {
if (configuration.isAlternativeJrePathEnabled()) {
- if (configuration.getAlternativeJrePath() == null ||
- configuration.getAlternativeJrePath().length() == 0 ||
- !JavaSdk.checkForJre(configuration.getAlternativeJrePath())) {
+ final String alternativeJrePath = configuration.getAlternativeJrePath();
+ if (alternativeJrePath == null ||
+ alternativeJrePath.length() == 0 ||
+ ProjectJdkTable.getInstance().findJdk(alternativeJrePath) == null && !JavaSdk.checkForJre(alternativeJrePath)) {
throw new RuntimeConfigurationWarning(
- ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", configuration.getAlternativeJrePath()));
+ ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", alternativeJrePath));
}
}
}
diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
index 5f6f18def730..8a4c380a669a 100644
--- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
+++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -43,7 +43,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -79,13 +79,14 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
});
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
- public EditorNotificationPanel createNotificationPanel(final VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull final VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() != JavaClassFileType.INSTANCE) return null;
final List<LibraryOrderEntry> libraries = findOrderEntriesContainingFile(file);
if (libraries == null) return null;
@@ -240,7 +241,7 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
if (modelsToCommit.isEmpty()) return new ActionCallback.Rejected();
new WriteAction() {
@Override
- protected void run(final Result result) {
+ protected void run(@NotNull final Result result) {
for (Library.ModifiableModel model : modelsToCommit) {
model.commit();
}
@@ -253,7 +254,7 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
@Nullable
private VirtualFile findRoot(Library library) {
for (VirtualFile classesRoot : library.getFiles(OrderRootType.CLASSES)) {
- if (VfsUtil.isAncestor(classesRoot, myClassFile, true)) {
+ if (VfsUtilCore.isAncestor(classesRoot, myClassFile, true)) {
return classesRoot;
}
}
diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java
index 178c85584ae2..668f2cc97577 100644
--- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java
+++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -53,13 +53,14 @@ public class SetupSDKNotificationProvider extends EditorNotifications.Provider<E
});
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
- public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() == JavaClassFileType.INSTANCE) return null;
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
diff --git a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
index 9b803f5d8d6e..e3570c2c0fe5 100644
--- a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
+++ b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,13 +18,22 @@ package com.intellij.ide.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.ui.Gray;
+import com.intellij.ui.border.CustomLineBorder;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
public class ShowStructureSettingsAction extends AnAction implements DumbAware {
public void actionPerformed(AnActionEvent e) {
@@ -33,6 +42,27 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware {
project = ProjectManager.getInstance().getDefaultProject();
}
- ShowSettingsUtil.getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
+ if (Registry.is("ide.new.project.settings")) {
+ new SingleConfigurableEditor(project, ProjectStructureConfigurable.getInstance(project), OptionsEditorDialog.DIMENSION_KEY) {
+ @Nullable
+ @Override
+ protected Border createContentPaneBorder() {
+ return new EmptyBorder(0,0,0,0);
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createSouthPanel() {
+ JComponent panel = super.createSouthPanel();
+ assert panel != null;
+ CustomLineBorder line = new CustomLineBorder(Gray._153, 1, 0, 0, 0);
+ panel.setBorder(new CompoundBorder(line, new EmptyBorder(10, 5, 5, 5)));
+ return panel;
+ }
+ }.show();
+ } else {
+ ShowSettingsUtil
+ .getInstance().editConfigurable(project, OptionsEditorDialog.DIMENSION_KEY, ProjectStructureConfigurable.getInstance(project));
+ }
}
} \ No newline at end of file
diff --git a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java
index a75eb5d5ce5a..0b35148283dc 100644
--- a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java
+++ b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java
@@ -26,7 +26,7 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.impl.libraries.LibraryTypeServiceImpl;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
-import com.intellij.openapi.roots.ui.configuration.ModulesCombobox;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryNameAndLevelPanel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
@@ -50,7 +50,7 @@ import java.util.List;
*/
public class CreateLibraryFromFilesDialog extends DialogWrapper {
private final LibraryNameAndLevelPanel myNameAndLevelPanel;
- private final ModulesCombobox myModulesCombobox;
+ private final ModulesComboBox myModulesComboBox;
private final Project myProject;
private final List<OrderRoot> myRoots;
private final JPanel myPanel;
@@ -67,10 +67,10 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper {
myNameAndLevelPanel = new LibraryNameAndLevelPanel(builder, myDefaultName, Arrays.asList(LibrariesContainer.LibraryLevel.values()),
LibrariesContainer.LibraryLevel.PROJECT);
myNameAndLevelPanel.setDefaultName(myDefaultName);
- myModulesCombobox = new ModulesCombobox();
- myModulesCombobox.fillModules(myProject);
- myModulesCombobox.setSelectedModule(findModule(roots));
- builder.addLabeledComponent("&Add to module:", myModulesCombobox);
+ myModulesComboBox = new ModulesComboBox();
+ myModulesComboBox.fillModules(myProject);
+ myModulesComboBox.setSelectedModule(findModule(roots));
+ builder.addLabeledComponent("&Add to module:", myModulesComboBox);
myPanel = builder.getPanel();
myNameAndLevelPanel.getLibraryNameField().selectAll();
myNameAndLevelPanel.getLevelComboBox().addActionListener(new ActionListener() {
@@ -134,7 +134,7 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper {
final LibrariesContainer.LibraryLevel level = myNameAndLevelPanel.getLibraryLevel();
AccessToken token = WriteAction.start();
try {
- final Module module = myModulesCombobox.getSelectedModule();
+ final Module module = myModulesComboBox.getSelectedModule();
final String libraryName = myNameAndLevelPanel.getLibraryName();
if (level == LibrariesContainer.LibraryLevel.MODULE) {
final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel();
diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
index e7e172c0c117..fbe8636ee360 100644
--- a/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/projectWizard/NewProjectWizard.java
@@ -21,6 +21,7 @@ import com.intellij.ide.util.newProjectWizard.StepSequence;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,6 +47,7 @@ public class NewProjectWizard extends AbstractProjectWizard {
protected void init(@NotNull ModulesProvider modulesProvider) {
myWizardContext.setNewWizard(true);
ProjectTypeStep projectTypeStep = new ProjectTypeStep(myWizardContext, this, modulesProvider);
+ Disposer.register(getDisposable(), projectTypeStep);
mySequence.addCommonStep(projectTypeStep);
ChooseTemplateStep chooseTemplateStep = new ChooseTemplateStep(myWizardContext, projectTypeStep);
mySequence.addCommonStep(chooseTemplateStep);
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
index 4de1dda33846..0b83da74e9f5 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AbstractProjectWizard.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -132,6 +132,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
return path;
}
+ @Override
protected void updateStep() {
if (!mySteps.isEmpty()) {
getCurrentStepObject().updateStep();
@@ -140,6 +141,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
myIcon.setIcon(null);
}
+ @Override
protected void dispose() {
StepSequence sequence = getSequence();
if (sequence != null) {
@@ -150,7 +152,13 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
super.dispose();
}
+ @Override
protected final void doOKAction() {
+ if (!doFinishAction()) return;
+ super.doOKAction();
+ }
+
+ public boolean doFinishAction() {
int idx = getCurrentStep();
try {
do {
@@ -159,7 +167,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
step.updateStep();
}
if (!commitStepData(step)) {
- return;
+ return false;
}
step.onStepLeaving();
try {
@@ -167,18 +175,19 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
}
catch (CommitStepException e) {
handleCommitException(e);
- return;
+ return false;
}
if (!isLastStep(idx)) {
idx = getNextStep(idx);
- } else {
+ }
+ else {
for (ModuleWizardStep wizardStep : mySteps) {
try {
wizardStep.onWizardFinished();
}
catch (CommitStepException e) {
handleCommitException(e);
- return;
+ return false;
}
}
break;
@@ -189,7 +198,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
myCurrentStep = idx;
updateStep();
}
- super.doOKAction();
+ return true;
}
private void handleCommitException(CommitStepException e) {
@@ -213,6 +222,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
return true;
}
+ @Override
public void doNextAction() {
final ModuleWizardStep step = getCurrentStepObject();
if (!commitStepData(step)) {
@@ -223,6 +233,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
}
+ @Override
protected String getHelpID() {
ModuleWizardStep step = getCurrentStepObject();
if (step != null) {
@@ -232,11 +243,6 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
}
@TestOnly
- public void doOk() {
- doOKAction();
- }
-
- @TestOnly
public boolean isLast() {
return isLastStep();
}
@@ -246,12 +252,14 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
return myWizardContext.getProjectFileDirectory() + File.separator + myWizardContext.getProjectName() + ModuleFileType.DOT_DEFAULT_EXTENSION;
}
+ @Override
protected void doPreviousAction() {
final ModuleWizardStep step = getCurrentStepObject();
step.onStepLeaving();
super.doPreviousAction();
}
+ @Override
public void doCancelAction() {
final ModuleWizardStep step = getCurrentStepObject();
step.onStepLeaving();
@@ -262,6 +270,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
return getNextStep(step) == step;
}
+ @Override
protected final int getNextStep(final int step) {
ModuleWizardStep nextStep = null;
final StepSequence stepSequence = getSequence();
@@ -275,6 +284,7 @@ public abstract class AbstractProjectWizard extends AbstractWizard<ModuleWizardS
return nextStep == null ? step : mySteps.indexOf(nextStep);
}
+ @Override
protected final int getPreviousStep(final int step) {
ModuleWizardStep previousStep = null;
final StepSequence stepSequence = getSequence();
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
index 47e901512ed5..10df2939f6e7 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -37,6 +37,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
import com.intellij.util.EventDispatcher;
@@ -238,9 +239,10 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable {
createEditors(getModule());
- JPanel northPanel = new JPanel(new GridBagLayout());
-
- myGenericSettingsPanel.add(northPanel, BorderLayout.NORTH);
+ if (!Registry.is("ide.new.project.settings")) {
+ JPanel northPanel = new JPanel(new GridBagLayout());
+ myGenericSettingsPanel.add(northPanel, BorderLayout.NORTH);
+ }
final JComponent component = createCenterPanel();
myGenericSettingsPanel.add(component, BorderLayout.CENTER);
@@ -332,7 +334,7 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable {
private final ModifiableRootModel myDelegateModel;
@NonNls private final Set<String> myCheckedNames = new HashSet<String>(
Arrays.asList("addOrderEntry", "addLibraryEntry", "addInvalidLibrary", "addModuleOrderEntry", "addInvalidModuleEntry",
- "removeOrderEntry", "setSdk", "inheritSdk", "inheritCompilerOutputPath", "setExcludeOutput", "replaceEntryOfType"));
+ "removeOrderEntry", "setSdk", "inheritSdk", "inheritCompilerOutputPath", "setExcludeOutput", "replaceEntryOfType", "rearrangeOrderEntries"));
ModifiableRootModelInvocationHandler(ModifiableRootModel model) {
myDelegateModel = model;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
index af34e4092d32..d007c3650642 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -38,11 +38,13 @@ import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactsStructureC
import com.intellij.openapi.roots.ui.configuration.projectRoot.*;
import com.intellij.openapi.ui.DetailsComponent;
import com.intellij.openapi.ui.MasterDetailsComponent;
-import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBSplitter;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.BackAction;
import com.intellij.ui.navigation.ForwardAction;
@@ -67,7 +69,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
public static final DataKey<ProjectStructureConfigurable> KEY = DataKey.create("ProjectStructureConfiguration");
protected final UIState myUiState = new UIState();
- private Splitter mySplitter;
+ private JBSplitter mySplitter;
private JComponent myToolbarComponent;
@NonNls public static final String CATEGORY = "category";
private JComponent myToFocus;
@@ -173,8 +175,16 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
public JComponent createComponent() {
myComponent = new MyPanel();
- mySplitter = new Splitter(false, .15f);
+ mySplitter = new JBSplitter(false, .15f);
+ mySplitter.setSplitterProportionKey("ProjectStructure.TopLevelElements");
mySplitter.setHonorComponentsMinimumSize(true);
+ if (Registry.is("ide.new.project.settings")) {
+ mySplitter.setDividerWidth(1);
+ mySplitter.setShowDividerIcon(false);
+ mySplitter.getDivider().setBackground(Gray._153.withAlpha(128));
+ mySplitter.setShowDividerControls(false);
+ mySplitter.setOrientation(mySplitter.getOrientation());
+ }
initSidePanel();
@@ -192,7 +202,11 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarGroup, true);
toolbar.setTargetComponent(myComponent);
myToolbarComponent = toolbar.getComponent();
- left.add(myToolbarComponent, BorderLayout.NORTH);
+ if (Registry.is("ide.new.project.settings")) {
+ left.setBackground(new Color(0xD2D6DD));
+ } else {
+ left.add(myToolbarComponent, BorderLayout.NORTH);
+ }
left.add(mySidePanel, BorderLayout.CENTER);
mySplitter.setFirstComponent(left);
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
index 193ce66a8f36..a2d1e4e0489d 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,14 +17,17 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.ui.popup.ListItemDescriptor;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
import com.intellij.ui.popup.list.GroupedItemsListRenderer;
+import com.intellij.util.ui.EmptyIcon;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
@@ -52,7 +55,10 @@ public class SidePanel extends JPanel {
myModel = new DefaultListModel();
myList = new JBList(myModel);
-
+ if (Registry.is("ide.new.project.settings")) {
+ myList.setBackground(new Color(0xD2D6DD));
+ myList.setBorder(new EmptyBorder(5, 0, 0, 0));
+ }
final ListItemDescriptor descriptor = new ListItemDescriptor() {
@Override
public String getTextFor(final Object value) {
@@ -66,7 +72,7 @@ public class SidePanel extends JPanel {
@Override
public Icon getIconFor(final Object value) {
- return null;
+ return Registry.is("ide.new.project.settings") ? EmptyIcon.create(16, 20) : null;
//return myPlace2Presentation.get(value).getIcon();
}
@@ -78,14 +84,22 @@ public class SidePanel extends JPanel {
@Override
public String getCaptionAboveOf(final Object value) {
- return myIndex2Separator.get(myPlaces.indexOf(value));
+ String text = myIndex2Separator.get(myPlaces.indexOf(value));
+ return text != null && Registry.is("ide.new.project.settings") ? text.toUpperCase() : text;
}
};
- myList.setCellRenderer(new GroupedItemsListRenderer(descriptor));
-
+ myList.setCellRenderer(new GroupedItemsListRenderer(descriptor) {
+ {
+ mySeparatorComponent.setCaptionCentered(false);
+ }
+ @Override
+ protected Color getBackground() {
+ return Registry.is("ide.new.project.settings") ? new Color(0xD2D6DD) : super.getBackground();
+ }
+ });
- add(ScrollPaneFactory.createScrollPane(myList), BorderLayout.CENTER);
+ add(ScrollPaneFactory.createScrollPane(myList, Registry.is("ide.new.project.settings")), BorderLayout.CENTER);
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myList.addListSelectionListener(new ListSelectionListener() {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
index 15a9cee022e8..69b490828f0b 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
@@ -235,7 +235,7 @@ public class ArtifactEditorImpl implements ArtifactEditorEx {
label.setBorder(HintUtil.createHintBorder());
label.setBackground(HintUtil.INFORMATION_COLOR);
label.setOpaque(true);
- HintManager.getInstance().showHint(label, RelativePoint.getSouthEastOf(link), HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE, -1);
+ HintManager.getInstance().showHint(label, RelativePoint.getSouthWestOf(link), HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE, -1);
}
});
labelPanel.add(link);
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java
index 046157ef3bc7..0a162f49bb90 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java
@@ -103,7 +103,7 @@ public abstract class ChangeLibraryLevelActionBase extends AnAction {
}
}
- final Library copied = ((LibraryTableBase.ModifiableModelEx)provider.getModifiableModel()).createLibrary(dialog.getLibraryName(), library.getKind());
+ final Library copied = ((LibraryTableBase.ModifiableModelEx)provider.getModifiableModel()).createLibrary(StringUtil.nullize(dialog.getLibraryName()), library.getKind());
final LibraryEx.ModifiableModelEx model = (LibraryEx.ModifiableModelEx)copied.getModifiableModel();
LibraryEditingUtil.copyLibrary(library, copiedFiles, model);
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelInClasspathAction.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelInClasspathAction.java
index 2b42fd3158e4..9a670be8f458 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelInClasspathAction.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelInClasspathAction.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.classpath;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.impl.OrderEntryUtil;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil;
import com.intellij.openapi.roots.libraries.Library;
@@ -43,15 +44,18 @@ class ChangeLibraryLevelInClasspathAction extends ChangeLibraryLevelActionBase {
public void actionPerformed(AnActionEvent event) {
final OrderEntry entry = myPanel.getSelectedEntry();
if (!(entry instanceof LibraryOrderEntry)) return;
- final LibraryEx library = (LibraryEx)((LibraryOrderEntry)entry).getLibrary();
+ LibraryOrderEntry libraryEntry = (LibraryOrderEntry)entry;
+ final LibraryEx library = (LibraryEx)libraryEntry.getLibrary();
if (library == null) return;
final Library copied = doCopy(library);
if (copied == null) return;
- myPanel.getRootModel().removeOrderEntry(entry);
if (!isConvertingToModuleLibrary()) {
- myPanel.getRootModel().addLibraryEntry(copied);
+ OrderEntryUtil.replaceLibrary(myPanel.getRootModel(), library, copied);
+ }
+ else {
+ OrderEntryUtil.replaceLibraryEntryByAdded(myPanel.getRootModel(), libraryEntry);
}
}
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java
index 92b110caef43..c2d3d801a211 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * User: anna
- * Date: 26-Dec-2007
- */
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.icons.AllIcons;
@@ -30,11 +25,15 @@ import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import javax.swing.*;
+/**
+ * @author anna
+ * @since 26-Dec-2007
+ */
public class ClassesOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
-
@Override
public SdkPathEditor createPathEditor(Sdk sdk) {
- return new SdkPathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, new FileChooserDescriptor(true, true, true, false, true, true));
+ FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, false, true, true);
+ return new SdkPathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, descriptor);
}
@Override
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
index bf4f67c0c824..b88f92474fcf 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/BaseStructureConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -38,6 +38,8 @@ import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.awt.RelativePoint;
@@ -300,7 +302,9 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i
result.addAll(copyActions);
result.add(Separator.getInstance());
- result.add(new MyFindUsagesAction(myTree));
+ if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
+ result.add(new MyFindUsagesAction(myTree));
+ }
return result;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
index 44d7820feb88..1c313c1077ee 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -53,7 +53,9 @@ import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.NullableComputable;
+import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -149,7 +151,9 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
final ArrayList<AnAction> result = super.createActions(fromPopup);
result.add(Separator.getInstance());
result.add(new MyGroupAction());
- addCollapseExpandActions(result);
+ if (fromPopup || !(SystemInfo.isMac && Registry.is("ide.new.project.settings"))) {
+ addCollapseExpandActions(result);
+ }
return result;
}
diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
index 231e61a85b6d..59b1b9601d90 100644
--- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
+++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
@@ -19,8 +19,8 @@ package com.intellij.util.descriptors.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.MultiValuesMap;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.*;
import com.intellij.util.EventDispatcher;
import com.intellij.util.descriptors.*;
@@ -35,14 +35,13 @@ import java.util.Set;
/**
* @author nik
*/
-public class ConfigFileContainerImpl implements ConfigFileContainer {
+public class ConfigFileContainerImpl extends SimpleModificationTracker implements ConfigFileContainer {
private final Project myProject;
private final EventDispatcher<ConfigFileListener> myDispatcher = EventDispatcher.create(ConfigFileListener.class);
private final MultiValuesMap<ConfigFileMetaData, ConfigFile> myConfigFiles = new MultiValuesMap<ConfigFileMetaData, ConfigFile>();
private ConfigFile[] myCachedConfigFiles;
private final ConfigFileMetaDataProvider myMetaDataProvider;
private final ConfigFileInfoSetImpl myConfiguration;
- private long myModificationCount;
public ConfigFileContainerImpl(final Project project, final ConfigFileMetaDataProvider descriptorMetaDataProvider,
final ConfigFileInfoSetImpl configuration) {
@@ -50,10 +49,12 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
myMetaDataProvider = descriptorMetaDataProvider;
myProject = project;
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
+ @Override
public void propertyChanged(@NotNull final VirtualFilePropertyEvent event) {
fileChanged(event.getFile());
}
+ @Override
public void fileMoved(@NotNull final VirtualFileMoveEvent event) {
fileChanged(event.getFile());
}
@@ -61,25 +62,17 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
myConfiguration.setContainer(this);
}
- public void incModificationCount() {
- myModificationCount ++;
- }
-
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
-
private void fileChanged(final VirtualFile file) {
for (ConfigFile descriptor : myConfigFiles.values()) {
final VirtualFile virtualFile = descriptor.getVirtualFile();
- if (virtualFile != null && VfsUtil.isAncestor(file, virtualFile, false)) {
+ if (virtualFile != null && VfsUtilCore.isAncestor(file, virtualFile, false)) {
myConfiguration.updateConfigFile(descriptor);
fireDescriptorChanged(descriptor);
}
}
}
+ @Override
@Nullable
public ConfigFile getConfigFile(ConfigFileMetaData metaData) {
final Collection<ConfigFile> descriptors = myConfigFiles.get(metaData);
@@ -89,6 +82,7 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
return descriptors.iterator().next();
}
+ @Override
public ConfigFile[] getConfigFiles() {
if (myCachedConfigFiles == null) {
final Collection<ConfigFile> descriptors = myConfigFiles.values();
@@ -97,10 +91,12 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
return myCachedConfigFiles;
}
+ @Override
public Project getProject() {
return myProject;
}
+ @Override
public void addListener(final ConfigFileListener listener, final Disposable parentDisposable) {
myDispatcher.addListener(listener, parentDisposable);
}
@@ -111,18 +107,21 @@ public class ConfigFileContainerImpl implements ConfigFileContainer {
}
+ @Override
public ConfigFileInfoSet getConfiguration() {
return myConfiguration;
}
+ @Override
public void dispose() {
- int i = 0;
}
+ @Override
public void addListener(final ConfigFileListener listener) {
myDispatcher.addListener(listener);
}
+ @Override
public void removeListener(final ConfigFileListener listener) {
myDispatcher.removeListener(listener);
}
diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
index db9b58b575ba..00be712070ae 100644
--- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
+++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,6 +16,7 @@
package com.intellij.util.descriptors.impl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
@@ -36,13 +37,12 @@ import java.lang.ref.SoftReference;
/**
* @author nik
*/
-public class ConfigFileImpl implements ConfigFile {
+public class ConfigFileImpl extends SimpleModificationTracker implements ConfigFile {
@NotNull private ConfigFileInfo myInfo;
private final VirtualFilePointer myFilePointer;
private volatile Reference<PsiFile> myPsiFile;
private final ConfigFileContainerImpl myContainer;
private final Project myProject;
- private long myModificationCount;
public ConfigFileImpl(@NotNull final ConfigFileContainerImpl container, @NotNull final ConfigFileInfo configuration) {
myContainer = container;
@@ -64,7 +64,7 @@ public class ConfigFileImpl implements ConfigFile {
}
private void onChange() {
- myModificationCount++;
+ incModificationCount();
myContainer.fireDescriptorChanged(this);
}
@@ -138,10 +138,4 @@ public class ConfigFileImpl implements ConfigFile {
public ConfigFileMetaData getMetaData() {
return myInfo.getMetaData();
}
-
-
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
}
diff --git a/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java
index 1a54284d17a3..5e1cb191ecdd 100644
--- a/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java
+++ b/java/java-analysis-api/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -262,4 +262,7 @@ public abstract class QuickFixFactory {
@NotNull Collection<String> missedElements);
@NotNull
public abstract IntentionAction createSurroundWithQuotesAnnotationParameterValueFix(@NotNull PsiAnnotationMemberValue value, @NotNull PsiType expectedType);
+
+ @NotNull
+ public abstract IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall);
}
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaBatchLocalInspectionTool.java b/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaBatchLocalInspectionTool.java
index 18f1c5128ab6..4b585c30cf83 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaBatchLocalInspectionTool.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaBatchLocalInspectionTool.java
@@ -26,18 +26,8 @@ import org.jetbrains.annotations.Nullable;
* - work with PSI or document only and
* - don't provide {@link com.intellij.codeInsight.intention.IntentionAction} for quick fixes/suppression, making do with {@link LocalQuickFix} only.
*/
-public abstract class BaseJavaBatchLocalInspectionTool extends AbstractBaseJavaLocalInspectionTool implements BatchSuppressableTool {
- @NotNull
- @Override
- public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
- return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()));
- }
-
- @Override
- public boolean isSuppressedFor(@NotNull PsiElement element) {
- return isSuppressedFor(element, this);
- }
-
+public abstract class BaseJavaBatchLocalInspectionTool extends AbstractBaseJavaLocalInspectionTool {
+ @Deprecated
public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
BatchSuppressManager manager = BatchSuppressManager.SERVICE.getInstance();
String alternativeId;
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java b/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
index ab807d608579..df0085fff6de 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
@@ -42,11 +42,7 @@ public abstract class BaseJavaLocalInspectionTool extends AbstractBaseJavaLocalI
return SuppressManager.getInstance().createSuppressActions(key);
}
- @Override
- public boolean isSuppressedFor(@NotNull PsiElement element) {
- return isSuppressedFor(element, this);
- }
-
+ @Deprecated
public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
return BaseJavaBatchLocalInspectionTool.isSuppressedFor(element, tool);
}
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaBatchInspectionTool.java b/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaBatchInspectionTool.java
index 8c2726e77bef..5ac743d212ce 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaBatchInspectionTool.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaBatchInspectionTool.java
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool implements BatchSuppressableTool {
+public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool {
@Override
public boolean queryExternalUsagesRequests(@NotNull final InspectionManager manager,
@NotNull final GlobalInspectionContext globalContext,
@@ -38,14 +38,4 @@ public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool
return false;
}
- @NotNull
- @Override
- public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
- return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()));
- }
-
- @Override
- public boolean isSuppressedFor(@NotNull final PsiElement element) {
- return BatchSuppressManager.SERVICE.getInstance().isSuppressedFor(element, getShortName());
- }
}
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java b/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
index 1d9ff9c4a6cc..f50d998124c0 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
@@ -20,13 +20,10 @@
*/
package com.intellij.codeInspection;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.reference.RefManager;
-import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool implements CustomSuppressableInspectionTool {
+public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool {
@Override
public boolean queryExternalUsagesRequests(@NotNull final InspectionManager manager,
@NotNull final GlobalInspectionContext globalContext,
@@ -37,15 +34,4 @@ public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool impl
protected boolean queryExternalUsagesRequests(@NotNull RefManager manager, @NotNull GlobalJavaInspectionContext globalContext, @NotNull ProblemDescriptionsProcessor processor) {
return false;
}
-
- @Override
- @Nullable
- public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
- return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
- }
-
- @Override
- public boolean isSuppressedFor(@NotNull final PsiElement element) {
- return SuppressManager.getInstance().isSuppressedFor(element, getShortName());
- }
} \ No newline at end of file
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/SuppressManager.java b/java/java-analysis-api/src/com/intellij/codeInspection/SuppressManager.java
index 2eaa94be3b03..5500f2430e72 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/SuppressManager.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/SuppressManager.java
@@ -29,7 +29,7 @@ import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
-public abstract class SuppressManager implements BatchSuppressManager {
+public abstract class SuppressManager implements BatchSuppressManager, InspectionSuppressor {
public static SuppressManager getInstance() {
return ServiceManager.getService(SuppressManager.class);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index 410be64ee738..b567ce41325a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -446,7 +446,7 @@ public class HighlightMethodUtil {
final String message = JavaErrorMessages
.message("incompatible.call.types", idx + 1, substitutor.substitute(parameters[idx].getType()).getCanonicalText(), argType.getCanonicalText());
- return XmlStringUtil.wrapInHtml("<body>" + message +
+ return XmlStringUtil.wrapInHtml("<body>" + XmlStringUtil.escapeString(message) +
" <a href=\"#assignment/" + XmlStringUtil.escapeString(createMismatchedArgumentsHtmlTooltip(candidateInfo, list)) + "\"" +
(UIUtil.isUnderDarcula() ? " color=\"7AB4C9\" " : "") +
">" + DaemonBundle.message("inspection.extended.description") + "</a></body>");
@@ -670,6 +670,7 @@ public class HighlightMethodUtil {
registerChangeParameterClassFix(methodCall, list, highlightInfo);
if (methodCandidates.length == 0) {
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createStaticImportMethodFix(methodCall));
+ QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.addMethodQualifierFix(methodCall));
}
for (IntentionAction action : QUICK_FIX_FACTORY.getVariableTypeFromCallFixes(methodCall, list)) {
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, action);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index 0dc8e3df8fec..7404d1fbfae3 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -1181,7 +1181,7 @@ public class HighlightUtil extends HighlightUtilBase {
final PsiType caughtType = parameter.getType();
if (caughtType instanceof PsiClassType) {
HighlightInfo info = checkSimpleCatchParameter(parameter, thrownTypes, (PsiClassType)caughtType);
- return info == null ? null : Collections.<HighlightInfo>singletonList(info);
+ return info == null ? null : Collections.singletonList(info);
}
if (caughtType instanceof PsiDisjunctionType) {
return checkMultiCatchParameter(parameter, thrownTypes);
@@ -1796,12 +1796,19 @@ public class HighlightUtil extends HighlightUtilBase {
*/
@Nullable
public static HighlightInfo checkIllegalForwardReferenceToField(@NotNull PsiReferenceExpression expression, @NotNull PsiField referencedField) {
+ final Boolean isIllegalForwardReference = isIllegalForwardReferenceToField(expression, referencedField, false);
+ if (isIllegalForwardReference == null) return null;
+ String description = isIllegalForwardReference ? JavaErrorMessages.message("illegal.forward.reference") : JavaErrorMessages.message("illegal.self.reference");
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
+ }
+
+ public static Boolean isIllegalForwardReferenceToField(@NotNull PsiReferenceExpression expression, @NotNull PsiField referencedField, boolean acceptQualified) {
PsiClass containingClass = referencedField.getContainingClass();
if (containingClass == null) return null;
if (expression.getContainingFile() != referencedField.getContainingFile()) return null;
if (expression.getTextRange().getStartOffset() >= referencedField.getTextRange().getEndOffset()) return null;
// only simple reference can be illegal
- if (expression.getQualifierExpression() != null) return null;
+ if (!acceptQualified && expression.getQualifierExpression() != null) return null;
PsiField initField = findEnclosingFieldInitializer(expression);
PsiClassInitializer classInitializer = findParentClassInitializer(expression);
if (initField == null && classInitializer == null) return null;
@@ -1814,8 +1821,7 @@ public class HighlightUtil extends HighlightUtilBase {
if (!containingClass.getManager().areElementsEquivalent(containingClass, PsiTreeUtil.getParentOfType(expression, PsiClass.class))) {
return null;
}
- String description = JavaErrorMessages.message("illegal.forward.reference");
- return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
+ return initField != referencedField;
}
/**
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java
index 19fcc3b9fcc3..367f28719d1b 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeStringLiteralToCharInMethodCallFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -33,6 +33,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class ChangeStringLiteralToCharInMethodCallFix implements IntentionAction {
private final PsiLiteralExpression myLiteral;
private final PsiCall myCall;
@@ -171,6 +173,6 @@ public class ChangeStringLiteralToCharInMethodCallFix implements IntentionAction
}
private static boolean isString(final PsiType type) {
- return type != null && "java.lang.String".equals(type.getCanonicalText());
+ return type != null && type.equalsToText(JAVA_LANG_STRING);
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/EmptyQuickFixFactory.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/EmptyQuickFixFactory.java
index a69603bdcecd..e886be781eab 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/intention/EmptyQuickFixFactory.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/EmptyQuickFixFactory.java
@@ -602,4 +602,10 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
@NotNull PsiType expectedType) {
return QuickFixes.EMPTY_FIX;
}
+
+ @NotNull
+ @Override
+ public IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall) {
+ return QuickFixes.EMPTY_FIX;
+ }
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
index 87ad7d9f6756..96066c34eefe 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java
@@ -433,6 +433,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
if (resolved instanceof PsiField && ((PsiField)resolved).getContainingClass() == field.getContainingClass()) {
final PsiExpression initializer = ((PsiField)resolved).getInitializer();
if (initializer == null ||
+ resolved == field ||
initializer.getTextOffset() > myAnonymClass.getTextOffset() && !((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC)) {
myBodyContainsForbiddenRefs = true;
return;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
index 6fb217eaa4e9..1e887030dcb4 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
@@ -112,7 +112,6 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
containingClass = psiMethod.getContainingClass();
isConstructor = psiMethod.isConstructor();
}
- if (containingClass == null) return null;
boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod);
if (isReceiverType && psiMethod != null) {
PsiMethod nonAmbiguousMethod = ensureNonAmbiguousMethod(parameters, psiMethod);
@@ -120,6 +119,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
psiMethod = nonAmbiguousMethod;
containingClass = nonAmbiguousMethod.getContainingClass();
}
+ if (containingClass == null) return null;
final boolean staticOrValidConstructorRef;
if (isConstructor) {
staticOrValidConstructorRef =
@@ -182,6 +182,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
}
});
if (usedInQualifier.get()) return null;
+ } else if (containingClass != PsiTreeUtil.getParentOfType(body, PsiClass.class) && containingClass.getName() == null) {
+ return null;
}
return methodCall;
} else if (methodCall instanceof PsiNewExpression) {
@@ -275,8 +277,16 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
methodRefText = qualifier + "::" + ((PsiMethodCallExpression)element).getTypeArgumentList().getText() + methodReferenceName;
}
else {
- methodRefText =
- (psiMethod.hasModifierProperty(PsiModifier.STATIC) ? getClassReferenceName(containingClass) : "this") + "::" + methodReferenceName;
+ if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
+ methodRefText = getClassReferenceName(containingClass);
+ } else {
+ if (containingClass != PsiTreeUtil.getParentOfType(element, PsiClass.class) ) {
+ methodRefText = containingClass.getName() + ".this";
+ } else {
+ methodRefText = "this";
+ }
+ }
+ methodRefText += "::" + methodReferenceName;
}
}
else if (element instanceof PsiNewExpression) {
@@ -343,7 +353,13 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
private static String getClassReferenceName(PsiClass containingClass) {
final String qualifiedName = containingClass.getQualifiedName();
- return qualifiedName != null ? qualifiedName : containingClass.getName();
+ if (qualifiedName != null) {
+ return qualifiedName;
+ }
+ else {
+ final String containingClassName = containingClass.getName();
+ return containingClassName != null ? containingClassName : "";
+ }
}
private static class ReplaceWithMethodRefFix implements LocalQuickFix {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
index 6136e01f85d8..5f8e43d24ef8 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/SuppressManagerImpl.java
@@ -38,6 +38,11 @@ public class SuppressManagerImpl extends SuppressManager {
}
@Override
+ public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, String toolShortName) {
+ return createBatchSuppressActions(HighlightDisplayKey.find(toolShortName));
+ }
+
+ @Override
public boolean isSuppressedFor(@NotNull final PsiElement element, final String toolId) {
return JavaSuppressionUtil.getElementToolSuppressedIn(element, toolId) != null;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
index b76177e58880..534d65b07531 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java
@@ -16,10 +16,15 @@
package com.intellij.codeInspection.dataFlow;
import com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.Function;
+import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,8 +40,14 @@ import static com.intellij.codeInspection.dataFlow.MethodContract.ValueConstrain
public class ContractInference {
@NotNull
- public static List<MethodContract> inferContracts(@NotNull PsiMethod method) {
- return new ContractInferenceInterpreter(method).inferContracts();
+ public static List<MethodContract> inferContracts(@NotNull final PsiMethod method) {
+ return CachedValuesManager.getCachedValue(method, new CachedValueProvider<List<MethodContract>>() {
+ @Nullable
+ @Override
+ public Result<List<MethodContract>> compute() {
+ return Result.create(new ContractInferenceInterpreter(method).inferContracts(), method);
+ }
+ });
}
}
@@ -49,15 +60,78 @@ class ContractInferenceInterpreter {
List<MethodContract> inferContracts() {
PsiCodeBlock body = myMethod.getBody();
- if (body == null) return Collections.emptyList();
-
- PsiStatement[] statements = body.getStatements();
+ PsiStatement[] statements = body == null ? PsiStatement.EMPTY_ARRAY : body.getStatements();
if (statements.length == 0) return Collections.emptyList();
+ if (statements.length == 1) {
+ if (statements[0] instanceof PsiReturnStatement) {
+ List<MethodContract> result = handleDelegation(((PsiReturnStatement)statements[0]).getReturnValue(), false);
+ if (result != null) return result;
+ }
+ else if (statements[0] instanceof PsiExpressionStatement && ((PsiExpressionStatement)statements[0]).getExpression() instanceof PsiMethodCallExpression) {
+ List<MethodContract> result = handleDelegation(((PsiExpressionStatement)statements[0]).getExpression(), false);
+ if (result != null) return result;
+ }
+ }
+
ValueConstraint[] emptyState = MethodContract.createConstraintArray(myMethod.getParameterList().getParametersCount());
return visitStatements(Collections.singletonList(emptyState), statements);
}
+ @Nullable
+ private List<MethodContract> handleDelegation(final PsiExpression expression, final boolean negated) {
+ if (expression instanceof PsiParenthesizedExpression) {
+ return handleDelegation(((PsiParenthesizedExpression)expression).getExpression(), negated);
+ }
+
+ if (expression instanceof PsiPrefixExpression && ((PsiPrefixExpression)expression).getOperationTokenType() == JavaTokenType.EXCL) {
+ return handleDelegation(((PsiPrefixExpression)expression).getOperand(), !negated);
+ }
+
+ if (expression instanceof PsiMethodCallExpression) {
+ return handleCallDelegation((PsiMethodCallExpression)expression, negated);
+ }
+
+ return null;
+ }
+
+ private List<MethodContract> handleCallDelegation(PsiMethodCallExpression expression, final boolean negated) {
+ final PsiMethod targetMethod = expression.resolveMethod();
+ if (targetMethod == null) return Collections.emptyList();
+
+ final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
+ return RecursionManager.doPreventingRecursion(myMethod, true, new Computable<List<MethodContract>>() {
+ @Override
+ public List<MethodContract> compute() {
+ List<MethodContract> delegateContracts = ContractInference.inferContracts(targetMethod); //todo use explicit contracts, too
+ return ContainerUtil.mapNotNull(delegateContracts, new NullableFunction<MethodContract, MethodContract>() {
+ @Nullable
+ @Override
+ public MethodContract fun(MethodContract delegateContract) {
+ ValueConstraint[] answer = MethodContract.createConstraintArray(myMethod.getParameterList().getParametersCount());
+ for (int i = 0; i < delegateContract.arguments.length; i++) {
+ if (i >= arguments.length) return null;
+
+ ValueConstraint argConstraint = delegateContract.arguments[i];
+ if (argConstraint != ANY_VALUE) {
+ int paramIndex = resolveParameter(arguments[i]);
+ if (paramIndex < 0) {
+ if (argConstraint != getLiteralConstraint(arguments[i])) {
+ return null;
+ }
+ }
+ else {
+ answer = withConstraint(answer, paramIndex, argConstraint);
+ }
+ }
+ }
+ return new MethodContract(answer, negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue);
+ }
+ });
+ }
+ });
+ }
+
@NotNull
private List<MethodContract> visitExpression(final List<ValueConstraint[]> states, @Nullable PsiExpression expr) {
if (states.isEmpty()) return Collections.emptyList();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index 3b44c82f9398..1b6d1dfedfec 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -583,7 +583,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
if (dfaLeft instanceof DfaVariableValue) {
DfaVariableValue dfaVar = (DfaVariableValue)dfaLeft;
if (isUnknownState(dfaVar)) return true;
-
+
+ if (!dfaRelation.isInstanceOf()) {
+ if (((DfaTypeValue)dfaRight).isNotNull() && isNull(dfaVar)) {
+ return isNegated;
+ }
+ return true;
+ }
+
if (isNegated) {
DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue)dfaRight);
if (newState != null) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 29bcecd0a53f..522bd34a9cf7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -254,7 +254,9 @@ public class StandardInstructionVisitor extends InstructionVisitor {
DfaValue condition = factory.getRelationFactory().createRelation(argValue, expectedValue, EQEQ, invertCondition);
if (condition == null) {
if (!(argValue instanceof DfaConstValue)) {
- falseStates.addAll(states);
+ for (DfaMemoryState state : states) {
+ falseStates.add(state.createCopy());
+ }
continue;
}
condition = constFactory.createFromValue((argValue == expectedValue) != invertCondition, PsiType.BOOLEAN, null);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StringExpressionHelper.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StringExpressionHelper.java
index b187d80a3957..9d2530cd2eff 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StringExpressionHelper.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StringExpressionHelper.java
@@ -20,7 +20,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.Processor;
+import com.intellij.util.CommonProcessors;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -161,18 +161,20 @@ public class StringExpressionHelper {
@NotNull
public static Set<PsiMethodCallExpression> searchMethodCalls(@NotNull final PsiMethod psiMethod, @NotNull SearchScope searchScope) {
final Set<PsiMethodCallExpression> callExpressions = new com.intellij.util.containers.HashSet<PsiMethodCallExpression>();
- MethodReferencesSearch.search(psiMethod, searchScope, true).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference psiReference) {
- final PsiMethodCallExpression methodCallExpression =
- PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiMethodCallExpression.class);
-
- if (methodCallExpression != null) {
- callExpressions.add(methodCallExpression);
- }
- return true;
+ final CommonProcessors.CollectUniquesProcessor<PsiReference> consumer = new CommonProcessors.CollectUniquesProcessor<PsiReference>();
+
+ MethodReferencesSearch.search(psiMethod, searchScope, true).forEach(consumer);
+
+ for (PsiReference psiReference : consumer.getResults()) {
+ final PsiMethodCallExpression methodCallExpression =
+ PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiMethodCallExpression.class);
+
+ if (methodCallExpression != null) {
+ callExpressions.add(methodCallExpression);
}
- });
+ }
+
+
return callExpressions;
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
index 8343fc9e6a2c..3e70b2d4b673 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
@@ -52,7 +52,6 @@ public class DfaRelationValue extends DfaValue {
}
public DfaRelationValue createRelation(DfaValue dfaLeft, DfaValue dfaRight, IElementType relation, boolean negated) {
- if (dfaRight instanceof DfaTypeValue && INSTANCEOF_KEYWORD != relation) return null;
if (PLUS == relation) return null;
if (dfaLeft instanceof DfaVariableValue || dfaLeft instanceof DfaBoxedValue || dfaLeft instanceof DfaUnboxedValue
@@ -169,6 +168,10 @@ public class DfaRelationValue extends DfaValue {
return myRelation == EQEQ && myIsNegated || myRelation == GT && !myIsNegated || myRelation == GE && myIsNegated;
}
+ public boolean isInstanceOf() {
+ return myRelation == INSTANCEOF_KEYWORD;
+ }
+
@NonNls public String toString() {
return (isNegated() ? "not " : "") + myLeftOperand + " " + myRelation + " " + myRightOperand;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspectionBase.java
index 29169ddaf5a2..006e5d946c22 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspectionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -74,7 +74,7 @@ public class Java15APIUsageInspectionBase extends BaseJavaBatchLocalInspectionTo
loadForbiddenApi("ignore16List.txt", ourIgnored16ClassesAPI);
}
- private static Set<String> ourGenerifiedClasses = new HashSet<String>();
+ private static final Set<String> ourGenerifiedClasses = new HashSet<String>();
static {
ourGenerifiedClasses.add("javax.swing.JComboBox");
ourGenerifiedClasses.add("javax.swing.ListModel");
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java
index ecf21db51d47..d725158a5201 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java
@@ -18,11 +18,9 @@ package com.intellij.codeInspection.miscGenerics;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.psi.*;
-import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.containers.IntArrayList;
-import com.sun.corba.se.impl.corba.TCUtility;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,10 +45,12 @@ public class SuspiciousMethodCallUtil {
PsiMethod contains = MethodSignatureUtil.findMethodBySignature(collectionClass, containsSignature, false);
addMethod(contains, 0, patternMethods, indices);
- PsiClassType wildcardCollection = javaPsiFacade.getElementFactory().createType(collectionClass, PsiWildcardType.createUnbounded(manager));
- MethodSignature removeAllSignature = MethodSignatureUtil.createMethodSignature("removeAll", new PsiType[] {wildcardCollection}, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
- PsiMethod removeAll = MethodSignatureUtil.findMethodBySignature(collectionClass, removeAllSignature, false);
- addMethod(removeAll, 0, patternMethods, indices);
+ if (PsiUtil.isLanguageLevel5OrHigher(collectionClass)) {
+ PsiClassType wildcardCollection = javaPsiFacade.getElementFactory().createType(collectionClass, PsiWildcardType.createUnbounded(manager));
+ MethodSignature removeAllSignature = MethodSignatureUtil.createMethodSignature("removeAll", new PsiType[] {wildcardCollection}, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
+ PsiMethod removeAll = MethodSignatureUtil.findMethodBySignature(collectionClass, removeAllSignature, false);
+ addMethod(removeAll, 0, patternMethods, indices);
+ }
}
final PsiClass listClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_LIST, searchScope);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java
index dc28a7b340c0..14da43194fe7 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java
@@ -15,14 +15,11 @@
*/
package com.intellij.codeInspection.unusedSymbol;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
-import com.intellij.codeInspection.*;
-import com.intellij.psi.PsiElement;
+import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspectionTool implements CustomSuppressableInspectionTool {
+public class UnusedSymbolLocalInspectionBase extends BaseJavaLocalInspectionTool {
@NonNls public static final String SHORT_NAME = HighlightInfoType.UNUSED_SYMBOL_SHORT_NAME;
@NonNls public static final String DISPLAY_NAME = HighlightInfoType.UNUSED_SYMBOL_DISPLAY_NAME;
@NonNls public static final String UNUSED_PARAMETERS_SHORT_NAME = "UnusedParameters";
@@ -33,22 +30,4 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
public boolean CLASS = true;
public boolean PARAMETER = true;
public boolean REPORT_PARAMETER_FOR_PUBLIC_METHODS = true;
-
- @Override
- public boolean isSuppressedFor(@NotNull PsiElement element) {
- return isSuppressedFor(element, this);
- }
- public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
- return BaseJavaBatchLocalInspectionTool.isSuppressedFor(element, tool);
- }
- @Override
- public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
- String shortName = getShortName();
- HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
- if (key == null) {
- throw new AssertionError("HighlightDisplayKey.find(" + shortName + ") is null. Inspection: "+getClass());
- }
- SuppressQuickFix[] batchSuppressActions = BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(key);
- return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionActions(batchSuppressActions);
- }
}
diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml
index f9eca174d12c..cf601bbd0f76 100644
--- a/java/java-impl/java-impl.iml
+++ b/java/java-impl/java-impl.iml
@@ -48,13 +48,14 @@
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="java-analysis-impl" exported="" />
<orderEntry type="module" module-name="external-system-api" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="library" name="Xerces" level="project" />
<orderEntry type="library" name="Velocity" level="project" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="java-structure-view" exported="" />
<orderEntry type="module" module-name="spellchecker" />
+ <orderEntry type="library" name="nekohtml" level="project" />
</component>
<component name="copyright">
<Base>
diff --git a/java/java-impl/src/com/intellij/application/options/editor/JavaCodeFoldingOptionsProvider.java b/java/java-impl/src/com/intellij/application/options/editor/JavaCodeFoldingOptionsProvider.java
index 7657ea05396d..7a9aed06479c 100644
--- a/java/java-impl/src/com/intellij/application/options/editor/JavaCodeFoldingOptionsProvider.java
+++ b/java/java-impl/src/com/intellij/application/options/editor/JavaCodeFoldingOptionsProvider.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.options.BeanConfigurable;
public class JavaCodeFoldingOptionsProvider extends BeanConfigurable<JavaCodeFoldingSettings> implements CodeFoldingOptionsProvider {
public JavaCodeFoldingOptionsProvider() {
super(JavaCodeFoldingSettings.getInstance());
+ checkBox("INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS", ApplicationBundle.message("checkbox.collapse.boolean.parameters"));
checkBox("COLLAPSE_ONE_LINE_METHODS", ApplicationBundle.message("checkbox.collapse.one.line.methods"));
checkBox("COLLAPSE_ACCESSORS", ApplicationBundle.message("checkbox.collapse.simple.property.accessors"));
checkBox("COLLAPSE_INNER_CLASSES", ApplicationBundle.message("checkbox.collapse.inner.classes"));
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
index 81968fed0a5d..af5f14e25131 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
@@ -509,11 +509,9 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
if (entry instanceof LibraryOrderEntry) {
Library library = ((LibraryOrderEntry)entry).getLibrary();
LOG.assertTrue(library != null);
- final ModifiableRootModel rootModel = ModuleRootManager.getInstance(entry.getOwnerModule()).getModifiableModel();
final Library.ModifiableModel model = library.getModifiableModel();
model.addRoot(vFile, AnnotationOrderRootType.getInstance());
model.commit();
- rootModel.commit();
}
else if (entry instanceof ModuleSourceOrderEntry) {
final ModifiableRootModel model = ModuleRootManager.getInstance(entry.getOwnerModule()).getModifiableModel();
@@ -558,7 +556,6 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
annotation.delete();
break;
}
- if (compare < 0) break;
anchor = annotation;
}
XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(
diff --git a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
index 88c1aa63eb9b..59521b1d6c47 100644
--- a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java
@@ -250,7 +250,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
}
@Override
- public boolean includeSelfInGotoImplementation(final PsiElement element) {
+ public boolean includeSelfInGotoImplementation(@NotNull final PsiElement element) {
if (element instanceof PsiModifierListOwner && ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.ABSTRACT)) {
return false;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java
index df113a5a77a1..2fc06a2dabd5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java
@@ -52,7 +52,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class));
@Override
- public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet _result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet _result) {
if (parameters.getCompletionType() == CompletionType.CLASS_NAME ||
parameters.isExtendedCompletion() && mayContainClassName(parameters)) {
addAllClasses(parameters, _result);
@@ -151,9 +151,11 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
if (withInners && name != null) {
for (PsiClass inner : psiClass.getInnerClasses()) {
if (inner.hasModifierProperty(PsiModifier.STATIC)) {
- for (JavaPsiClassReferenceElement lookupInner : createClassLookupItems(inner, withInners, insertHandler, condition)) {
+ for (JavaPsiClassReferenceElement lookupInner : createClassLookupItems(inner, true, insertHandler, condition)) {
String forced = lookupInner.getForcedPresentableName();
- lookupInner.setForcedPresentableName(name + "." + (forced != null ? forced : inner.getName()));
+ String qualifiedName = name + "." + (forced != null ? forced : inner.getName());
+ lookupInner.setForcedPresentableName(qualifiedName);
+ lookupInner.setLookupString(qualifiedName);
result.add(lookupInner);
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
index d80b6b590c98..be6d8146ce3d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java
@@ -53,6 +53,8 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
}
PsiElement position = file.findElementAt(offset);
+ PsiJavaCodeReferenceElement ref = position != null && position.getParent() instanceof PsiJavaCodeReferenceElement ?
+ (PsiJavaCodeReferenceElement) position.getParent() : null;
PsiClass psiClass = item.getObject();
final Project project = context.getProject();
@@ -75,14 +77,8 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
return;
}
- if (position != null) {
- PsiElement parent = position.getParent();
- if (parent instanceof PsiJavaCodeReferenceElement) {
- final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)parent;
- if (PsiTreeUtil.getParentOfType(position, PsiDocTag.class) != null && ref.isReferenceTo(psiClass)) {
- return;
- }
- }
+ if (ref != null && PsiTreeUtil.getParentOfType(position, PsiDocTag.class) != null && ref.isReferenceTo(psiClass)) {
+ return;
}
OffsetKey refEnd = context.trackOffset(context.getTailOffset(), false);
@@ -92,7 +88,9 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
context.setAddCompletionChar(false);
}
- PsiTypeLookupItem.addImportForItem(context, psiClass);
+ if (ref == null || !ref.isQualified()) {
+ PsiTypeLookupItem.addImportForItem(context, psiClass);
+ }
if (context.getOffset(refEnd) < 0) {
return;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java
index e84eb2646ec0..f6871faea16e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java
@@ -41,7 +41,7 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut
}
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiElement position = parameters.getPosition();
JavaClassReference reference = findJavaClassReference(position.getContainingFile(), parameters.getOffset());
if (reference == null) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
index 20615a027a42..7310227a80f0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -53,6 +53,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Consumer;
+import com.intellij.util.ObjectUtils;
import com.intellij.util.PairConsumer;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
@@ -196,7 +197,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet _result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet _result) {
if (parameters.getCompletionType() != CompletionType.BASIC) {
return;
}
@@ -340,6 +341,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
final Object[] variants = reference.getVariants();
+ //noinspection ConstantConditions
if (variants == null) {
LOG.error("Reference=" + reference);
}
@@ -365,6 +367,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
else {
+ //noinspection deprecation
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
usedWords.add(element.getLookupString());
result.addElement(element);
@@ -434,7 +437,7 @@ public class JavaCompletionContributor extends CompletionContributor {
private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement,
CompletionParameters parameters) {
PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class);
- PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)pair.getParent();
+ PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)ObjectUtils.assertNotNull(pair).getParent();
PsiAnnotation anno = (PsiAnnotation)parameterList.getParent();
boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement);
PsiClass annoClass = null;
@@ -507,7 +510,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (psiElement().withParent(psiReferenceExpression().withFirstChild(psiReferenceExpression().referencing(psiClass()))).accepts(position)) {
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) {
final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
- if (shortcut != null) {
+ if (StringUtil.isNotEmpty(shortcut)) {
return "Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods";
}
}
@@ -517,7 +520,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (parameters.getCompletionType() != CompletionType.SMART && shouldSuggestSmartCompletion(parameters.getPosition())) {
if (CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.EDITING_COMPLETION_SMARTTYPE_GENERAL)) {
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
- if (shortcut != null) {
+ if (StringUtil.isNotEmpty(shortcut)) {
return CompletionBundle.message("completion.smart.hint", shortcut);
}
}
@@ -528,7 +531,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (psiTypes.length > 0) {
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_TOAR)) {
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
- if (shortcut != null) {
+ if (StringUtil.isNotEmpty(shortcut)) {
for (final PsiType psiType : psiTypes) {
final PsiType type = PsiUtil.extractIterableTypeParameter(psiType, false);
if (type != null) {
@@ -539,7 +542,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_ASLIST)) {
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
- if (shortcut != null) {
+ if (StringUtil.isNotEmpty(shortcut)) {
for (final PsiType psiType : psiTypes) {
if (psiType instanceof PsiArrayType) {
final PsiType componentType = ((PsiArrayType)psiType).getComponentType();
@@ -553,7 +556,7 @@ public class JavaCompletionContributor extends CompletionContributor {
if (CompletionUtil.shouldShowFeature(parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_CHAIN)) {
final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION);
- if (shortcut != null) {
+ if (StringUtil.isNotEmpty(shortcut)) {
return CompletionBundle.message("completion.smart.chain.hint", shortcut);
}
}
@@ -639,9 +642,12 @@ public class JavaCompletionContributor extends CompletionContributor {
final PsiFile file = context.getFile();
if (file instanceof PsiJavaFile) {
- JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
+ if (context.getInvocationCount() > 0) {
+ autoImport(file, context.getStartOffset() - 1, context.getEditor());
+ PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument());
+ }
- autoImport(file, context.getStartOffset() - 1, context.getEditor());
+ JavaCompletionUtil.initOffsets(file, context.getOffsetMap());
if (context.getCompletionType() == CompletionType.BASIC) {
if (semicolonNeeded(context.getEditor(), file, context.getStartOffset())) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
index d5b16a9bbcb5..1112738c5464 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -56,7 +56,6 @@ import com.intellij.util.PairConsumer;
import com.intellij.util.PairFunction;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -447,8 +446,10 @@ public class JavaCompletionUtil {
PsiSubstitutor plainSub = plainResult.getSubstitutor();
PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
+ PsiType returnType = method.getReturnType();
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
- Comparing.equal(plainSub.substitute(method.getReturnType()), castSub.substitute(method.getReturnType())) &&
+ returnType != null &&
+ castSub.substitute(returnType).isAssignableFrom(plainSub.substitute(returnType)) &&
processor.isAccessible(plainClass.findMethodBySignature(method, true))
) {
return item;
@@ -600,12 +601,7 @@ public class JavaCompletionUtil {
}
public static LookupItem setShowFQN(final LookupItem ret) {
- final PsiClass psiClass = (PsiClass)ret.getObject();
- @NonNls String packageName = PsiFormatUtil.getPackageDisplayName(psiClass);
-
- final String tailText = (String)ret.getAttribute(LookupItem.TAIL_TEXT_ATTR);
- ret.setAttribute(LookupItem.TAIL_TEXT_ATTR, StringUtil.notNullize(tailText) + " (" + packageName + ")");
- ret.setAttribute(LookupItem.TAIL_TEXT_SMALL_ATTR, "");
+ ret.setAttribute(JavaPsiClassReferenceElement.PACKAGE_NAME, PsiFormatUtil.getPackageDisplayName((PsiClass)ret.getObject()));
return ret;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
index 7e7e0955b560..49379c2c4f3e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java
@@ -140,7 +140,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
if (PsiJavaPatterns.psiElement(JavaDocTokenType.DOC_COMMENT_DATA).accepts(position)) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
index a484e4b1f4f9..a1d4a6f8ac81 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java
@@ -39,6 +39,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -63,7 +64,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
static final int MAX_SCOPE_SIZE_TO_SEARCH_UNRESOLVED = 50000;
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC && parameters.getCompletionType() != CompletionType.SMART) {
return;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
index 74bdc7ccc0a5..b409014c1fe8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.ResolveResult;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -28,7 +29,7 @@ import java.util.ArrayList;
public class JavaMethodMergingContributor extends CompletionContributor {
@Override
- public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
+ public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final CompletionParameters parameters = context.getParameters();
if (parameters.getCompletionType() != CompletionType.SMART && parameters.getCompletionType() != CompletionType.BASIC) {
return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
index a174ef437acf..f36f567199a0 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
@@ -27,6 +27,7 @@ import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.CollectConsumer;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -42,7 +43,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
index 43c19b0483b5..9934cddc90ff 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaPsiClassReferenceElement.java
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer;
import com.intellij.openapi.util.ClassConditionKey;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -41,6 +42,7 @@ import java.util.Set;
* @author peter
*/
public class JavaPsiClassReferenceElement extends LookupItem<Object> {
+ public static final Key<String> PACKAGE_NAME = Key.create("PACKAGE_NAME");
public static final ClassConditionKey<JavaPsiClassReferenceElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaPsiClassReferenceElement.class);
private final Object myClass;
private volatile Reference<PsiClass> myCache;
@@ -171,8 +173,9 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
presentation.setTailText(tailText, true);
}
- public static String getLocationString(LookupItem item) {
- return StringUtil.notNullize((String)item.getAttribute(LookupItem.TAIL_TEXT_ATTR));
+ public static String getLocationString(LookupItem<?> item) {
+ String pkgName = item.getAttribute(PACKAGE_NAME);
+ return pkgName == null ? "" : " (" + pkgName + ")";
}
private static String getName(final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
index 37dc0829f969..61d8abe18368 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java
@@ -352,7 +352,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
super.fillCompletionVariants(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
index 2960bd797dea..b60094ffbd6f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.completion;
+import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
@@ -29,8 +30,10 @@ import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.proximity.KnownElementWeigher;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
import java.util.Set;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
@@ -69,10 +72,32 @@ public class PreferByKindWeigher extends LookupElementWeigher {
}
private static Condition<PsiClass> createSuitabilityCondition(final PsiElement position) {
- if (IN_CATCH_TYPE.accepts(position) ||
- IN_MULTI_CATCH_TYPE.accepts(position) ||
- JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(position) ||
- INSIDE_METHOD_THROWS_CLAUSE.accepts(position)) {
+ if (IN_CATCH_TYPE.accepts(position) || IN_MULTI_CATCH_TYPE.accepts(position)) {
+ PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(position, PsiTryStatement.class);
+ final List<PsiClass> thrownExceptions = ContainerUtil.newArrayList();
+ if (tryStatement != null && tryStatement.getTryBlock() != null) {
+ for (PsiClassType type : ExceptionUtil.getThrownExceptions(tryStatement.getTryBlock())) {
+ ContainerUtil.addIfNotNull(thrownExceptions, type.resolve());
+ }
+ }
+ if (thrownExceptions.isEmpty()) {
+ ContainerUtil.addIfNotNull(thrownExceptions,
+ JavaPsiFacade.getInstance(position.getProject()).findClass(
+ CommonClassNames.JAVA_LANG_THROWABLE, position.getResolveScope()));
+ }
+ return new Condition<PsiClass>() {
+ @Override
+ public boolean value(PsiClass psiClass) {
+ for (PsiClass exception : thrownExceptions) {
+ if (InheritanceUtil.isInheritorOrSelf(psiClass, exception, true)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ }
+ else if (JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(position) || INSIDE_METHOD_THROWS_CLAUSE.accepts(position)) {
return new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
@@ -120,6 +145,7 @@ public class PreferByKindWeigher extends LookupElementWeigher {
collectionFactory,
expectedTypeMethod,
suitableClass,
+ improbableKeyword,
nonInitialized,
classLiteral,
classNameOrGlobalStatic,
@@ -138,10 +164,13 @@ public class PreferByKindWeigher extends LookupElementWeigher {
if (PsiKeyword.ELSE.equals(keyword) || PsiKeyword.FINALLY.equals(keyword)) {
return MyResult.probableKeyword;
}
- if (PsiKeyword.TRUE.equals(keyword) || PsiKeyword.FALSE.equals(keyword)) {
- boolean inReturn = PsiTreeUtil.getParentOfType(myPosition, PsiReturnStatement.class, false, PsiMember.class) != null;
+ if ((PsiKeyword.TRUE.equals(keyword) || PsiKeyword.FALSE.equals(keyword)) && myCompletionType == CompletionType.SMART) {
+ boolean inReturn = psiElement().withParents(PsiReferenceExpression.class, PsiReturnStatement.class).accepts(myPosition);
return inReturn ? MyResult.probableKeyword : MyResult.normal;
}
+ if (PsiKeyword.INTERFACE.equals(keyword) && psiElement().afterLeaf("@").accepts(myPosition)) {
+ return MyResult.improbableKeyword;
+ }
}
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java
index 62dbd0df8f79..9264599a4e1b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java
@@ -24,13 +24,14 @@ import com.intellij.openapi.module.ModuleUtil;
import com.intellij.psi.PsiClass;
import com.intellij.refactoring.ui.ClassNameReferenceEditor;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class RefactoringCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet resultSet) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet resultSet) {
if (parameters.getOriginalFile().getUserData(ClassNameReferenceEditor.CLASS_NAME_REFERENCE_FRAGMENT) == null) {
return;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java
index a57303044485..310cf1444e88 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java
@@ -21,6 +21,7 @@ import com.intellij.lang.StdLanguages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
@@ -28,7 +29,7 @@ import com.intellij.util.Consumer;
public class XmlBasicToClassNameDelegator extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
PsiFile file = position.getContainingFile();
if (parameters.getCompletionType() != CompletionType.BASIC ||
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
new file mode 100644
index 000000000000..ff851372e208
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodQualifierFix.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.codeInsight.daemon.QuickFixBundle;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.psi.*;
+import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class AddMethodQualifierFix implements IntentionAction {
+ private static final boolean UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode();
+
+ private final SmartPsiElementPointer<PsiMethodCallExpression> myMethodCall;
+ private List<PsiVariable> myCandidates = null;
+
+ public AddMethodQualifierFix(final PsiMethodCallExpression methodCallExpression) {
+ myMethodCall = SmartPointerManager.getInstance(methodCallExpression.getProject()).createSmartPsiElementPointer(methodCallExpression);
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ String text = QuickFixBundle.message("add.method.qualifier.fix.text", myCandidates.size() > 1 ? "" : myCandidates.get(0).getName());
+ if (myCandidates.size() > 1) {
+ text += "...";
+ }
+ return text;
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
+ final PsiMethodCallExpression element = myMethodCall.getElement();
+ if (element == null || !element.isValid()) {
+ return false;
+ }
+ if (myCandidates == null) {
+ findCandidates();
+ }
+ return myCandidates.size() != 0;
+ }
+
+ private void findCandidates() {
+ myCandidates = new ArrayList<PsiVariable>();
+ final PsiMethodCallExpression methodCallElement = myMethodCall.getElement();
+ final String methodName = methodCallElement.getMethodExpression().getReferenceName();
+ if (methodName == null) {
+ return;
+ }
+
+ for (final PsiVariable var : CreateFromUsageUtils.guessMatchingVariables(methodCallElement)) {
+ final PsiType type = var.getType();
+ if (!(type instanceof PsiClassType)) {
+ continue;
+ }
+ final PsiClass resolvedClass = ((PsiClassType)type).resolve();
+ if (resolvedClass == null) {
+ continue;
+ }
+ if (resolvedClass.findMethodsByName(methodName, true).length > 0) {
+ myCandidates.add(var);
+ }
+ }
+ }
+
+ @TestOnly
+ public List<PsiVariable> getCandidates() {
+ return myCandidates;
+ }
+
+ @Override
+ public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
+ if (myCandidates.size() == 1 || UNIT_TEST_MODE) {
+ qualify(myCandidates.get(0), editor);
+ }
+ else {
+ chooseAndQualify(editor);
+ }
+ }
+
+ private void chooseAndQualify(final Editor editor) {
+ final BaseListPopupStep<PsiVariable> step =
+ new BaseListPopupStep<PsiVariable>(QuickFixBundle.message("add.qualifier"), myCandidates) {
+ @Override
+ public PopupStep onChosen(final PsiVariable selectedValue, final boolean finalChoice) {
+ if (selectedValue != null && finalChoice) {
+ WriteCommandAction.runWriteCommandAction(selectedValue.getProject(), new Runnable() {
+ @Override
+ public void run() {
+ qualify(selectedValue, editor);
+ }
+ });
+ }
+ return FINAL_CHOICE;
+ }
+
+ @NotNull
+ @Override
+ public String getTextFor(final PsiVariable value) {
+ return ObjectUtils.assertNotNull(value.getName());
+ }
+
+ @Override
+ public Icon getIconFor(final PsiVariable aValue) {
+ return aValue.getIcon(0);
+ }
+ };
+
+ final ListPopupImpl popup = new ListPopupImpl(step);
+ popup.showInBestPositionFor(editor);
+ }
+
+ private void qualify(final PsiVariable qualifier, final Editor editor) {
+ final String qualifierPresentableText = qualifier.getName();
+ final PsiMethodCallExpression oldExpression = myMethodCall.getElement();
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(qualifier.getProject());
+ final PsiExpression expression = elementFactory
+ .createExpressionFromText(qualifierPresentableText + "." + oldExpression.getMethodExpression().getReferenceName() + "()", null);
+ final PsiElement replacedExpression = oldExpression.replace(expression);
+ editor.getCaretModel().moveToOffset(replacedExpression.getTextOffset() + replacedExpression.getTextLength());
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModuleDependencyFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModuleDependencyFix.java
index 348d052a81b4..f3b95702eac7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModuleDependencyFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddModuleDependencyFix.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
+import com.intellij.application.options.ModuleListCellRenderer;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.actions.AddImportAction;
import com.intellij.compiler.ModuleCompilerUtil;
@@ -22,7 +23,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
@@ -32,13 +32,11 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
@@ -115,15 +113,7 @@ class AddModuleDependencyFix extends OrderEntryFix {
}
else {
final JBList list = new JBList(myModules);
- list.setCellRenderer(new ListCellRendererWrapper<Module>() {
- @Override
- public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) {
- if (module != null) {
- setIcon(ModuleType.get(module).getIcon());
- setText(module.getName());
- }
- }
- });
+ list.setCellRenderer(new ModuleListCellRenderer());
final JBPopup popup = JBPopupFactory.getInstance().createListPopupBuilder(list)
.setTitle("Choose Module to Add Dependency on")
.setMovable(false)
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java
index 8e3fe5158d13..dce0d54e405b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeExtendsToImplementsFix.java
@@ -33,7 +33,8 @@ public class ChangeExtendsToImplementsFix extends ExtendsListFix {
public ChangeExtendsToImplementsFix(@NotNull PsiClass aClass, @NotNull PsiClassType classToExtendFrom) {
super(aClass, classToExtendFrom, true);
- myName = QuickFixBundle.message("exchange.extends.implements.keyword",
+ myName = myClassToExtendFrom == null ? getFamilyName() :
+ QuickFixBundle.message("exchange.extends.implements.keyword",
aClass.isInterface() == myClassToExtendFrom.isInterface() ? PsiKeyword.IMPLEMENTS : PsiKeyword.EXTENDS,
aClass.isInterface() == myClassToExtendFrom.isInterface() ? PsiKeyword.EXTENDS : PsiKeyword.IMPLEMENTS,
myClassToExtendFrom.getName());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
index dab9a3bb6208..72df2025348f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -33,6 +33,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
/**
* User: anna
* Date: 2/22/12
@@ -82,7 +84,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
return;
}
final boolean isSwitchOnString =
- switchExpressionType.equalsToText("java.lang.String");
+ switchExpressionType.equalsToText(JAVA_LANG_STRING);
boolean useEquals = isSwitchOnString;
if (!useEquals) {
final PsiClass aClass = PsiUtil.resolveClassInType(switchExpressionType);
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
index ee371f8e1206..e2dedf5ea3ec 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java
@@ -131,7 +131,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
return Result.CONTINUE;
}
if (PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class, false, PsiMember.class) != null) {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "{");
+ EditorModificationUtil.insertStringAtCaret(editor, "{");
TypedHandler.indentOpenedBrace(project, editor);
return Result.STOP;
}
@@ -169,7 +169,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
char charAt = editor.getDocument().getCharsSequence().charAt(offset);
if (charAt != ';') return false;
- EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
+ EditorModificationUtil.moveCaretRelatively(editor, 1);
return true;
}
@@ -209,7 +209,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
}
if (balance == 0) {
- EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
+ EditorModificationUtil.moveCaretRelatively(editor, 1);
return true;
}
@@ -248,12 +248,7 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
}
if (balance == 1) {
- if (editor.getCaretModel().supportsMultipleCarets()) {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, ">", 0);
- }
- else {
- editor.getDocument().insertString(offset, ">");
- }
+ editor.getDocument().insertString(offset, ">");
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java
index ff2f19d465c0..9d43379ce920 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/AfterSemicolonEnterProcessor.java
@@ -44,8 +44,8 @@ public class AfterSemicolonEnterProcessor implements EnterProcessor {
((PsiMethod) psiElement).hasModifierProperty(PsiModifier.NATIVE))) {
int errorOffset = getErrorElementOffset(psiElement);
int elementEndOffset = psiElement.getTextRange().getEndOffset();
- final CharSequence text = editor.getDocument().getCharsSequence();
if (psiElement instanceof PsiEnumConstant) {
+ final CharSequence text = editor.getDocument().getCharsSequence();
final int commaOffset = CharArrayUtil.shiftForwardUntil(text, elementEndOffset, ",");
if (commaOffset < text.length()) {
elementEndOffset = commaOffset + 1;
@@ -53,18 +53,13 @@ public class AfterSemicolonEnterProcessor implements EnterProcessor {
}
if (errorOffset >= 0 && errorOffset < elementEndOffset) {
+ final CharSequence text = editor.getDocument().getCharsSequence();
if (text.charAt(errorOffset) == ' ' && text.charAt(errorOffset + 1) == ';') {
errorOffset++;
}
}
editor.getCaretModel().moveToOffset(errorOffset >= 0 ? errorOffset : elementEndOffset);
- if (errorOffset < 0 &&
- isModified &&
- (elementEndOffset == text.length() || text.charAt(elementEndOffset) == '\n') &&
- (psiElement instanceof PsiExpressionStatement || psiElement instanceof PsiDeclarationStatement)) {
- JavaSmartEnterProcessor.plainEnter(editor);
- }
return isModified;
}
return false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java
index 1c51da143810..6d903cafb418 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/LiteralSelectioner.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,9 +22,12 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLiteralExpression;
+import com.intellij.psi.PsiType;
import java.util.List;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class LiteralSelectioner extends BasicSelectioner {
@Override
public boolean canSelect(PsiElement e) {
@@ -34,8 +37,10 @@ public class LiteralSelectioner extends BasicSelectioner {
}
private static boolean isStringLiteral(PsiElement element) {
- return element instanceof PsiLiteralExpression &&
- ((PsiLiteralExpression)element).getType().equalsToText("java.lang.String") && element.getText().startsWith("\"") && element.getText().endsWith("\"");
+ final PsiType type = element instanceof PsiLiteralExpression ? ((PsiLiteralExpression)element).getType() : null;
+ return type != null && type.equalsToText(JAVA_LANG_STRING)
+ && element.getText().startsWith("\"")
+ && element.getText().endsWith("\"");
}
@Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java
index daf5aa5eac74..899da3035ce5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddAnnotationIntention.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -64,6 +65,11 @@ public abstract class AddAnnotationIntention extends BaseIntentionAction {
return returnType != null && !(returnType instanceof PsiPrimitiveType);
}
+
+ if (owner instanceof PsiClass) {
+ return PsiUtil.isLanguageLevel8OrHigher(owner);
+ }
+
return true;
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java
index a26e78ac85c7..22abefb01c98 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.editorActions.FixDocCommentAction;
+import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -26,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Batkovich
*/
-public class AddJavadocIntention extends PsiElementBaseIntentionAction {
+public class AddJavadocIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
@Override
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
final PsiDocCommentOwner docCommentOwner = (PsiDocCommentOwner)element.getParent();
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java
index 84831e2dc6e2..4fba52583963 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java
@@ -48,7 +48,7 @@ public class DeannotateIntentionAction implements IntentionAction {
@Override
@NotNull
public String getText() {
- return CodeInsightBundle.message("deannotate.intention.action.text") + (myAnnotationName != null ? " " + myAnnotationName : "");
+ return CodeInsightBundle.message("deannotate.intention.action.text") + (myAnnotationName != null ? " " + myAnnotationName : "...");
}
@Override
@@ -59,6 +59,7 @@ public class DeannotateIntentionAction implements IntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
+ myAnnotationName = null;
PsiModifierListOwner listOwner = getContainer(editor, file);
if (listOwner != null) {
final ExternalAnnotationsManager externalAnnotationsManager = ExternalAnnotationsManager.getInstance(project);
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SwapIfStatementsIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SwapIfStatementsIntentionAction.java
new file mode 100644
index 000000000000..cd8ce8dd1dce
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SwapIfStatementsIntentionAction.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.intention.impl;
+
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class SwapIfStatementsIntentionAction extends PsiElementBaseIntentionAction {
+ @Override
+ public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
+ final PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
+ final PsiIfStatement nestedIfStatement = (PsiIfStatement) ifStatement.getElseBranch();
+ assert nestedIfStatement != null;
+
+ final PsiExpression condition = ifStatement.getCondition();
+ final PsiExpression nestedCondition = nestedIfStatement.getCondition();
+
+ final PsiStatement thenBranch = ifStatement.getThenBranch();
+ final PsiStatement nestedThenBranch = nestedIfStatement.getThenBranch();
+
+ assert condition != null;
+ assert nestedCondition != null;
+ assert thenBranch != null;
+ assert nestedThenBranch != null;
+
+ final PsiElement conditionCopy = condition.copy();
+ condition.replace(nestedCondition);
+ nestedCondition.replace(conditionCopy);
+
+ final PsiElement thenBranchCopy = thenBranch.copy();
+ thenBranch.replace(nestedThenBranch);
+ nestedThenBranch.replace(thenBranchCopy);
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
+ if (!(element instanceof PsiKeyword) || !PsiKeyword.ELSE.equals(element.getText())) {
+ return false;
+ }
+ final PsiElement parent = element.getParent();
+ return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getElseBranch() instanceof PsiIfStatement;
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Swap If Statements";
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
index e934a9f387cf..81f0204049b6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
@@ -762,6 +762,12 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
return new SurroundWithQuotesAnnotationParameterValueFix(value, expectedType);
}
+ @NotNull
+ @Override
+ public IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall) {
+ return new AddMethodQualifierFix(methodCall);
+ }
+
private static boolean timeToOptimizeImports(@NotNull PsiFile file) {
if (!CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) return false;
diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
index 49befb363437..a6d734b92d8e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
@@ -103,10 +103,11 @@ public class PsiTypeLookupItem extends LookupItem {
myImportFixer.handleInsert(context, this);
PsiElement position = context.getFile().findElementAt(context.getStartOffset());
- assert position != null;
- int genericsStart = context.getTailOffset();
- context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context)));
- JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1);
+ if (position != null) {
+ int genericsStart = context.getTailOffset();
+ context.getDocument().insertString(genericsStart, JavaCompletionUtil.escapeXmlIfNeeded(context, calcGenerics(position, context)));
+ JavaCompletionUtil.shortenReference(context.getFile(), genericsStart - 1);
+ }
int tail = context.getTailOffset();
String braces = StringUtil.repeat("[]", getBracketsCount());
diff --git a/java/java-impl/src/com/intellij/codeInspection/RemoveAssignmentFix.java b/java/java-impl/src/com/intellij/codeInspection/RemoveAssignmentFix.java
index b80e3a07121d..9db065ad321f 100644
--- a/java/java-impl/src/com/intellij/codeInspection/RemoveAssignmentFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/RemoveAssignmentFix.java
@@ -40,7 +40,7 @@ public class RemoveAssignmentFix extends RemoveInitializerFix {
if (!(parent instanceof PsiAssignmentExpression)) return;
final PsiExpression rExpression = ((PsiAssignmentExpression)parent).getRExpression();
final PsiElement gParent = parent.getParent();
- if (gParent instanceof PsiExpression && rExpression != null) {
+ if ((gParent instanceof PsiExpression || gParent instanceof PsiExpressionList) && rExpression != null) {
if (!FileModificationService.getInstance().prepareFileForWrite(gParent.getContainingFile())) return;
if (gParent instanceof PsiParenthesizedExpression) {
gParent.replace(rExpression);
diff --git a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java
index c3d61021c0d0..f9127f0b48a5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java
+++ b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +79,6 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
@Override
protected void analyze(@NotNull final Project project, @NotNull final AnalysisScope scope) {
-
PropertiesComponent.getInstance().setValue(ANNOTATE_LOCAL_VARIABLES, String.valueOf(myAnnotateLocalVariablesCb.isSelected()));
final ProgressManager progressManager = ProgressManager.getInstance();
@@ -174,7 +173,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
final String path = dialog.getResultingLibraryPath();
new WriteCommandAction(project) {
@Override
- protected void run(final Result result) throws Throwable {
+ protected void run(@NotNull final Result result) throws Throwable {
for (Module module : modulesWithoutAnnotations) {
OrderEntryFix.addBundledJarToRoots(project, null, module, null, AnnotationUtil.NOT_NULL, path);
}
@@ -206,8 +205,8 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
}
- private UsageInfo[] findUsages(final Project project,
- final AnalysisScope scope) {
+ private UsageInfo[] findUsages(@NotNull final Project project,
+ @NotNull final AnalysisScope scope) {
final NullityInferrer inferrer = new NullityInferrer(myAnnotateLocalVariablesCb.isSelected(), project);
final PsiManager psiManager = PsiManager.getInstance(project);
final Runnable searchForUsages = new Runnable() {
@@ -257,7 +256,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
try {
new WriteCommandAction(project, INFER_NULLITY_ANNOTATIONS) {
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(@NotNull Result result) throws Throwable {
final UsageInfo[] infos = computable.compute();
if (infos.length > 0) {
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, INFER_NULLITY_ANNOTATIONS, false);
@@ -287,7 +286,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
}
- private void showUsageView(final Project project, final UsageInfo[] usageInfos, AnalysisScope scope) {
+ private void showUsageView(@NotNull Project project, final UsageInfo[] usageInfos, @NotNull AnalysisScope scope) {
final UsageTarget[] targets = UsageTarget.EMPTY_ARRAY;
final Ref<Usage[]> convertUsagesRef = new Ref<Usage[]>();
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
@@ -326,7 +325,8 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
usageView.addPerformOperationAction(refactoringRunnable, INFER_NULLITY_ANNOTATIONS, canNotMakeString, INFER_NULLITY_ANNOTATIONS, false);
}
- private Factory<UsageSearcher> rerunFactory(final Project project, final AnalysisScope scope) {
+ @NotNull
+ private Factory<UsageSearcher> rerunFactory(@NotNull final Project project, @NotNull final AnalysisScope scope) {
return new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java
index 4f9fa882be6e..8150b618f8dc 100644
--- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java
@@ -25,6 +25,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
@@ -46,7 +47,7 @@ public class MagicCompletionContributor extends CompletionContributor {
private static final int PRIORITY = 100;
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
//if (parameters.getCompletionType() != CompletionType.SMART) return;
PsiElement pos = parameters.getPosition();
MagicConstantInspection.AllowedValues allowedValues = null;
diff --git a/java/java-impl/src/com/intellij/find/findUsages/FindThrowUsagesDialog.java b/java/java-impl/src/com/intellij/find/findUsages/FindThrowUsagesDialog.java
index 400acce6d8c2..e9c059eff080 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/FindThrowUsagesDialog.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/FindThrowUsagesDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.psi.impl.search.ThrowSearchUtil;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.StateRestoringCheckBox;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -32,9 +33,13 @@ public class FindThrowUsagesDialog extends JavaFindUsagesDialog<JavaThrowFindUsa
private boolean myHasFindWhatPanel;
private ThrowSearchUtil.Root [] myRoots;
- public FindThrowUsagesDialog(final PsiElement element, final Project project,
- final FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, boolean mustOpenInNewTab,
- boolean isSingleFile, FindUsagesHandler handler){
+ public FindThrowUsagesDialog(@NotNull PsiElement element,
+ @NotNull Project project,
+ @NotNull JavaThrowFindUsagesOptions findUsagesOptions,
+ boolean toShowInNewTab,
+ boolean mustOpenInNewTab,
+ boolean isSingleFile,
+ @NotNull FindUsagesHandler handler) {
super(element, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
}
@@ -92,7 +97,7 @@ public class FindThrowUsagesDialog extends JavaFindUsagesDialog<JavaThrowFindUsa
@Override
protected void doOKAction() {
- myFindUsagesOptions.putUserData(ThrowSearchUtil.THROW_SEARCH_ROOT_KEY, (ThrowSearchUtil.Root)myCbExns.getSelectedItem());
+ getFindUsagesOptions().setRoot((ThrowSearchUtil.Root)myCbExns.getSelectedItem());
super.doOKAction();
}
@@ -102,7 +107,7 @@ public class FindThrowUsagesDialog extends JavaFindUsagesDialog<JavaThrowFindUsa
setOKActionEnabled(true);
}
else{
- myFindUsagesOptions.putUserData(ThrowSearchUtil.THROW_SEARCH_ROOT_KEY, (ThrowSearchUtil.Root)myCbExns.getSelectedItem());
+ getFindUsagesOptions().setRoot((ThrowSearchUtil.Root)myCbExns.getSelectedItem());
final boolean hasSelected = isSelected(myCbUsages);
setOKActionEnabled(hasSelected);
}
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java
index 17f9650b3b24..65528fb8a921 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +36,7 @@ public abstract class JavaFindUsagesDialog<T extends JavaFindUsagesOptions> exte
boolean toShowInNewTab,
boolean mustOpenInNewTab,
boolean isSingleFile,
- FindUsagesHandler handler) {
+ @NotNull FindUsagesHandler handler) {
super(element, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
}
@@ -82,10 +82,12 @@ public abstract class JavaFindUsagesDialog<T extends JavaFindUsagesOptions> exte
}
}
+ @NotNull
protected final PsiElement getPsiElement() {
return myPsiElement;
}
+ @NotNull
protected T getFindUsagesOptions() {
return (T)myFindUsagesOptions;
}
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
index 3fd1161bb0ed..1791fd0d6e8e 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
@@ -220,9 +220,10 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
@Override
- protected Set<String> getStringsToSearch(final PsiElement element) {
+ protected Set<String> getStringsToSearch(@NotNull final PsiElement element) {
if (element instanceof PsiDirectory) { // normalize a directory to a corresponding package
- return getStringsToSearch(JavaDirectoryService.getInstance().getPackage((PsiDirectory)element));
+ PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)element);
+ return aPackage == null ? Collections.<String>emptySet() : getStringsToSearch(aPackage);
}
final Set<String> result = new HashSet<String>();
@@ -264,7 +265,8 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
else if (element instanceof XmlAttributeValue) {
ContainerUtil.addIfNotNull(result, ((XmlAttributeValue)element).getValue());
- } else {
+ }
+ else {
LOG.error("Unknown element type: " + element);
}
}
@@ -306,7 +308,7 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
@Override
public Boolean compute() {
if (ThrowSearchUtil.isSearchable (element) && options instanceof JavaThrowFindUsagesOptions && options.isUsages) {
- ThrowSearchUtil.Root root = options.getUserData(ThrowSearchUtil.THROW_SEARCH_ROOT_KEY);
+ ThrowSearchUtil.Root root = ((JavaThrowFindUsagesOptions)options).getRoot();
if (root == null) {
final ThrowSearchUtil.Root[] roots = ThrowSearchUtil.getSearchRoots(element);
if (roots != null && roots.length > 0) {
@@ -346,6 +348,9 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
else if (classOptions.isImplementingClasses){
if (!addImplementingClasses(psiClass, processor, classOptions)) return false;
+ }
+
+ if (classOptions.isImplementingClasses) {
FunctionalExpressionSearch.search(psiClass, classOptions.searchScope).forEach(new PsiElementProcessorAdapter<PsiFunctionalExpression>(
new PsiElementProcessor<PsiFunctionalExpression>() {
@Override
@@ -755,6 +760,7 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
+ @NotNull
@Override
public Collection<PsiReference> findReferencesToHighlight(@NotNull final PsiElement target, @NotNull final SearchScope searchScope) {
if (target instanceof PsiMethod) {
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java
index 2d28a8ddf57c..b78dfca59fe5 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesOptions.java
@@ -34,6 +34,7 @@ public abstract class JavaFindUsagesOptions extends FindUsagesOptions {
isUsages = true;
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (!super.equals(this)) return false;
@@ -42,6 +43,7 @@ public abstract class JavaFindUsagesOptions extends FindUsagesOptions {
return isSkipImportStatements == ((JavaFindUsagesOptions)o).isSkipImportStatements;
}
+ @Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (isSkipImportStatements ? 1 : 0);
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaThrowFindUsagesOptions.java b/java/java-impl/src/com/intellij/find/findUsages/JavaThrowFindUsagesOptions.java
index c90c6a675dee..4ccc0c4aef6e 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaThrowFindUsagesOptions.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaThrowFindUsagesOptions.java
@@ -1,16 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.find.findUsages;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.impl.search.ThrowSearchUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class JavaThrowFindUsagesOptions extends JavaFindUsagesOptions {
+ private ThrowSearchUtil.Root root;
public JavaThrowFindUsagesOptions(@NotNull Project project) {
super(project);
isSearchForTextOccurrences = false;
}
+ public ThrowSearchUtil.Root getRoot() {
+ return root;
+ }
+
+ public void setRoot(ThrowSearchUtil.Root root) {
+ this.root = root;
+ }
}
diff --git a/java/java-impl/src/com/intellij/jarFinder/FindJarFix.java b/java/java-impl/src/com/intellij/jarFinder/FindJarFix.java
index 688788ae3c16..ee203e34deac 100644
--- a/java/java-impl/src/com/intellij/jarFinder/FindJarFix.java
+++ b/java/java-impl/src/com/intellij/jarFinder/FindJarFix.java
@@ -31,7 +31,7 @@ import com.intellij.util.NotNullFunction;
import com.intellij.util.PlatformIcons;
import com.intellij.util.download.DownloadableFileDescription;
import com.intellij.util.download.DownloadableFileService;
-import org.apache.xerces.parsers.DOMParser;
+import org.cyberneko.html.parsers.DOMParser;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
@@ -40,11 +40,8 @@ import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.swing.*;
-import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
import java.util.*;
/**
@@ -129,22 +126,9 @@ public abstract class FindJarFix<T extends PsiElement> implements IntentionActio
final Runnable runnable = new Runnable() {
public void run() {
try {
- Document doc;
-
- DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
- builderFactory.setExpandEntityReferences(false);
- builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
-
- URL url = new URL(CLASS_ROOT_URL + fqn.replace('.', '/') + CLASS_PAGE_EXT);
-
- InputStream stream = url.openStream();
- try {
- doc = builderFactory.newDocumentBuilder().parse(stream);
- }
- finally {
- stream.close();
- }
-
+ final DOMParser parser = new DOMParser();
+ parser.parse(CLASS_ROOT_URL + fqn.replace('.', '/') + CLASS_PAGE_EXT);
+ final Document doc = parser.getDocument();
if (doc != null) {
final NodeList links = doc.getElementsByTagName(LINK_TAG_NAME);
for (int i = 0; i < links.getLength(); i++) {
diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java b/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java
index 6daedef21ef9..d933576fc697 100644
--- a/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java
+++ b/java/java-impl/src/com/intellij/openapi/roots/impl/JavaLanguageLevelPusher.java
@@ -37,7 +37,7 @@ import java.io.IOException;
* @author Gregory.Shrago
*/
public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel> {
- public static void pushLanguageLevel(final Project project) {
+ public static void pushLanguageLevel(@NotNull final Project project) {
PushedFilePropertiesUpdater.getInstance(project).pushAll(new JavaLanguageLevelPusher());
}
diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java b/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
index 01114788ac9d..b7b5a05aef28 100644
--- a/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
+++ b/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
@@ -5,7 +5,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.search.NonClasspathDirectoryScope;
+import com.intellij.psi.search.NonClasspathDirectoriesScope;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +25,7 @@ public class NonClasspathResolveScopeEnlarger extends ResolveScopeEnlarger {
final List<VirtualFile> roots = ((NonClasspathClassFinder)finder).getClassRoots();
for (VirtualFile root : roots) {
if (VfsUtil.isAncestor(root, file, true)) {
- return NonClasspathDirectoryScope.compose(roots);
+ return NonClasspathDirectoriesScope.compose(roots);
}
}
}
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/FieldDependenciesManager.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/FieldDependenciesManager.java
new file mode 100644
index 000000000000..cea1c9e07f4c
--- /dev/null
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/FieldDependenciesManager.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.codeStyle.arrangement;
+
+import com.intellij.psi.PsiField;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class FieldDependenciesManager {
+ private final Map<PsiField, Set<PsiField>> myFieldDependencies;
+ private final Map<PsiField, ArrangementEntryDependencyInfo> myFieldInfosMap = ContainerUtil.newHashMap();
+
+ public FieldDependenciesManager(@NotNull Map<PsiField, Set<PsiField>> fieldDependencies, @NotNull Map<PsiField, JavaElementArrangementEntry> fields) {
+ myFieldDependencies = fieldDependencies;
+ for (PsiField field : fields.keySet()) {
+ JavaElementArrangementEntry entry = fields.get(field);
+ myFieldInfosMap.put(field, new ArrangementEntryDependencyInfo(entry));
+ }
+ }
+
+ @NotNull
+ public List<ArrangementEntryDependencyInfo> getRoots() {
+ List<ArrangementEntryDependencyInfo> list = ContainerUtil.newArrayList();
+
+ for (Map.Entry<PsiField, Set<PsiField>> entry : myFieldDependencies.entrySet()) {
+ ArrangementEntryDependencyInfo currentInfo = myFieldInfosMap.get(entry.getKey());
+
+ for (PsiField usedInInitialization : entry.getValue()) {
+ ArrangementEntryDependencyInfo fieldInfo = myFieldInfosMap.get(usedInInitialization);
+ if (fieldInfo != null)
+ currentInfo.addDependentEntryInfo(fieldInfo);
+ }
+
+ list.add(currentInfo);
+ }
+
+ return list;
+ }
+} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
index 2796fecea024..f042bb316c40 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
@@ -27,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-import java.util.HashMap;
-import java.util.HashSet;
/**
* @author Denis Zhdanov
@@ -36,28 +34,22 @@ import java.util.HashSet;
*/
public class JavaArrangementParseInfo {
- @NotNull private final List<JavaElementArrangementEntry> myEntries = new ArrayList<JavaElementArrangementEntry>();
+ private final List<JavaElementArrangementEntry> myEntries = new ArrayList<JavaElementArrangementEntry>();
- @NotNull private final Map<Pair<String/* property name */, String/* class name */>, JavaArrangementPropertyInfo> myProperties
- = new HashMap<Pair<String, String>, JavaArrangementPropertyInfo>();
+ private final Map<Pair<String/* property name */, String/* class name */>, JavaArrangementPropertyInfo> myProperties = new HashMap<Pair<String, String>, JavaArrangementPropertyInfo>();
- @NotNull private final List<ArrangementEntryDependencyInfo> myMethodDependencyRoots
- = new ArrayList<ArrangementEntryDependencyInfo>();
+ private final List<ArrangementEntryDependencyInfo> myMethodDependencyRoots = new ArrayList<ArrangementEntryDependencyInfo>();
+ private final Map<PsiMethod /* anchor */, Set<PsiMethod /* dependencies */>> myMethodDependencies = new HashMap<PsiMethod, Set<PsiMethod>>();
- @NotNull private final Map<PsiMethod /* anchor */, Set<PsiMethod /* dependencies */>> myMethodDependencies
- = new HashMap<PsiMethod, Set<PsiMethod>>();
+ private final Map<PsiMethod, JavaElementArrangementEntry> myMethodEntriesMap = new HashMap<PsiMethod, JavaElementArrangementEntry>();
+ private final Map<PsiClass, List<Pair<PsiMethod/*overridden*/, PsiMethod/*overriding*/>>> myOverriddenMethods = new LinkedHashMap<PsiClass, List<Pair<PsiMethod, PsiMethod>>>();
- @NotNull private final Map<PsiMethod, JavaElementArrangementEntry> myMethodEntriesMap =
- new HashMap<PsiMethod, JavaElementArrangementEntry>();
-
- @NotNull private final Map<PsiClass, List<Pair<PsiMethod/*overridden*/, PsiMethod/*overriding*/>>> myOverriddenMethods
- = new LinkedHashMap<PsiClass, List<Pair<PsiMethod, PsiMethod>>>();
-
- @NotNull private final Set<PsiMethod> myTmpMethodDependencyRoots = new LinkedHashSet<PsiMethod>();
- @NotNull private final Set<PsiMethod> myDependentMethods = new HashSet<PsiMethod>();
+ private final Set<PsiMethod> myTmpMethodDependencyRoots = new LinkedHashSet<PsiMethod>();
+ private final Set<PsiMethod> myDependentMethods = new HashSet<PsiMethod>();
private boolean myRebuildMethodDependencies;
- @NotNull private FieldDependenciesManager myFieldDependenciesManager = new FieldDependenciesManager();
+ private final HashMap<PsiField, JavaElementArrangementEntry> myFields = ContainerUtil.newLinkedHashMap();
+ private final Map<PsiField, Set<PsiField>> myFieldDependencies = ContainerUtil.newHashMap();
@NotNull
public List<JavaElementArrangementEntry> getEntries() {
@@ -96,8 +88,7 @@ public class JavaArrangementParseInfo {
@Nullable
private ArrangementEntryDependencyInfo buildMethodDependencyInfo(@NotNull final PsiMethod method,
- @NotNull Map<PsiMethod, ArrangementEntryDependencyInfo> cache)
- {
+ @NotNull Map<PsiMethod, ArrangementEntryDependencyInfo> cache) {
JavaElementArrangementEntry entry = myMethodEntriesMap.get(method);
if (entry == null) {
return null;
@@ -158,7 +149,7 @@ public class JavaArrangementParseInfo {
}
public void onFieldEntryCreated(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) {
- myFieldDependenciesManager.registerFieldAndEntry(field, entry);
+ myFields.put(field, entry);
}
public void onOverriddenMethod(@NotNull PsiMethod baseMethod, @NotNull PsiMethod overridingMethod) {
@@ -201,7 +192,7 @@ public class JavaArrangementParseInfo {
result.add(info);
}
}
-
+
return result;
}
@@ -226,49 +217,21 @@ public class JavaArrangementParseInfo {
}
public void registerFieldInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) {
- myFieldDependenciesManager.registerInitializationDependency(fieldToInitialize, usedInInitialization);
+ Set<PsiField> fields = myFieldDependencies.get(fieldToInitialize);
+ if (fields == null) {
+ fields = ContainerUtil.newHashSet();
+ myFieldDependencies.put(fieldToInitialize, fields);
+ }
+ fields.add(usedInInitialization);
}
@NotNull
public List<ArrangementEntryDependencyInfo> getFieldDependencyRoots() {
- return myFieldDependenciesManager.getRoots();
+ return new FieldDependenciesManager(myFieldDependencies, myFields).getRoots();
}
- private static class FieldDependenciesManager {
- private final Map<PsiField, Set<PsiField>> myFieldDependencies = ContainerUtil.newHashMap();
- private final Map<PsiField, ArrangementEntryDependencyInfo> myFieldInfosMap = ContainerUtil.newHashMap();
-
-
- public void registerFieldAndEntry(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) {
- myFieldInfosMap.put(field, new ArrangementEntryDependencyInfo(entry));
- }
-
- public void registerInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) {
- Set<PsiField> fields = myFieldDependencies.get(fieldToInitialize);
- if (fields == null) {
- fields = new HashSet<PsiField>();
- myFieldDependencies.put(fieldToInitialize, fields);
- }
- fields.add(usedInInitialization);
- }
-
- @NotNull
- public List<ArrangementEntryDependencyInfo> getRoots() {
- List<ArrangementEntryDependencyInfo> list = ContainerUtil.newArrayList();
-
- for (Map.Entry<PsiField, Set<PsiField>> entry : myFieldDependencies.entrySet()) {
- ArrangementEntryDependencyInfo currentInfo = myFieldInfosMap.get(entry.getKey());
-
- for (PsiField usedInInitialization : entry.getValue()) {
- ArrangementEntryDependencyInfo fieldInfo = myFieldInfosMap.get(usedInInitialization);
- if (fieldInfo != null)
- currentInfo.addDependentEntryInfo(fieldInfo);
- }
-
- list.add(currentInfo);
- }
-
- return list;
- }
+ @NotNull
+ public Collection<JavaElementArrangementEntry> getFields() {
+ return myFields.values();
}
} \ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
index e35cc50379dd..9e23eadc3073 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
@@ -34,8 +35,6 @@ import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
-import com.intellij.psi.codeStyle.arrangement.std.ArrangementColorsAware;
-import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsAware;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
@@ -46,10 +45,10 @@ import java.util.*;
import java.util.List;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.EntryType.*;
+import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.General.*;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Grouping.*;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*;
import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.*;
-import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.General.*;
/**
* @author Denis Zhdanov
@@ -250,16 +249,29 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
setupOverriddenMethods(parseInfo);
}
}
- setupFieldInitializationDependencies(parseInfo.getFieldDependencyRoots());
+ List<ArrangementEntryDependencyInfo> fieldDependencyRoots = parseInfo.getFieldDependencyRoots();
+ if (!fieldDependencyRoots.isEmpty()) {
+ setupFieldInitializationDependencies(fieldDependencyRoots, settings, parseInfo);
+ }
return parseInfo.getEntries();
}
+ public void setupFieldInitializationDependencies(@NotNull List<ArrangementEntryDependencyInfo> fieldDependencyRoots,
+ @NotNull ArrangementSettings settings,
+ @NotNull JavaArrangementParseInfo parseInfo)
+ {
+ Collection<JavaElementArrangementEntry> fields = parseInfo.getFields();
+ List<JavaElementArrangementEntry> arrangedFields = ArrangementEngine.arrange(fields, settings.getSections(), settings.getRulesSortedByPriority(), null);
+
+ for (ArrangementEntryDependencyInfo root : fieldDependencyRoots) {
+ JavaElementArrangementEntry anchorField = root.getAnchorEntry();
+ final int anchorEntryIndex = arrangedFields.indexOf(anchorField);
- public void setupFieldInitializationDependencies(@NotNull List<ArrangementEntryDependencyInfo> list) {
- for (ArrangementEntryDependencyInfo info : list) {
- JavaElementArrangementEntry anchorField = info.getAnchorEntry();
- for (ArrangementEntryDependencyInfo fieldUsedInInitialization : info.getDependentEntriesInfos()) {
- anchorField.addDependency(fieldUsedInInitialization.getAnchorEntry());
+ for (ArrangementEntryDependencyInfo fieldInInitializerInfo : root.getDependentEntriesInfos()) {
+ JavaElementArrangementEntry fieldInInitializer = fieldInInitializerInfo.getAnchorEntry();
+ if (arrangedFields.indexOf(fieldInInitializer) > anchorEntryIndex) {
+ anchorField.addDependency(fieldInInitializer);
+ }
}
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateBeanPropertyFix.java b/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateBeanPropertyFix.java
index 053a534e0c98..a53bd1c9d187 100644
--- a/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateBeanPropertyFix.java
+++ b/java/java-impl/src/com/intellij/psi/impl/beanProperties/CreateBeanPropertyFix.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +34,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
/**
* @author Dmitry Avdeev
*/
@@ -59,7 +61,7 @@ public abstract class CreateBeanPropertyFix implements LocalQuickFix, IntentionA
if (type == null) {
final Project project = psiClass.getProject();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
- final PsiClass aClass = facade.findClass("java.lang.String", GlobalSearchScope.allScope(project));
+ final PsiClass aClass = facade.findClass(JAVA_LANG_STRING, GlobalSearchScope.allScope(project));
if (aClass == null) {
return NO_FIXES;
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/ThrowSearchUtil.java b/java/java-impl/src/com/intellij/psi/impl/search/ThrowSearchUtil.java
index f3adf354de41..9375561d92e1 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/ThrowSearchUtil.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/ThrowSearchUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.search;
import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.psi.util.PsiFormatUtil;
@@ -34,34 +33,29 @@ import java.util.Set;
* Author: msk
*/
public class ThrowSearchUtil {
-
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.ThrowSearchUtil");
private ThrowSearchUtil() {
}
public static class Root {
- final PsiElement myElement;
- final PsiType myType;
- final boolean isExact;
+ @NotNull private final PsiElement myElement;
+ @NotNull private final PsiType myType;
+ private final boolean isExact;
- public Root(final PsiElement root, final PsiType type, final boolean exact) {
+ public Root(@NotNull PsiElement root, @NotNull PsiType type, final boolean exact) {
myElement = root;
myType = type;
isExact = exact;
}
+ @Override
public String toString() {
return PsiFormatUtil.formatType(myType, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY);
}
}
- public static Key<Root> THROW_SEARCH_ROOT_KEY = Key.create("ThrowSearchUtil.root");
-
/**
- * @param aCatch
- * @param processor
- * @param root
* @return true, if we should continue processing
*/
private static boolean processExn(@NotNull PsiParameter aCatch, @NotNull Processor<UsageInfo> processor, @NotNull Root root) {
@@ -123,7 +117,6 @@ public class ThrowSearchUtil {
}
/**
- * @param exn
* @return is type of exn exactly known
*/
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java
new file mode 100644
index 000000000000..db1a385d5137
--- /dev/null
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaCharsetReferenceContributor.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.impl.source.resolve.reference.impl;
+
+import com.intellij.codeInsight.daemon.impl.analysis.encoding.EncodingReference;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.StringLiteralManipulator;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+import java.nio.charset.Charset;
+
+import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
+import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
+import static com.intellij.patterns.StandardPatterns.string;
+
+/**
+ * @author peter
+ */
+public class JavaCharsetReferenceContributor extends PsiReferenceContributor {
+ @Override
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
+ registrar.registerReferenceProvider(
+ literalExpression().methodCallParameter(
+ 0, psiMethod().withName(string().oneOf("forName", "isSupported")).inClass(Charset.class.getName())),
+ new PsiReferenceProvider() {
+ @NotNull
+ @Override
+ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
+ PsiLiteralExpression literal = (PsiLiteralExpression)element;
+ Object value = literal.getValue();
+ if (value instanceof String) {
+ return new PsiReference[]{new EncodingReference(element, (String)value, StringLiteralManipulator.getValueRange(literal))};
+ }
+ return PsiReference.EMPTY_ARRAY;
+ }
+ });
+ }
+}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java
index 06e5d4a672f4..dbcc03041c6f 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +19,7 @@ import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.psi.PsiLiteral;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
+import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.PsiJavaPatterns.psiExpression;
import static com.intellij.patterns.PsiJavaPatterns.psiLiteral;
@@ -38,7 +39,7 @@ public class JavaReflectionReferenceContributor extends PsiReferenceContributor
.definedInClass(JAVA_LANG_CLASS)));
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PATTERN, new JavaReflectionReferenceProvider());
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PackagePrefixFileSystemItemImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PackagePrefixFileSystemItemImpl.java
index 7b85d17470ed..ce56ac3a36ad 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PackagePrefixFileSystemItemImpl.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PackagePrefixFileSystemItemImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -37,11 +37,11 @@ import java.util.ArrayList;
* @author Gregory.Shrago
*/
class PackagePrefixFileSystemItemImpl extends PsiElementBase implements PsiFileSystemItem, PackagePrefixFileSystemItem {
- private final PsiDirectory myDirectory;
+ @NotNull private final PsiDirectory myDirectory;
private final int myIndex;
private final PsiPackage[] myPackages;
- public static PackagePrefixFileSystemItemImpl create(final PsiDirectory directory) {
+ public static PackagePrefixFileSystemItemImpl create(@NotNull PsiDirectory directory) {
final ArrayList<PsiPackage> packages = new ArrayList<PsiPackage>();
for (PsiPackage cur = JavaDirectoryService.getInstance().getPackage(directory); cur != null; cur = cur.getParentPackage()) {
packages.add(0, cur);
@@ -49,7 +49,7 @@ class PackagePrefixFileSystemItemImpl extends PsiElementBase implements PsiFileS
return new PackagePrefixFileSystemItemImpl(directory, 0, packages.toArray(new PsiPackage[packages.size()]));
}
- private PackagePrefixFileSystemItemImpl(final PsiDirectory directory, int index, final PsiPackage[] packages) {
+ private PackagePrefixFileSystemItemImpl(@NotNull PsiDirectory directory, int index, final PsiPackage[] packages) {
myDirectory = directory;
myIndex = index;
myPackages = packages;
@@ -249,6 +249,7 @@ class PackagePrefixFileSystemItemImpl extends PsiElementBase implements PsiFileS
return myDirectory.getIcon(flags);
}
+ @NotNull
@Override
public PsiDirectory getDirectory() {
return myDirectory;
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java
index 5ffbaec2217d..195f06fb9cd3 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,8 +22,8 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.PsiParameterizedCachedValue;
@@ -38,9 +38,8 @@ import java.util.List;
/**
* @author cdr
*/
-public class JavaConcatenationInjectorManager implements ModificationTracker {
+public class JavaConcatenationInjectorManager extends SimpleModificationTracker {
public static final ExtensionPointName<ConcatenationAwareInjector> CONCATENATION_INJECTOR_EP_NAME = ExtensionPointName.create("com.intellij.concatenationAwareInjector");
- private volatile long myModificationCounter;
public JavaConcatenationInjectorManager(Project project, PsiManagerEx psiManagerEx) {
final ExtensionPoint<ConcatenationAwareInjector> concatPoint = Extensions.getArea(project).getExtensionPoint(CONCATENATION_INJECTOR_EP_NAME);
@@ -58,7 +57,7 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
psiManagerEx.registerRunnableToRunOnAnyChange(new Runnable() {
@Override
public void run() {
- myModificationCounter++; // clear caches even on non-physical changes
+ incModificationCount(); // clear caches even on non-physical changes
}
});
}
@@ -67,11 +66,6 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
return ServiceManager.getService(project, JavaConcatenationInjectorManager.class);
}
- @Override
- public long getModificationCount() {
- return myModificationCounter;
- }
-
private static Pair<PsiElement,PsiElement[]> computeAnchorAndOperandsImpl(@NotNull PsiElement context) {
PsiElement element = context;
PsiElement parent = context.getParent();
@@ -228,6 +222,6 @@ public class JavaConcatenationInjectorManager implements ModificationTracker {
}
private void concatenationInjectorsChanged() {
- myModificationCounter++;
+ incModificationCount();
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/MyTestInjector.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/MyTestInjector.java
index 271eb0ca87b6..e9b8da7f7d20 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/MyTestInjector.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/injected/MyTestInjector.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -160,6 +160,7 @@ public class MyTestInjector {
private static void injectVariousStuffEverywhere(Disposable parent, final PsiManager psiManager) {
final Language ql = Language.findLanguageByID("JPAQL");
final Language js = Language.findLanguageByID("JavaScript");
+ final Language html = Language.findLanguageByID("HTML");
if (ql == null || js == null) return;
final Language ecma4 = Language.findLanguageByID("ECMA Script Level 4");
@@ -216,6 +217,7 @@ public class MyTestInjector {
inject(host, placesToInject, js);
return;
}
+
if ("jsprefix".equals(attrName)) {
inject(host, placesToInject, js, "function foo(doc, window){", "}");
return;
@@ -235,6 +237,10 @@ public class MyTestInjector {
inject(host, placesToInject, js);
return;
}
+ if ("htmlInject".equals(tag.getLocalName())) {
+ inject(host, placesToInject, html);
+ return;
+ }
if (ecma4 != null && "ecma4".equals(tag.getLocalName())) {
inject(host, placesToInject, ecma4);
return;
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index a9fe12d19126..75544f9d8ab9 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -244,8 +244,6 @@ public class ExtractMethodProcessor implements MatchProvider {
myOutputVariables = myControlFlowWrapper.getOutputVariables();
- checkCanBeChainedConstructor();
-
return chooseTargetClass(codeFragment, pass);
}
@@ -1287,6 +1285,9 @@ public class ExtractMethodProcessor implements MatchProvider {
if (!checkExitPoints()){
return false;
}
+
+ checkCanBeChainedConstructor();
+
if (extractPass != null) {
extractPass.pass(this);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalDialog.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalDialog.java
index 78d96096a8e7..f994eeb07db0 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalDialog.java
@@ -23,15 +23,15 @@ import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
-public class InlineLocalDialog extends InlineOptionsDialog {
+public class InlineLocalDialog extends AbstractInlineLocalDialog {
public static final String REFACTORING_NAME = RefactoringBundle.message("inline.method.title");
private final PsiVariable myVariable;
private int myOccurrencesNumber = -1;
- public InlineLocalDialog(Project project, PsiVariable variable, PsiJavaCodeReferenceElement ref, int occurrencesCount) {
- super(project, true, variable);
+ public InlineLocalDialog(Project project, PsiVariable variable, final PsiJavaCodeReferenceElement ref, int occurrencesCount) {
+ super(project, variable, ref, occurrencesCount);
myVariable = variable;
myInvokedOnReference = ref != null;
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
index 44fd8cb8f724..78e99d94ef51 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
@@ -147,15 +148,18 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
final Ref<Boolean> inlineAll = new Ref<Boolean>(true);
if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) {
int occurrencesCount = refsToInlineList.size();
- final InlineLocalDialog inlineLocalDialog = new InlineLocalDialog(project, local, refExpr, occurrencesCount);
- inlineLocalDialog.show();
- if (!inlineLocalDialog.isOK()){
- WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
- return;
- }
- if (refExpr != null && inlineLocalDialog.isInlineThis()) {
- refsToInlineList = Collections.<PsiElement>singletonList(refExpr);
- inlineAll.set(false);
+ if (refExpr != null && occurrencesCount > 1 || EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog()) {
+ final InlineLocalDialog inlineLocalDialog = new InlineLocalDialog(project, local, refExpr, occurrencesCount);
+ inlineLocalDialog.show();
+ if (!inlineLocalDialog.isOK()){
+ WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
+ return;
+ }
+
+ if (refExpr != null && inlineLocalDialog.isInlineThis()) {
+ refsToInlineList = Collections.<PsiElement>singletonList(refExpr);
+ inlineAll.set(false);
+ }
}
}
@@ -280,7 +284,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
finally {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(containingClass);
- project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(refactoringId, afterData);
+ project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(refactoringId, afterData);
}
}
};
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
index 071e2cf59bbc..4bae67e08f16 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -268,7 +268,7 @@ class IntroduceConstantDialog extends DialogWrapper {
}
final PsiManager psiManager = PsiManager.getInstance(myProject);
- if ((myTypeSelectorManager.isSuggestedType("java.lang.String") || (myLocalVariable != null && AnnotationUtil.isAnnotated(myLocalVariable, AnnotationUtil.NON_NLS, false, false)))&&
+ if ((myTypeSelectorManager.isSuggestedType(CommonClassNames.JAVA_LANG_STRING) || (myLocalVariable != null && AnnotationUtil.isAnnotated(myLocalVariable, AnnotationUtil.NON_NLS, false, false)))&&
LanguageLevelProjectExtension.getInstance(psiManager.getProject()).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5) &&
JavaPsiFacade.getInstance(psiManager.getProject()).findClass(AnnotationUtil.NON_NLS, myParentClass.getResolveScope()) != null) {
final PropertiesComponent component = PropertiesComponent.getInstance(myProject);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
index e24c40dbfe32..5bd1c20a0b1e 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java
@@ -180,7 +180,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
}
else {
final PsiReferenceParameterList parameterList = refExpr.getParameterList();
- if (parameterList != null && parameterList.getTypeArguments().length == 0){
+ if (parameterList != null && parameterList.getTypeArguments().length == 0 && !(refExpr instanceof PsiMethodReferenceExpression)){
refExpr.setQualifierExpression(null);
} else {
final Project project = element.getProject();
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
index 4f3bf58ab4ab..9e19232ede36 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
@@ -20,10 +20,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameter;
+import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.impl.beanProperties.BeanProperty;
@@ -56,7 +53,11 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler {
private void performInvoke(@Nullable Editor editor, DataContext dataContext) {
final BeanProperty property = getProperty(dataContext);
- new PropertyRenameDialog(property, editor).show();
+ assert property != null;
+ PsiNamedElement element = property.getPsiElement();
+ if (PsiElementRenameHandler.canRename(element.getProject(), editor, element)) {
+ new PropertyRenameDialog(property, editor).show();
+ }
}
public static void doRename(@NotNull final BeanProperty property, final String newName, final boolean searchInComments, boolean isPreview) {
diff --git a/java/java-impl/src/com/intellij/slicer/SliceUtil.java b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
index f27701a88c67..6d556b5f9681 100644
--- a/java/java-impl/src/com/intellij/slicer/SliceUtil.java
+++ b/java/java-impl/src/com/intellij/slicer/SliceUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -64,14 +64,25 @@ public class SliceUtil {
expression = ((PsiArrayAccessExpression)expression).getArrayExpression();
indexNesting++;
}
- if (expression instanceof PsiExpressionList && indexNesting != 0 && expression.getParent() instanceof PsiMethodCallExpression) {
+ PsiElement par = expression == null ? null : expression.getParent();
+ if (expression instanceof PsiExpressionList && par instanceof PsiMethodCallExpression) {
// expression list ends up here if we track varargs
- // unfold varargs list into individual expressions
- PsiExpression[] expressions = ((PsiExpressionList)expression).getExpressions();
- for (PsiExpression arg : expressions) {
- if (!handToProcessor(arg, processor, parent, parentSubstitutor, indexNesting -1, syntheticField)) return false;
+ PsiMethod method = ((PsiMethodCallExpression)par).resolveMethod();
+ if (method != null) {
+ int parametersCount = method.getParameterList().getParametersCount();
+ if (parametersCount != 0) {
+ // unfold varargs list into individual expressions
+ PsiExpression[] expressions = ((PsiExpressionList)expression).getExpressions();
+ if (indexNesting != 0) {
+ // should skip not-vararg arguments
+ for (int i = parametersCount-1; i < expressions.length; i++) {
+ PsiExpression arg = expressions[i];
+ if (!handToProcessor(arg, processor, parent, parentSubstitutor, indexNesting - 1, syntheticField)) return false;
+ }
+ }
+ return true;
+ }
}
- return true;
}
boolean needToReportDeclaration = false;
@@ -409,7 +420,6 @@ public class SliceUtil {
PsiType actualExpressionType;
if (actualParameterType instanceof PsiEllipsisType) {
passExpression = argumentList;
- //passExpression = createArrayInitializerFromExpressions(argumentList, ((PsiEllipsisType)actualType).getComponentType(), expressions);
actualExpressionType = expressions[paramSeqNo].getType();
}
else {
@@ -446,6 +456,10 @@ public class SliceUtil {
if (substituted == null) return true;
PsiType typeToCheck;
if (actualParameterType instanceof PsiEllipsisType) {
+ // there may be the case of passing the vararg argument to the other vararg method: foo(int... ints) { bar(ints); } bar(int... ints) {}
+ if (TypeConversionUtil.areTypesConvertible(substituted, actualParameterType)) {
+ return handToProcessor(expressions[paramSeqNo], processor, parent, combined, indexNesting, syntheticField);
+ }
typeToCheck = ((PsiEllipsisType)actualParameterType).getComponentType();
}
else {
diff --git a/java/java-impl/src/com/intellij/spellchecker/JavaSpellcheckingStrategy.java b/java/java-impl/src/com/intellij/spellchecker/JavaSpellcheckingStrategy.java
index ee198727ffa8..0086b72ea0b1 100644
--- a/java/java-impl/src/com/intellij/spellchecker/JavaSpellcheckingStrategy.java
+++ b/java/java-impl/src/com/intellij/spellchecker/JavaSpellcheckingStrategy.java
@@ -15,23 +15,20 @@
*/
package com.intellij.spellchecker;
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;
-import com.intellij.codeInspection.BatchSuppressManager;
import com.intellij.codeInspection.SuppressManager;
-import com.intellij.codeInspection.SuppressQuickFix;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.javadoc.PsiDocComment;
-import com.intellij.spellchecker.tokenizer.SuppressibleSpellcheckingStrategy;
+import com.intellij.spellchecker.tokenizer.SpellcheckingStrategy;
import com.intellij.spellchecker.tokenizer.Tokenizer;
import org.jetbrains.annotations.NotNull;
/**
* @author shkate@jetbrains.com
*/
-public class JavaSpellcheckingStrategy extends SuppressibleSpellcheckingStrategy {
+public class JavaSpellcheckingStrategy extends SpellcheckingStrategy {
private final MethodNameTokenizerJava myMethodNameTokenizer = new MethodNameTokenizerJava();
private final DocCommentTokenizer myDocCommentTokenizer = new DocCommentTokenizer();
private final LiteralExpressionTokenizer myLiteralExpressionTokenizer = new LiteralExpressionTokenizer();
@@ -58,14 +55,4 @@ public class JavaSpellcheckingStrategy extends SuppressibleSpellcheckingStrategy
return super.getTokenizer(element);
}
-
- @Override
- public boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String name) {
- return SuppressManager.getInstance().isSuppressedFor(element, name);
- }
-
- @Override
- public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, @NotNull String name) {
- return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(name));
- }
}
diff --git a/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java b/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java
index 77246ec92763..2eade6903cd2 100644
--- a/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java
+++ b/java/java-impl/src/com/intellij/spellchecker/LiteralExpressionTokenizer.java
@@ -17,8 +17,10 @@ package com.intellij.spellchecker;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.spellchecker.inspections.PlainTextSplitter;
@@ -30,8 +32,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
/**
- * Created by IntelliJ IDEA.
- *
* @author shkate@jetbrains.com
*/
public class LiteralExpressionTokenizer extends Tokenizer<PsiLiteralExpression> {
@@ -42,6 +42,8 @@ public class LiteralExpressionTokenizer extends Tokenizer<PsiLiteralExpression>
return; // not a string literal
}
+ if (InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) return;
+
final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class);
if (listOwner != null && AnnotationUtil.isAnnotated(listOwner, Collections.singleton(AnnotationUtil.NON_NLS), false, false)) {
return;
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/AllClassesSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/AllClassesSearch.java
index 21027204c180..db8c54d08d69 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/AllClassesSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/AllClassesSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -58,7 +58,7 @@ public class AllClassesSearch extends ExtensibleQueryFactory<PsiClass, AllClasse
return myProject;
}
- public boolean nameMatches(String name) {
+ public boolean nameMatches(@NotNull String name) {
return myShortNameCondition.value(name);
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java
index abedbcbbda23..abca8f160a3d 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/VariableInIncompleteCodeSearcher.java
@@ -54,6 +54,7 @@ public class VariableInIncompleteCodeSearcher extends QueryExecutorBase<PsiRefer
if (element instanceof PsiJavaCodeReferenceElement) {
final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element;
if (!ref.isQualified() && name.equals(ref.getText()) &&
+ !(ref.getParent() instanceof PsiMethodCallExpression) &&
ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) {
consumer.process(ref);
}
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/folding/JavaCodeFoldingSettings.java b/java/java-psi-api/src/com/intellij/codeInsight/folding/JavaCodeFoldingSettings.java
index 360b9832431d..5e45853f2f0f 100644
--- a/java/java-psi-api/src/com/intellij/codeInsight/folding/JavaCodeFoldingSettings.java
+++ b/java/java-psi-api/src/com/intellij/codeInsight/folding/JavaCodeFoldingSettings.java
@@ -64,4 +64,7 @@ public abstract class JavaCodeFoldingSettings {
public abstract boolean isCollapseEndOfLineComments();
public abstract void setCollapseEndOfLineComments(boolean value);
+
+ public abstract boolean isInlineParameterNamesForLiteralCallArguments();
+ public abstract void setInlineParameterNamesForLiteralCallArguments(boolean value);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
index 55a5e9d55260..d1a1d7299d15 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
@@ -19,7 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
-import gnu.trove.THashSet;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -52,7 +52,7 @@ public class PsiIntersectionType extends PsiType.Stub {
private static PsiType[] flattenAndRemoveDuplicates(PsiType[] conjuncts) {
try {
- Set<PsiType> flattened = flatten(conjuncts, new THashSet<PsiType>());
+ Set<PsiType> flattened = flatten(conjuncts, ContainerUtil.<PsiType>newLinkedHashSet());
return flattened.toArray(createArray(flattened.size()));
}
catch (NoSuchElementException e) {
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index 4c0e4be87185..fe45c66cf024 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -33,6 +33,7 @@ public class PsiMethodReferenceUtil {
public static boolean hasReceiver(PsiType[] parameterTypes, QualifierResolveResult qualifierResolveResult, PsiMethodReferenceExpression methodRef) {
if (parameterTypes.length > 0 &&
+ !methodRef.isConstructor() &&
isReceiverType(parameterTypes[0], qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor()) &&
isStaticallyReferenced(methodRef)) {
return true;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiParameter.java b/java/java-psi-api/src/com/intellij/psi/PsiParameter.java
index dc8b0aefdabc..b7ad72a17c29 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiParameter.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiParameter.java
@@ -37,7 +37,7 @@ public interface PsiParameter extends PsiVariable {
};
/**
- * Returns the element (method, foreach statement or catch block) in which the
+ * Returns the element (method, lambda expression, foreach statement or catch block) in which the
* parameter is declared.
*
* @return the declaration scope for the parameter.
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index 917a88888d40..e7506ebd92fd 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -158,6 +158,7 @@ public class MethodCandidateInfo extends CandidateInfo{
return level;
}
+ @NotNull
public PsiSubstitutor getSiteSubstitutor() {
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
if (myTypeArguments != null) {
diff --git a/java/java-psi-api/src/com/intellij/psi/search/PackageScope.java b/java/java-psi-api/src/com/intellij/psi/search/PackageScope.java
index 19f72a8f91d5..a03f8849daa7 100644
--- a/java/java-psi-api/src/com/intellij/psi/search/PackageScope.java
+++ b/java/java-psi-api/src/com/intellij/psi/search/PackageScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -96,10 +96,12 @@ public class PackageScope extends GlobalSearchScope {
", includeSubpackages = " + myIncludeSubpackages;
}
+ @NotNull
public static GlobalSearchScope packageScope(@NotNull PsiPackage aPackage, boolean includeSubpackages) {
return new PackageScope(aPackage, includeSubpackages, true);
}
+ @NotNull
public static GlobalSearchScope packageScopeWithoutLibraries(@NotNull PsiPackage aPackage, boolean includeSubpackages) {
return new PackageScope(aPackage, includeSubpackages, false);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java b/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java
index 877094929876..dba92bebcb65 100644
--- a/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java
+++ b/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.util.Query;
import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -38,8 +39,8 @@ public class SuperMethodsSearch extends ExtensibleQueryFactory<MethodSignatureBa
private final boolean myCheckBases;
private final boolean myAllowStaticMethod;
- public SearchParameters(final PsiMethod method,
- @Nullable final PsiClass aClass,
+ public SearchParameters(@NotNull PsiMethod method,
+ @Nullable PsiClass aClass,
final boolean checkBases,
final boolean allowStaticMethod) {
myCheckBases = checkBases;
@@ -52,6 +53,7 @@ public class SuperMethodsSearch extends ExtensibleQueryFactory<MethodSignatureBa
return myCheckBases;
}
+ @NotNull
public final PsiMethod getMethod() {
return myMethod;
}
@@ -69,7 +71,11 @@ public class SuperMethodsSearch extends ExtensibleQueryFactory<MethodSignatureBa
private SuperMethodsSearch() {
}
- public static Query<MethodSignatureBackedByPsiMethod> search(final PsiMethod derivedMethod, @Nullable final PsiClass psiClass, boolean checkBases, boolean allowStaticMethod) {
+ @NotNull
+ public static Query<MethodSignatureBackedByPsiMethod> search(@NotNull PsiMethod derivedMethod,
+ @Nullable final PsiClass psiClass,
+ boolean checkBases,
+ boolean allowStaticMethod) {
final SearchParameters parameters = new SearchParameters(derivedMethod, psiClass, checkBases, allowStaticMethod);
return SUPER_METHODS_SEARCH_INSTANCE.createUniqueResultsQuery(parameters, MethodSignatureUtil.METHOD_BASED_HASHING_STRATEGY);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/IsConstantExpressionVisitor.java b/java/java-psi-api/src/com/intellij/psi/util/IsConstantExpressionVisitor.java
index 531edd732fae..be304ff5396f 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/IsConstantExpressionVisitor.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/IsConstantExpressionVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,8 @@ import gnu.trove.THashMap;
import java.util.Map;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class IsConstantExpressionVisitor extends JavaElementVisitor {
protected boolean myIsConstant;
private final Map<PsiVariable, Boolean> varIsConst = new THashMap<PsiVariable, Boolean>();
@@ -63,7 +65,7 @@ public class IsConstantExpressionVisitor extends JavaElementVisitor {
}
PsiType type = element.getType();
if (type instanceof PsiPrimitiveType) return;
- if (type.equalsToText("java.lang.String")) return;
+ if (type.equalsToText(JAVA_LANG_STRING)) return;
myIsConstant = false;
}
@@ -88,7 +90,7 @@ public class IsConstantExpressionVisitor extends JavaElementVisitor {
operand.accept(this);
if (!myIsConstant) return;
final PsiType type = operand.getType();
- if (type != null && !(type instanceof PsiPrimitiveType) && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+ if (type != null && !(type instanceof PsiPrimitiveType) && !type.equalsToText(JAVA_LANG_STRING)) {
myIsConstant = false;
return;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
index adc9306ec962..5d11f1fb5005 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -66,10 +66,12 @@ public class MethodSignatureBackedByPsiMethod extends MethodSignatureBase {
return myMethod;
}
+ @NotNull
public static MethodSignatureBackedByPsiMethod create(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) {
return create(method, substitutor, PsiUtil.isRawSubstitutor(method, substitutor));
}
+ @NotNull
public static MethodSignatureBackedByPsiMethod create(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor, boolean isRaw) {
PsiTypeParameter[] methodTypeParameters = method.getTypeParameters();
if (isRaw) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java
index feeb28037a5b..70c97495995b 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiConcatenationUtil.java
@@ -22,6 +22,8 @@ import com.intellij.util.IncorrectOperationException;
import java.util.List;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
/**
* User: cdr
*/
@@ -42,11 +44,11 @@ public class PsiConcatenationUtil {
formatString.append(formatText);
} else if (expression instanceof PsiPolyadicExpression) {
final PsiType type = expression.getType();
- if (type != null && type.equalsToText("java.lang.String")) {
+ if (type != null && type.equalsToText(JAVA_LANG_STRING)) {
final PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression) expression;
PsiExpression[] operands = binaryExpression.getOperands();
PsiType left = operands[0].getType();
- boolean stringStarted = left != null && left.equalsToText("java.lang.String");
+ boolean stringStarted = left != null && left.equalsToText(JAVA_LANG_STRING);
if (stringStarted) {
buildFormatString(operands[0], formatString, formatParameters, printfFormat);
}
@@ -54,7 +56,7 @@ public class PsiConcatenationUtil {
PsiExpression op = operands[i];
PsiType optype = op.getType();
PsiType r = TypeConversionUtil.calcTypeForBinaryExpression(left, optype, binaryExpression.getOperationTokenType(), true);
- if (r != null && r.equalsToText("java.lang.String") && !stringStarted) {
+ if (r != null && r.equalsToText(JAVA_LANG_STRING) && !stringStarted) {
stringStarted = true;
PsiElement element = binaryExpression.getTokenBeforeOperand(op);
if (element.getPrevSibling() instanceof PsiWhiteSpace) element = element.getPrevSibling();
@@ -64,7 +66,7 @@ public class PsiConcatenationUtil {
addFormatParameter(subExpression, formatString, formatParameters, printfFormat);
}
if (stringStarted) {
- if (optype != null && (optype.equalsToText("java.lang.String") || optype == PsiType.CHAR)) {
+ if (optype != null && (optype.equalsToText(JAVA_LANG_STRING) || optype == PsiType.CHAR)) {
buildFormatString(op, formatString, formatParameters, printfFormat);
}
else {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index c63a1373b00b..b71214f907f0 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -39,12 +39,15 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.EmptyIterable;
import com.intellij.util.containers.HashMap;
import gnu.trove.THashSet;
+import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public final class PsiUtil extends PsiUtilCore {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.PsiUtil");
@@ -311,19 +314,18 @@ public final class PsiUtil extends PsiUtilCore {
return false;
}
+ @MagicConstant(intValues = {ACCESS_LEVEL_PUBLIC, ACCESS_LEVEL_PROTECTED, ACCESS_LEVEL_PACKAGE_LOCAL, ACCESS_LEVEL_PRIVATE})
public static int getAccessLevel(@NotNull PsiModifierList modifierList) {
if (modifierList.hasModifierProperty(PsiModifier.PRIVATE)) {
return ACCESS_LEVEL_PRIVATE;
}
- else if (modifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
+ if (modifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
return ACCESS_LEVEL_PACKAGE_LOCAL;
}
- else if (modifierList.hasModifierProperty(PsiModifier.PROTECTED)) {
+ if (modifierList.hasModifierProperty(PsiModifier.PROTECTED)) {
return ACCESS_LEVEL_PROTECTED;
}
- else {
- return ACCESS_LEVEL_PUBLIC;
- }
+ return ACCESS_LEVEL_PUBLIC;
}
@PsiModifier.ModifierConstant
@@ -590,7 +592,7 @@ public final class PsiUtil extends PsiUtilCore {
*/
public static boolean isCompileTimeConstant(@NotNull final PsiField field) {
return field.hasModifierProperty(PsiModifier.FINAL)
- && (TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) || field.getType().equalsToText("java.lang.String"))
+ && (TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) || field.getType().equalsToText(JAVA_LANG_STRING))
&& field.hasInitializer()
&& isConstantExpression(field.getInitializer());
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
index 0fbfa4a059f9..d4382b40db7a 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java
@@ -504,8 +504,22 @@ public class RedundantCastUtil {
return;
}
if (parent instanceof PsiForeachStatement) {
- if (InheritanceUtil.isInheritor(PsiUtil.resolveClassInType(opType), false, CommonClassNames.JAVA_LANG_ITERABLE)) {
- addToResults(typeCast);
+ final PsiClassType.ClassResolveResult castResolveResult = PsiUtil.resolveGenericsClassInType(opType);
+ final PsiClass psiClass = castResolveResult.getElement();
+ if (psiClass != null) {
+ final PsiClass iterableClass = JavaPsiFacade.getInstance(parent.getProject()).findClass(CommonClassNames.JAVA_LANG_ITERABLE, psiClass.getResolveScope());
+ if (iterableClass != null && InheritanceUtil.isInheritorOrSelf(psiClass, iterableClass, true)) {
+ final PsiTypeParameter[] iterableTypeParameters = iterableClass.getTypeParameters();
+ if (iterableTypeParameters.length == 1) {
+ final PsiType resultedParamType = TypeConversionUtil.getSuperClassSubstitutor(iterableClass, psiClass, castResolveResult.getSubstitutor()).substitute(iterableTypeParameters[0]);
+ if (resultedParamType != null &&
+ TypeConversionUtil.isAssignable(((PsiForeachStatement)parent).getIterationParameter().getType(), resultedParamType)) {
+ addToResults(typeCast);
+ return;
+ }
+ }
+ }
+ } else {
return;
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
index 5a793b9ef340..477a74e64b2e 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -40,6 +40,8 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class TypeConversionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.TypeConversionUtil");
@@ -469,7 +471,7 @@ public class TypeConversionUtil {
int rank = TYPE_TO_RANK_MAP.get(type);
if (rank != 0) return rank;
- if (type.equalsToText("java.lang.String")) return STRING_RANK;
+ if (type.equalsToText(JAVA_LANG_STRING)) return STRING_RANK;
return Integer.MAX_VALUE;
}
@@ -531,12 +533,12 @@ public class TypeConversionUtil {
}
}
else if (tokenType == JavaTokenType.PLUS) {
- if (ltype.equalsToText("java.lang.String")) {
+ if (ltype.equalsToText(JAVA_LANG_STRING)) {
isApplicable = !isVoidType(rtype);
resultTypeRank = STRING_RANK;
break Label;
}
- else if (rtype.equalsToText("java.lang.String")) {
+ else if (rtype.equalsToText(JAVA_LANG_STRING)) {
isApplicable = !isVoidType(ltype);
resultTypeRank = STRING_RANK;
break Label;
@@ -1370,7 +1372,7 @@ public class TypeConversionUtil {
public static Object computeCastTo(final Object operand, final PsiType castType) {
if (operand == null || castType == null) return null;
Object value;
- if (operand instanceof String && castType.equalsToText("java.lang.String")) {
+ if (operand instanceof String && castType.equalsToText(JAVA_LANG_STRING)) {
value = operand;
}
else if (operand instanceof Boolean && PsiType.BOOLEAN.equals(castType)) {
@@ -1444,12 +1446,12 @@ public class TypeConversionUtil {
if (sign == JavaTokenType.PLUS) {
// evaluate right argument first, since '+-/*%' is left associative and left operand tends to be bigger
if (rType == null) return null;
- if (rType.equalsToText("java.lang.String")) {
+ if (rType.equalsToText(JAVA_LANG_STRING)) {
return rType;
}
if (!accessLType) return NULL_TYPE;
if (lType == null) return null;
- if (lType.equalsToText("java.lang.String")) {
+ if (lType.equalsToText(JAVA_LANG_STRING)) {
return lType;
}
return unboxAndBalanceTypes(lType, rType);
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
index 81dda5863402..5e13c8f780fc 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
@@ -57,7 +57,7 @@ public class TypesDistinctProver {
final PsiClass boundClass1 = PsiUtil.resolveClassInType(extendsBound);
if (boundClass1 == null) return false;
- if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass2.getQualifiedName())) {
+ if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass2.getQualifiedName()) && !(boundClass1 instanceof PsiTypeParameter)) {
return !CommonClassNames.JAVA_LANG_OBJECT.equals(boundClass1.getQualifiedName());
}
@@ -121,7 +121,7 @@ public class TypesDistinctProver {
if (substitutedType1 instanceof PsiWildcardType && !((PsiWildcardType)substitutedType1).isBounded()) return true;
}
}
- return false;
+ if (level < 2) return false;
}
final PsiClass boundClass1 = classResolveResult1.getElement();
diff --git a/java/java-psi-api/src/com/intellij/util/VisibilityIcons.java b/java/java-psi-api/src/com/intellij/util/VisibilityIcons.java
index 1988e63586a8..96d903a1a1b9 100644
--- a/java/java-psi-api/src/com/intellij/util/VisibilityIcons.java
+++ b/java/java-psi-api/src/com/intellij/util/VisibilityIcons.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -24,6 +24,7 @@ import com.intellij.psi.PsiModifierList;
import com.intellij.psi.util.PsiUtil;
import com.intellij.ui.RowIcon;
import com.intellij.util.ui.EmptyIcon;
+import org.intellij.lang.annotations.MagicConstant;
import javax.swing.*;
@@ -55,7 +56,7 @@ public class VisibilityIcons {
}
}
- public static void setVisibilityIcon(int accessLevel, RowIcon baseIcon) {
+ public static void setVisibilityIcon(@MagicConstant(intValues = {PsiUtil.ACCESS_LEVEL_PUBLIC, PsiUtil.ACCESS_LEVEL_PROTECTED, PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL, PsiUtil.ACCESS_LEVEL_PRIVATE}) int accessLevel, RowIcon baseIcon) {
Icon icon;
switch (accessLevel) {
case PsiUtil.ACCESS_LEVEL_PUBLIC:
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java
index ee3ff0c3ffd8..647a1e45ac13 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaCodeFoldingSettingsBase.java
@@ -14,6 +14,7 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_I18N_MESSAGES = true;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_SUPPRESS_WARNINGS = true;
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_END_OF_LINE_COMMENTS = false;
+ @SuppressWarnings({"WeakerAccess"}) public boolean INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS = true;
@Override
public boolean isCollapseImports() {
@@ -148,4 +149,14 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
public void setCollapseEndOfLineComments(boolean value) {
COLLAPSE_END_OF_LINE_COMMENTS = value;
}
+
+ @Override
+ public boolean isInlineParameterNamesForLiteralCallArguments() {
+ return INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS;
+ }
+
+ @Override
+ public void setInlineParameterNamesForLiteralCallArguments(boolean value) {
+ INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS = value;
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
index 15d40f1baf4b..9f5ecb109fd5 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
@@ -41,13 +41,11 @@ import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PropertyUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.util.*;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -703,6 +701,12 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
else if (element instanceof PsiComment) {
return settings.isCollapseEndOfLineComments();
}
+ else if (isLiteralExpression(element)
+ && element.getParent() instanceof PsiExpressionList
+ && (element.getParent().getParent() instanceof PsiCallExpression
+ || element.getParent().getParent() instanceof PsiAnonymousClass)) {
+ return settings.isInlineParameterNamesForLiteralCallArguments();
+ }
else {
LOG.error("Unknown element:" + element);
return false;
@@ -725,6 +729,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
if (!dumb) {
addMethodGenericParametersFolding(expression, foldElements, document, quick);
+ inlineLiteralArgumentsNames(expression, foldElements, quick);
}
super.visitMethodCallExpression(expression);
@@ -734,6 +739,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
public void visitNewExpression(PsiNewExpression expression) {
if (!dumb) {
addGenericParametersFolding(expression, foldElements, document, quick);
+ inlineLiteralArgumentsNames(expression, foldElements, quick);
}
super.visitNewExpression(expression);
@@ -747,6 +753,64 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
});
}
+ private static void inlineLiteralArgumentsNames(@NotNull PsiCallExpression expression,
+ @NotNull List<FoldingDescriptor> foldElements,
+ boolean quick)
+ {
+ if (quick || !JavaCodeFoldingSettings.getInstance().isInlineParameterNamesForLiteralCallArguments()) {
+ return;
+ }
+ PsiExpressionList callArgumentsList = expression.getArgumentList();
+ if (callArgumentsList == null) {
+ return;
+ }
+
+ PsiExpression[] callArguments = callArgumentsList.getExpressions();
+ if (callArguments.length > 1) {
+ PsiParameter[] parameters = null;
+ boolean isResolved = false;
+
+ for (int i = 0; i < callArguments.length; i++) {
+ PsiExpression callArgument = callArguments[i];
+
+ if (callArgument.getType() != null && isLiteralExpression(callArgument)) {
+ if (!isResolved) {
+ PsiMethod method = expression.resolveMethod();
+ isResolved = true;
+ if (method == null) {
+ return;
+ }
+ parameters = method.getParameterList().getParameters();
+ if (parameters.length != callArguments.length) {
+ return;
+ }
+ }
+
+ PsiParameter methodParam = parameters[i];
+ if (TypeConversionUtil.isAssignable(methodParam.getType(), callArgument.getType())) {
+ TextRange range = callArgument.getTextRange();
+ String placeholderText = methodParam.getName() + ": " + callArgument.getText();
+ foldElements.add(new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText));
+ }
+ }
+ }
+ }
+ }
+
+ @Contract("null -> false")
+ private static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
+ if (callArgument instanceof PsiLiteralExpression)
+ return true;
+
+ if (callArgument instanceof PsiPrefixExpression) {
+ PsiPrefixExpression expr = (PsiPrefixExpression)callArgument;
+ IElementType tokenType = expr.getOperationTokenType();
+ return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression;
+ }
+
+ return false;
+ }
+
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
@NotNull Set<PsiElement> processedComments, final boolean quick) {
if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
index 7b154bd5383c..0052dd5bb8b9 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java
@@ -253,13 +253,13 @@ public class JavaDocInfoGenerator {
public static String generateSignature(PsiElement element) {
StringBuilder buf = new StringBuilder();
if (element instanceof PsiClass) {
- if (generateClassSignature(buf, (PsiClass)element)) return null;
+ if (generateClassSignature(buf, (PsiClass)element, false)) return null;
}
else if (element instanceof PsiField) {
- generateFieldSignature(buf, (PsiField)element);
+ generateFieldSignature(buf, (PsiField)element, false);
}
else if (element instanceof PsiMethod) {
- generateMethodSignature(buf, (PsiMethod)element);
+ generateMethodSignature(buf, (PsiMethod)element, false);
}
return buf.toString();
}
@@ -291,7 +291,6 @@ public class JavaDocInfoGenerator {
private void generateClassJavaDoc(@NonNls StringBuilder buffer, PsiClass aClass, boolean generatePrologueAndEpilogue) {
if (aClass instanceof PsiAnonymousClass) return;
- PsiManager manager = aClass.getManager();
if (generatePrologueAndEpilogue)
generatePrologue(buffer);
@@ -307,7 +306,7 @@ public class JavaDocInfoGenerator {
}
buffer.append("<PRE>");
- if (generateClassSignature(buffer, aClass)) return;
+ if (generateClassSignature(buffer, aClass, true)) return;
buffer.append("</PRE>");
//buffer.append("<br>");
@@ -321,8 +320,8 @@ public class JavaDocInfoGenerator {
generateEpilogue(buffer);
}
- private static boolean generateClassSignature(StringBuilder buffer, PsiClass aClass) {
- generateAnnotations(buffer, aClass);
+ private static boolean generateClassSignature(StringBuilder buffer, PsiClass aClass, boolean generateLink) {
+ generateAnnotations(buffer, aClass, generateLink);
String modifiers = PsiFormatUtil.formatModifiers(aClass, PsiFormatUtilBase.JAVADOC_MODIFIERS_ONLY);
if (!modifiers.isEmpty()) {
buffer.append(modifiers);
@@ -355,7 +354,7 @@ public class JavaDocInfoGenerator {
}
else {
for (int i = 0; i < refs.length; i++) {
- generateType(buffer, refs[i], aClass);
+ generateType(buffer, refs[i], aClass, generateLink);
if (i < refs.length - 1) {
buffer.append(",&nbsp;");
}
@@ -369,7 +368,7 @@ public class JavaDocInfoGenerator {
if (refs.length > 0) {
buffer.append("implements ");
for (int i = 0; i < refs.length; i++) {
- generateType(buffer, refs[i], aClass);
+ generateType(buffer, refs[i], aClass, generateLink);
if (i < refs.length - 1) {
buffer.append(",&nbsp;");
}
@@ -472,7 +471,7 @@ public class JavaDocInfoGenerator {
}
buffer.append("<PRE>");
- generateFieldSignature(buffer, field);
+ generateFieldSignature(buffer, field, true);
buffer.append("</PRE>");
//buffer.append("<br>");
@@ -487,14 +486,14 @@ public class JavaDocInfoGenerator {
generateEpilogue(buffer);
}
- private static void generateFieldSignature(StringBuilder buffer, PsiField field) {
- generateAnnotations(buffer, field);
+ private static void generateFieldSignature(StringBuilder buffer, PsiField field, boolean generateLink) {
+ generateAnnotations(buffer, field, generateLink);
String modifiers = PsiFormatUtil.formatModifiers(field, PsiFormatUtilBase.JAVADOC_MODIFIERS_ONLY);
if (!modifiers.isEmpty()) {
buffer.append(modifiers);
buffer.append(" ");
}
- generateType(buffer, field.getType(), field);
+ generateType(buffer, field.getType(), field, generateLink);
buffer.append(" ");
buffer.append("<b>");
buffer.append(field.getName());
@@ -696,14 +695,21 @@ public class JavaDocInfoGenerator {
}
}
- private static void generateAnnotations(@NonNls @NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner) {
+ private static void generateAnnotations(@NonNls @NotNull StringBuilder buffer, @NotNull PsiModifierListOwner owner, boolean generateLink) {
final PsiModifierList ownerModifierList = owner.getModifierList();
if (ownerModifierList == null) return;
- PsiAnnotation[] annotations = ownerModifierList.getAnnotations();
+ generateAnnotations(buffer, owner, ownerModifierList.getAnnotations(), false, generateLink);
final PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner);
if (externalAnnotations != null) {
- annotations = ArrayUtil.mergeArrays(annotations, externalAnnotations, PsiAnnotation.ARRAY_FACTORY);
+ generateAnnotations(buffer, owner, externalAnnotations, true, generateLink);
}
+ }
+
+ private static void generateAnnotations(StringBuilder buffer,
+ PsiModifierListOwner owner,
+ PsiAnnotation[] annotations,
+ boolean external,
+ boolean generateLink) {
PsiManager manager = owner.getManager();
for (PsiAnnotation annotation : annotations) {
@@ -715,7 +721,7 @@ public class JavaDocInfoGenerator {
if (AnnotationUtil.isAnnotated(annotationType, "java.lang.annotation.Documented", false)) {
final PsiClassType type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(annotationType, PsiSubstitutor.EMPTY);
buffer.append("@");
- generateType(buffer, type, owner);
+ generateType(buffer, type, owner, generateLink);
final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
if (attributes.length > 0) {
buffer.append("(");
@@ -737,12 +743,17 @@ public class JavaDocInfoGenerator {
}
buffer.append("&nbsp;");
}
- } else {
+ } else if (external) {
+ buffer.append(annotation.getText());
+ buffer.append("&nbsp;");
+ }
+ else {
buffer.append("<font color=red>");
buffer.append(annotation.getText());
buffer.append("</font>");
buffer.append("&nbsp;");
}
+ buffer.append("\n");
}
}
@@ -756,7 +767,7 @@ public class JavaDocInfoGenerator {
buffer.append(modifiers);
buffer.append(" ");
}
- generateAnnotations(buffer, parameter);
+ generateAnnotations(buffer, parameter, true);
generateType(buffer, parameter.getType(), parameter);
buffer.append(" ");
buffer.append("<b>");
@@ -801,7 +812,7 @@ public class JavaDocInfoGenerator {
}
buffer.append("<PRE>");
- generateMethodSignature(buffer, method);
+ generateMethodSignature(buffer, method, true);
buffer.append("</PRE>");
//buffer.append("<br>");
@@ -831,8 +842,8 @@ public class JavaDocInfoGenerator {
generateEpilogue(buffer);
}
- private static void generateMethodSignature(StringBuilder buffer, PsiMethod method) {
- generateAnnotations(buffer, method);
+ private static void generateMethodSignature(StringBuilder buffer, PsiMethod method, boolean generateLink) {
+ generateAnnotations(buffer, method, generateLink);
String modifiers = PsiFormatUtil.formatModifiers(method, PsiFormatUtilBase.JAVADOC_MODIFIERS_ONLY);
int indent = 0;
if (!modifiers.isEmpty()) {
@@ -850,7 +861,7 @@ public class JavaDocInfoGenerator {
}
if (method.getReturnType() != null) {
- indent += generateType(buffer, method.getReturnType(), method);
+ indent += generateType(buffer, method.getReturnType(), method, generateLink);
buffer.append("&nbsp;");
indent++;
}
@@ -865,8 +876,8 @@ public class JavaDocInfoGenerator {
PsiParameter[] parms = method.getParameterList().getParameters();
for (int i = 0; i < parms.length; i++) {
PsiParameter parm = parms[i];
- generateAnnotations(buffer, parm);
- generateType(buffer, parm.getType(), method);
+ generateAnnotations(buffer, parm, generateLink);
+ generateType(buffer, parm.getType(), method, generateLink);
buffer.append("&nbsp;");
if (parm.getName() != null) {
buffer.append(parm.getName());
@@ -1862,9 +1873,11 @@ public class JavaDocInfoGenerator {
return null;
}
- @Nullable private <T> Pair<T, InheritDocProvider<T>> searchDocTagInSupers(PsiClassType[] supers,
+ @Nullable
+ private <T> Pair<T, InheritDocProvider<T>> searchDocTagInSupers(PsiClassType[] supers,
PsiMethod method,
- DocTagLocator<T> loc) {
+ DocTagLocator<T> loc,
+ Set<PsiClass> visitedClasses) {
for (PsiClassType superType : supers) {
PsiClass aSuper = superType.resolve();
@@ -1878,8 +1891,8 @@ public class JavaDocInfoGenerator {
for (PsiClassType superType : supers) {
PsiClass aSuper = superType.resolve();
- if (aSuper != null) {
- Pair<T, InheritDocProvider<T>> tag = findInheritDocTagInClass(method, aSuper, loc);
+ if (aSuper != null && visitedClasses.add(aSuper)) {
+ Pair<T, InheritDocProvider<T>> tag = findInheritDocTagInClass(method, aSuper, loc, visitedClasses);
if (tag != null) {
return tag;
@@ -1892,20 +1905,21 @@ public class JavaDocInfoGenerator {
private <T> Pair<T, InheritDocProvider<T>> findInheritDocTagInClass(PsiMethod aMethod,
PsiClass aClass,
- DocTagLocator<T> loc) {
+ DocTagLocator<T> loc,
+ Set<PsiClass> visitedClasses) {
if (aClass == null) {
return null;
}
PsiClassType[] implementsTypes = aClass.getImplementsListTypes();
- Pair<T, InheritDocProvider<T>> tag = searchDocTagInSupers(implementsTypes, aMethod, loc);
+ Pair<T, InheritDocProvider<T>> tag = searchDocTagInSupers(implementsTypes, aMethod, loc, visitedClasses);
if (tag != null) {
return tag;
}
PsiClassType[] extendsTypes = aClass.getExtendsListTypes();
- return searchDocTagInSupers(extendsTypes, aMethod, loc);
+ return searchDocTagInSupers(extendsTypes, aMethod, loc, visitedClasses);
}
@Nullable private <T> Pair<T, InheritDocProvider<T>> findInheritDocTag(PsiMethod method, DocTagLocator<T> loc) {
@@ -1913,7 +1927,7 @@ public class JavaDocInfoGenerator {
if (aClass == null) return null;
- return findInheritDocTagInClass(method, aClass, loc);
+ return findInheritDocTagInClass(method, aClass, loc, new HashSet<PsiClass>());
}
private static class ReturnTagLocator implements DocTagLocator<PsiDocTag> {
diff --git a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
index a012988edf08..0cfb60b3ae69 100644
--- a/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
+++ b/java/java-psi-impl/src/com/intellij/core/CoreJavaFileManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -181,6 +181,7 @@ public class CoreJavaFileManager implements JavaFileManager {
return null;
}
+ @NotNull
@Override
public PsiClass[] findClasses(@NotNull String qName, @NotNull GlobalSearchScope scope) {
List<PsiClass> result = new ArrayList<PsiClass>();
@@ -193,6 +194,7 @@ public class CoreJavaFileManager implements JavaFileManager {
return result.toArray(new PsiClass[result.size()]);
}
+ @NotNull
@Override
public Collection<String> getNonTrivialPackagePrefixes() {
return Collections.emptyList();
diff --git a/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java b/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java
index b71bdefee9be..d676f03f611a 100644
--- a/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java
+++ b/java/java-psi-impl/src/com/intellij/core/JavaCoreApplicationEnvironment.java
@@ -39,10 +39,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
+import com.intellij.psi.compiled.ClassFileDecompilers;
import com.intellij.psi.impl.EmptySubstitutorImpl;
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
import com.intellij.psi.impl.PsiExpressionEvaluator;
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
+import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy;
import com.intellij.psi.impl.compiled.ClsStubBuilderFactory;
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
import com.intellij.psi.impl.source.tree.CoreJavaASTFactory;
@@ -54,6 +56,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
+@SuppressWarnings("UnusedDeclaration") // Upsource and Kotlin
public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment {
public JavaCoreApplicationEnvironment(@NotNull Disposable parentDisposable) {
super(parentDisposable);
@@ -105,8 +108,12 @@ public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment {
return false;
}
});
+
+ registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy.class);
+ registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
}
+ @SuppressWarnings("MethodMayBeStatic") // overridden in upsource
protected CoreJavaDirectoryService createJavaDirectoryService() {
return new CoreJavaDirectoryService();
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProviderFactory.java b/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProviderFactory.java
index de870b9cfcbf..4a73a85da0bc 100644
--- a/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProviderFactory.java
+++ b/java/java-psi-impl/src/com/intellij/psi/ClassFileViewProviderFactory.java
@@ -28,6 +28,7 @@ import static com.intellij.psi.compiled.ClassFileDecompilers.Full;
* @author max
*/
public class ClassFileViewProviderFactory implements FileViewProviderFactory {
+ @NotNull
@Override
public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, Language language, @NotNull PsiManager manager, boolean eventSystemEnabled) {
ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file);
diff --git a/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java
index 2d11fc963cec..59a4e10d40fe 100644
--- a/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.file.PsiPackageImpl;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.NonClasspathDirectoryScope;
+import com.intellij.psi.search.NonClasspathDirectoriesScope;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -252,7 +252,7 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder {
GlobalSearchScope scope = base;
for (PsiElementFinder finder : Extensions.getExtensions(EP_NAME, project)) {
if (finder instanceof NonClasspathClassFinder) {
- scope = scope.uniteWith(NonClasspathDirectoryScope.compose(((NonClasspathClassFinder)finder).getClassRoots()));
+ scope = scope.uniteWith(NonClasspathDirectoriesScope.compose(((NonClasspathClassFinder)finder).getClassRoots()));
}
}
return scope;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
index 107bff5e60f2..3496b98f5ddf 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
@@ -760,7 +760,6 @@ public class PsiClassImplUtil {
@NotNull
private static PsiClass[] getSupersInner(@NotNull PsiClass psiClass) {
PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
- PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
if (psiClass.isInterface()) {
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), true);
@@ -792,6 +791,7 @@ public class PsiClassImplUtil {
return resolveClassReferenceList(extendsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
}
+ PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
PsiClass[] interfaces = resolveClassReferenceList(implementsListTypes, psiClass.getManager(), psiClass.getResolveScope(), false);
PsiClass superClass = getSuperClass(psiClass);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
index e5080d3dfafe..514087492300 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
@@ -537,8 +537,10 @@ public class PsiImplUtil {
@NotNull
public static SearchScope getMemberUseScope(@NotNull PsiMember member) {
- final GlobalSearchScope maximalUseScope = ResolveScopeManager.getElementUseScope(member);
PsiFile file = member.getContainingFile();
+ PsiElement topElement = file == null ? member : file;
+ Project project = topElement.getProject();
+ final GlobalSearchScope maximalUseScope = ResolveScopeManager.getInstance(project).getUseScope(topElement);
if (isInServerPage(file)) return maximalUseScope;
PsiClass aClass = member.getContainingClass();
@@ -549,28 +551,23 @@ public class PsiImplUtil {
return new LocalSearchScope(methodCallExpr != null ? methodCallExpr : aClass);
}
- if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
+ PsiModifierList modifierList = member.getModifierList();
+ int accessLevel = modifierList == null ? PsiUtil.ACCESS_LEVEL_PUBLIC : PsiUtil.getAccessLevel(modifierList);
+ if (accessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC || accessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) {
return maximalUseScope; // class use scope doesn't matter, since another very visible class can inherit from aClass
}
- else if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
- return maximalUseScope; // class use scope doesn't matter, since another very visible class can inherit from aClass
- }
- else if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+ if (accessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) {
PsiClass topClass = PsiUtil.getTopLevelClass(member);
- return topClass != null ? new LocalSearchScope(topClass) : file != null ? new LocalSearchScope(file) : maximalUseScope;
+ return topClass != null ? new LocalSearchScope(topClass) : file == null ? maximalUseScope : new LocalSearchScope(file);
}
- else {
- if (file instanceof PsiJavaFile) {
- PsiPackage aPackage = JavaPsiFacade.getInstance(member.getProject()).findPackage(((PsiJavaFile)file).getPackageName());
- if (aPackage != null) {
- SearchScope scope = PackageScope.packageScope(aPackage, false);
- scope = scope.intersectWith(maximalUseScope);
- return scope;
- }
+ if (file instanceof PsiJavaFile) {
+ PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(((PsiJavaFile)file).getPackageName());
+ if (aPackage != null) {
+ SearchScope scope = PackageScope.packageScope(aPackage, false);
+ return scope.intersectWith(maximalUseScope);
}
-
- return maximalUseScope;
}
+ return maximalUseScope;
}
public static boolean isInServerPage(@Nullable final PsiElement element) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index e2065ce3d46c..7c597e495f2e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -158,10 +158,16 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
}
if (newBound instanceof PsiCapturedWildcardType) {
final PsiWildcardType wildcard = ((PsiCapturedWildcardType)newBound).getWildcard();
- if (wildcardType.isExtends() != wildcard.isExtends() && wildcard.isBounded()) {
- return wildcardType.isExtends() ? PsiWildcardType.createExtends(wildcardType.getManager(), newBound)
- : PsiWildcardType.createSuper(wildcardType.getManager(), newBound);
+ if (wildcardType.isExtends() != wildcard.isExtends()) {
+ if (wildcard.isBounded()) {
+ return wildcardType.isExtends() ? PsiWildcardType.createExtends(wildcardType.getManager(), newBound)
+ : PsiWildcardType.createSuper(wildcardType.getManager(), newBound);
+ }
+ else {
+ return newBound;
+ }
}
+ if (!wildcard.isBounded()) return PsiWildcardType.createUnbounded(wildcardType.getManager());
return newBound;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
index d70fa1f4be4b..f1d847cb24c2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
@@ -17,15 +17,16 @@ package com.intellij.psi.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.HierarchicalMethodSignatureImpl;
+import com.intellij.psi.impl.source.PsiClassImpl;
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.*;
-import com.intellij.util.NotNullFunction;
-import com.intellij.util.Processor;
-import com.intellij.util.SmartList;
+import com.intellij.util.*;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
@@ -36,8 +37,8 @@ import java.util.*;
public class PsiSuperMethodImplUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiSuperMethodImplUtil");
- private static final PsiCacheKey<Map<MethodSignature, HierarchicalMethodSignature>, PsiClass> SIGNATURES_KEY = PsiCacheKey
- .create("SIGNATURES_KEY", new NotNullFunction<PsiClass, Map<MethodSignature, HierarchicalMethodSignature>>() {
+ private static final PsiCacheKey<Map<MethodSignature, HierarchicalMethodSignature>, PsiClass> SIGNATURES_FOR_CLASS_KEY = PsiCacheKey
+ .create("SIGNATURES_FOR_CLASS_KEY", new NotNullFunction<PsiClass, Map<MethodSignature, HierarchicalMethodSignature>>() {
@NotNull
@Override
public Map<MethodSignature, HierarchicalMethodSignature> fun(PsiClass dom) {
@@ -49,46 +50,45 @@ public class PsiSuperMethodImplUtil {
}
@NotNull
- public static PsiMethod[] findSuperMethods(PsiMethod method) {
+ public static PsiMethod[] findSuperMethods(@NotNull PsiMethod method) {
return findSuperMethods(method, null);
}
@NotNull
- public static PsiMethod[] findSuperMethods(PsiMethod method, boolean checkAccess) {
+ public static PsiMethod[] findSuperMethods(@NotNull PsiMethod method, boolean checkAccess) {
if (!canHaveSuperMethod(method, checkAccess, false)) return PsiMethod.EMPTY_ARRAY;
return findSuperMethodsInternal(method, null);
}
@NotNull
- public static PsiMethod[] findSuperMethods(PsiMethod method, PsiClass parentClass) {
+ public static PsiMethod[] findSuperMethods(@NotNull PsiMethod method, PsiClass parentClass) {
if (!canHaveSuperMethod(method, true, false)) return PsiMethod.EMPTY_ARRAY;
return findSuperMethodsInternal(method, parentClass);
}
@NotNull
- private static PsiMethod[] findSuperMethodsInternal(PsiMethod method, PsiClass parentClass) {
+ private static PsiMethod[] findSuperMethodsInternal(@NotNull PsiMethod method, PsiClass parentClass) {
List<MethodSignatureBackedByPsiMethod> outputMethods = findSuperMethodSignatures(method, parentClass, false);
return MethodSignatureUtil.convertMethodSignaturesToMethods(outputMethods);
}
@NotNull
- public static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignaturesIncludingStatic(PsiMethod method,
- boolean checkAccess) {
+ public static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignaturesIncludingStatic(@NotNull PsiMethod method,
+ boolean checkAccess) {
if (!canHaveSuperMethod(method, checkAccess, true)) return Collections.emptyList();
return findSuperMethodSignatures(method, null, true);
}
@NotNull
- private static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignatures(PsiMethod method,
+ private static List<MethodSignatureBackedByPsiMethod> findSuperMethodSignatures(@NotNull PsiMethod method,
PsiClass parentClass,
boolean allowStaticMethod) {
-
return new ArrayList<MethodSignatureBackedByPsiMethod>(SuperMethodsSearch.search(method, parentClass, true, allowStaticMethod).findAll());
}
- private static boolean canHaveSuperMethod(PsiMethod method, boolean checkAccess, boolean allowStaticMethod) {
+ private static boolean canHaveSuperMethod(@NotNull PsiMethod method, boolean checkAccess, boolean allowStaticMethod) {
if (method.isConstructor()) return false;
if (!allowStaticMethod && method.hasModifierProperty(PsiModifier.STATIC)) return false;
if (checkAccess && method.hasModifierProperty(PsiModifier.PRIVATE)) return false;
@@ -97,21 +97,23 @@ public class PsiSuperMethodImplUtil {
}
@Nullable
- public static PsiMethod findDeepestSuperMethod(PsiMethod method) {
+ public static PsiMethod findDeepestSuperMethod(@NotNull PsiMethod method) {
if (!canHaveSuperMethod(method, true, false)) return null;
return DeepestSuperMethodsSearch.search(method).findFirst();
}
- public static PsiMethod[] findDeepestSuperMethods(PsiMethod method) {
+ @NotNull
+ public static PsiMethod[] findDeepestSuperMethods(@NotNull PsiMethod method) {
if (!canHaveSuperMethod(method, true, false)) return PsiMethod.EMPTY_ARRAY;
Collection<PsiMethod> collection = DeepestSuperMethodsSearch.search(method).findAll();
return collection.toArray(new PsiMethod[collection.size()]);
}
- private static Map<MethodSignature, HierarchicalMethodSignature> buildMethodHierarchy(PsiClass aClass,
- PsiSubstitutor substitutor,
+ @NotNull
+ private static Map<MethodSignature, HierarchicalMethodSignature> buildMethodHierarchy(@NotNull PsiClass aClass,
+ @NotNull PsiSubstitutor substitutor,
final boolean includePrivates,
- final Set<PsiClass> visited,
+ @NotNull final Set<PsiClass> visited,
boolean isInRawContext) {
ProgressManager.checkCanceled();
Map<MethodSignature, HierarchicalMethodSignature> result = new LinkedHashMap<MethodSignature, HierarchicalMethodSignature>();
@@ -140,7 +142,15 @@ public class PsiSuperMethodImplUtil {
}
});
- for (PsiMethod method : aClass.getMethods()) {
+ PsiMethod[] methods = aClass.getMethods();
+ if (aClass instanceof PsiClassImpl) {
+ final PsiMethod valuesMethod = ((PsiClassImpl)aClass).getValuesMethod();
+ if (valuesMethod != null) {
+ methods = ArrayUtil.append(methods, valuesMethod);
+ }
+ }
+
+ for (PsiMethod method : methods) {
if (!method.isValid()) {
throw new PsiInvalidElementAccessException(method, "class.valid=" + aClass.isValid() + "; name=" + method.getName());
}
@@ -207,11 +217,11 @@ public class PsiSuperMethodImplUtil {
return result;
}
- private static void putInMap(PsiClass aClass,
- Map<MethodSignature, HierarchicalMethodSignature> result,
- Map<MethodSignature, HierarchicalMethodSignatureImpl> map,
- HierarchicalMethodSignature hierarchicalMethodSignature,
- MethodSignature signature) {
+ private static void putInMap(@NotNull PsiClass aClass,
+ @NotNull Map<MethodSignature, HierarchicalMethodSignature> result,
+ @NotNull Map<MethodSignature, HierarchicalMethodSignatureImpl> map,
+ @NotNull HierarchicalMethodSignature hierarchicalMethodSignature,
+ @NotNull MethodSignature signature) {
if (!PsiUtil.isAccessible(aClass.getProject(), hierarchicalMethodSignature.getMethod(), aClass, aClass)) return;
HierarchicalMethodSignatureImpl existing = map.get(signature);
if (existing == null) {
@@ -241,7 +251,7 @@ public class PsiSuperMethodImplUtil {
return thatRet != null && thisRet != null && !thatRet.equals(thisRet) && TypeConversionUtil.isAssignable(thatRet, thisRet, false);
}
- private static void mergeSupers(final HierarchicalMethodSignatureImpl existing, final HierarchicalMethodSignature superSignature) {
+ private static void mergeSupers(@NotNull HierarchicalMethodSignatureImpl existing, @NotNull HierarchicalMethodSignature superSignature) {
for (HierarchicalMethodSignature existingSuper : existing.getSuperSignatures()) {
if (existingSuper.getMethod() == superSignature.getMethod()) {
for (HierarchicalMethodSignature signature : superSignature.getSuperSignatures()) {
@@ -262,9 +272,9 @@ public class PsiSuperMethodImplUtil {
}
}
- private static boolean isSuperMethod(PsiClass aClass,
- HierarchicalMethodSignature hierarchicalMethodSignature,
- HierarchicalMethodSignature superSignatureHierarchical) {
+ private static boolean isSuperMethod(@NotNull PsiClass aClass,
+ @NotNull HierarchicalMethodSignature hierarchicalMethodSignature,
+ @NotNull HierarchicalMethodSignature superSignatureHierarchical) {
PsiMethod superMethod = superSignatureHierarchical.getMethod();
PsiClass superClass = superMethod.getContainingClass();
PsiClass containingClass = hierarchicalMethodSignature.getMethod().getContainingClass();
@@ -302,7 +312,8 @@ public class PsiSuperMethodImplUtil {
return false;
}
- private static HierarchicalMethodSignatureImpl copy(HierarchicalMethodSignature hi) {
+ @NotNull
+ private static HierarchicalMethodSignatureImpl copy(@NotNull HierarchicalMethodSignature hi) {
HierarchicalMethodSignatureImpl hierarchicalMethodSignature = new HierarchicalMethodSignatureImpl(hi);
for (HierarchicalMethodSignature his : hi.getSuperSignatures()) {
hierarchicalMethodSignature.addSuperSignature(copy(his));
@@ -310,9 +321,11 @@ public class PsiSuperMethodImplUtil {
return hierarchicalMethodSignature;
}
- private static PsiSubstitutor obtainFinalSubstitutor(PsiClass superClass,
- PsiSubstitutor superSubstitutor,
- PsiSubstitutor derivedSubstitutor, boolean inRawContext) {
+ @NotNull
+ private static PsiSubstitutor obtainFinalSubstitutor(@NotNull PsiClass superClass,
+ @NotNull PsiSubstitutor superSubstitutor,
+ @NotNull PsiSubstitutor derivedSubstitutor,
+ boolean inRawContext) {
if (inRawContext) {
Set<PsiTypeParameter> typeParams = superSubstitutor.getSubstitutionMap().keySet();
PsiElementFactory factory = JavaPsiFacade.getElementFactory(superClass.getProject());
@@ -331,35 +344,40 @@ public class PsiSuperMethodImplUtil {
return map == null ? PsiSubstitutor.EMPTY : JavaPsiFacade.getInstance(superClass.getProject()).getElementFactory().createSubstitutor(map);
}
- public static Collection<HierarchicalMethodSignature> getVisibleSignatures(PsiClass aClass) {
+ @NotNull
+ public static Collection<HierarchicalMethodSignature> getVisibleSignatures(@NotNull PsiClass aClass) {
Map<MethodSignature, HierarchicalMethodSignature> map = getSignaturesMap(aClass);
return map.values();
}
@NotNull
- public static HierarchicalMethodSignature getHierarchicalMethodSignature(final PsiMethod method) {
- return CachedValuesManager
- .getCachedValue(method, new CachedValueProvider<HierarchicalMethodSignature>() {
- @Nullable
- @Override
- public Result<HierarchicalMethodSignature> compute() {
- PsiClass aClass = method.getContainingClass();
- HierarchicalMethodSignature result = null;
- if (aClass != null) {
- result = getSignaturesMap(aClass).get(method.getSignature(PsiSubstitutor.EMPTY));
- }
- if (result == null) {
- result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY));
- }
- return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
- }
- });
+ public static HierarchicalMethodSignature getHierarchicalMethodSignature(@NotNull final PsiMethod method) {
+ Project project = method.getProject();
+ return CachedValuesManager.getManager(project).getParameterizedCachedValue(method, HIERARCHICAL_SIGNATURE_KEY,
+ HIERARCHICAL_SIGNATURE_PROVIDER, false, method);
}
- private static Map<MethodSignature, HierarchicalMethodSignature> getSignaturesMap(final PsiClass aClass) {
- return SIGNATURES_KEY.getValue(aClass);
- }
+ private static final Key<ParameterizedCachedValue<HierarchicalMethodSignature, PsiMethod>> HIERARCHICAL_SIGNATURE_KEY = Key.create("HierarchicalMethodSignature");
+ private static final ParameterizedCachedValueProvider<HierarchicalMethodSignature, PsiMethod> HIERARCHICAL_SIGNATURE_PROVIDER =
+ new ParameterizedCachedValueProvider<HierarchicalMethodSignature, PsiMethod>() {
+ @Override
+ public CachedValueProvider.Result<HierarchicalMethodSignature> compute(PsiMethod method) {
+ PsiClass aClass = method.getContainingClass();
+ HierarchicalMethodSignature result = null;
+ if (aClass != null) {
+ result = getSignaturesMap(aClass).get(method.getSignature(PsiSubstitutor.EMPTY));
+ }
+ if (result == null) {
+ result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY));
+ }
+ return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
+ }
+ };
+ @NotNull
+ private static Map<MethodSignature, HierarchicalMethodSignature> getSignaturesMap(@NotNull PsiClass aClass) {
+ return SIGNATURES_FOR_CLASS_KEY.getValue(aClass);
+ }
// uses hierarchy signature tree if available, traverses class structure by itself otherwise
public static boolean processDirectSuperMethodsSmart(@NotNull PsiMethod method, @NotNull Processor<PsiMethod> superMethodProcessor) {
@@ -370,7 +388,7 @@ public class PsiSuperMethodImplUtil {
if (!canHaveSuperMethod(method, true, false)) return false;
- Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass);
+ Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_FOR_CLASS_KEY.getCachedValueOrNull(aClass);
if (cachedMap != null) {
HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY));
if (signature != null) {
@@ -420,7 +438,7 @@ public class PsiSuperMethodImplUtil {
if (!canHaveSuperMethod(method, true, false)) return false;
PsiMethod[] superMethods = null;
- Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_KEY.getCachedValueOrNull(aClass);
+ Map<MethodSignature, HierarchicalMethodSignature> cachedMap = SIGNATURES_FOR_CLASS_KEY.getCachedValueOrNull(aClass);
if (cachedMap != null) {
HierarchicalMethodSignature signature = cachedMap.get(method.getSignature(PsiSubstitutor.EMPTY));
if (signature != null) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/impl/JavaFileManager.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/impl/JavaFileManager.java
index fc883fe34b56..22b4104fb8c9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/file/impl/JavaFileManager.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/impl/JavaFileManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,8 +34,10 @@ public interface JavaFileManager {
@Nullable
PsiClass findClass(@NotNull String qName, @NotNull GlobalSearchScope scope);
+ @NotNull
PsiClass[] findClasses(@NotNull String qName, @NotNull GlobalSearchScope scope);
+ @NotNull
Collection<String> getNonTrivialPackagePrefixes();
} \ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
index 429c276303c9..544925856a52 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/ClassInnerStuffCache.java
@@ -93,15 +93,13 @@ public class ClassInnerStuffCache {
if (checkBases) {
return PsiClassImplUtil.findFieldByName(myClass, name, true);
}
- else {
- return CachedValuesManager.getCachedValue(myClass, new CachedValueProvider<Map<String, PsiField>>() {
- @Nullable
- @Override
- public Result<Map<String, PsiField>> compute() {
- return Result.create(getFieldsMap(), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
- }
- }).get(name);
- }
+ return CachedValuesManager.getCachedValue(myClass, new CachedValueProvider<Map<String, PsiField>>() {
+ @Nullable
+ @Override
+ public Result<Map<String, PsiField>> compute() {
+ return Result.create(getFieldsMap(), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
+ }
+ }).get(name);
}
@NotNull
@@ -109,16 +107,14 @@ public class ClassInnerStuffCache {
if (checkBases) {
return PsiClassImplUtil.findMethodsByName(myClass, name, true);
}
- else {
- PsiMethod[] methods = CachedValuesManager.getCachedValue(myClass, new CachedValueProvider<Map<String, PsiMethod[]>>() {
- @Nullable
- @Override
- public Result<Map<String, PsiMethod[]>> compute() {
- return Result.create(getMethodsMap(), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
- }
- }).get(name);
- return methods != null ? methods : PsiMethod.EMPTY_ARRAY;
- }
+ PsiMethod[] methods = CachedValuesManager.getCachedValue(myClass, new CachedValueProvider<Map<String, PsiMethod[]>>() {
+ @Nullable
+ @Override
+ public Result<Map<String, PsiMethod[]>> compute() {
+ return Result.create(getMethodsMap(), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myTracker);
+ }
+ }).get(name);
+ return methods == null ? PsiMethod.EMPTY_ARRAY : methods;
}
@Nullable
@@ -167,24 +163,28 @@ public class ClassInnerStuffCache {
});
}
+ @NotNull
private PsiField[] getAllFields() {
List<PsiField> own = myClass.getOwnFields();
List<PsiField> ext = PsiAugmentProvider.collectAugments(myClass, PsiField.class);
return ArrayUtil.mergeCollections(own, ext, PsiField.ARRAY_FACTORY);
}
+ @NotNull
private PsiMethod[] getAllMethods() {
List<PsiMethod> own = myClass.getOwnMethods();
List<PsiMethod> ext = PsiAugmentProvider.collectAugments(myClass, PsiMethod.class);
return ArrayUtil.mergeCollections(own, ext, PsiMethod.ARRAY_FACTORY);
}
+ @NotNull
private PsiClass[] getAllInnerClasses() {
List<PsiClass> own = myClass.getOwnInnerClasses();
List<PsiClass> ext = PsiAugmentProvider.collectAugments(myClass, PsiClass.class);
return ArrayUtil.mergeCollections(own, ext, PsiClass.ARRAY_FACTORY);
}
+ @NotNull
private Map<String, PsiField> getFieldsMap() {
PsiField[] fields = getFields();
if (fields.length == 0) return Collections.emptyMap();
@@ -199,6 +199,7 @@ public class ClassInnerStuffCache {
return cachedFields;
}
+ @NotNull
private Map<String, PsiMethod[]> getMethodsMap() {
PsiMethod[] methods = getMethods();
if (methods.length == 0) return Collections.emptyMap();
@@ -220,6 +221,7 @@ public class ClassInnerStuffCache {
return cachedMethods;
}
+ @NotNull
private Map<String, PsiClass> getInnerClassesMap() {
PsiClass[] classes = getInnerClasses();
if (classes.length == 0) return Collections.emptyMap();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index 60cb54cefe6b..55b760031646 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -882,7 +882,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
if (superParent instanceof PsiCodeBlock || superParent instanceof PsiLocalVariable) {
return true;
}
- if (superParent instanceof PsiClass) {
+ if (superParent instanceof PsiClass || superParent instanceof PsiCatchSection) {
return false;
}
superParent = superParent.getParent();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
index cd2e27f27b11..175f083ce319 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java
@@ -23,6 +23,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import java.util.List;
@@ -66,10 +67,18 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
}
} else {
- final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
- PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember();
LOG.assertTrue(applicableMember != null);
+
+ final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
+ final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass();
+ final PsiClass containingClass = qualifierResolveResult.getContainingClass();
+
+ PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
+ psiSubstitutor = applicableMemberContainingClass == null || containingClass == null || myExpression.isConstructor()
+ ? psiSubstitutor
+ : TypeConversionUtil.getSuperClassSubstitutor(applicableMemberContainingClass, containingClass, psiSubstitutor);
+
PsiType applicableMethodReturnType = applicableMember instanceof PsiMethod ? ((PsiMethod)applicableMember).getReturnType() : null;
int idx = 0;
for (PsiTypeParameter param : ((PsiTypeParameterListOwner)applicableMember).getTypeParameters()) {
@@ -99,7 +108,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(applicableMethodReturnType)));
} else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject());
- final PsiClass containingClass = qualifierResolveResult.getContainingClass();
+
if (containingClass != null) {
final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor);
constraints.add(new TypeCompatibilityConstraint(returnType, classType));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
index 49012290e52b..f01c82cae769 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/TypeCompatibilityConstraint.java
@@ -75,8 +75,6 @@ public class TypeCompatibilityConstraint implements ConstraintFormula {
if (sSubstitutor != null && PsiUtil.isRawSubstitutor(tClass, sSubstitutor)) {
return true;
}
- //comment in 18.2.2. Type Compatibility Constraints
- if (tClass instanceof PsiTypeParameter && ((PsiClassType)s).isRaw()) return true;
}
}
else if (t instanceof PsiArrayType && t.getArrayDimensions() == s.getArrayDimensions()) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java
index 9d9b1f1ce9e2..e359f7531757 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/StringLiteralManipulator.java
@@ -49,7 +49,8 @@ public class StringLiteralManipulator extends AbstractElementManipulator<PsiLite
return getValueRange(element);
}
- public static TextRange getValueRange(PsiLiteralExpression element) {
+ @NotNull
+ public static TextRange getValueRange(@NotNull PsiLiteralExpression element) {
final Object value = element.getValue();
if (!(value instanceof String || value instanceof Character)) return TextRange.from(0, element.getTextLength());
return new TextRange(1, Math.max(1, element.getTextLength() - 1));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
index 9e31f7b88656..4066c6cc4a78 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java
@@ -219,7 +219,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
}
@Override
- protected int getPertinentApplicabilityLevel(MethodCandidateInfo conflict) {
+ protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict) {
return conflict.isVarargs() ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY;
}
@@ -299,7 +299,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
}
@Override
- protected boolean nonComparable(CandidateInfo method, CandidateInfo conflict) {
+ protected boolean nonComparable(@NotNull CandidateInfo method, @NotNull CandidateInfo conflict) {
if (method == conflict) return true;
PsiElement psiElement = method.getElement();
PsiElement conflictElement = conflict.getElement();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
index 36a97157a8a1..73639b26c945 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiConditionalExpressionImpl.java
@@ -73,8 +73,12 @@ public class PsiConditionalExpressionImpl extends ExpressionPsiElement implement
if (type2 instanceof PsiClassType && type1.equals(PsiPrimitiveType.getUnboxedType(type2))) return type1;
if (TypeConversionUtil.isNumericType(typeRank1) && TypeConversionUtil.isNumericType(typeRank2)){
- if (typeRank1 == TypeConversionUtil.BYTE_RANK && typeRank2 == TypeConversionUtil.SHORT_RANK) return type2;
- if (typeRank1 == TypeConversionUtil.SHORT_RANK && typeRank2 == TypeConversionUtil.BYTE_RANK) return type1;
+ if (typeRank1 == TypeConversionUtil.BYTE_RANK && typeRank2 == TypeConversionUtil.SHORT_RANK) {
+ return type2 instanceof PsiPrimitiveType ? type2 : PsiPrimitiveType.getUnboxedType(type2);
+ }
+ if (typeRank1 == TypeConversionUtil.SHORT_RANK && typeRank2 == TypeConversionUtil.BYTE_RANK) {
+ return type1 instanceof PsiPrimitiveType ? type1 : PsiPrimitiveType.getUnboxedType(type1);
+ }
if (typeRank2 == TypeConversionUtil.INT_RANK && (typeRank1 == TypeConversionUtil.BYTE_RANK || typeRank1 == TypeConversionUtil.SHORT_RANK || typeRank1 == TypeConversionUtil.CHAR_RANK)){
if (TypeConversionUtil.areTypesAssignmentCompatible(type1, expr2)) return type1;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
index cf099fb33304..e5892be2fb4d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLiteralExpressionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -370,6 +370,7 @@ public class PsiLiteralExpressionImpl
}
}
+ @Override
public String toString() {
return "PsiLiteralExpression:" + getText();
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 94cce501d521..2209efe4141b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
-import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
@@ -45,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -228,7 +226,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
@Override
public void setQualifierExpression(@Nullable PsiExpression newQualifier) throws IncorrectOperationException {
if (newQualifier == null) {
- super.setQualifierExpression(newQualifier);
+ LOG.error("Forbidden null qualifier");
return;
}
final PsiExpression expression = getQualifierExpression();
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index aa18e6e6b8a4..f136c843aa87 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -131,9 +131,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
private static PsiLambdaExpression findNestedLambdaExpression(PsiExpression expression) {
if (expression instanceof PsiLambdaExpression) {
return (PsiLambdaExpression)expression;
- } else if (expression instanceof PsiParenthesizedExpression) {
+ }
+ else if (expression instanceof PsiParenthesizedExpression) {
return findNestedLambdaExpression(((PsiParenthesizedExpression)expression).getExpression());
- } else if (expression instanceof PsiConditionalExpression) {
+ }
+ else if (expression instanceof PsiConditionalExpression) {
PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(((PsiConditionalExpression)expression).getThenExpression());
if (lambdaExpression != null) {
return lambdaExpression;
@@ -143,7 +145,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return null;
}
- private static void checkLambdaApplicable(List<CandidateInfo> conflicts, int i, PsiLambdaExpression lambdaExpression) {
+ private static void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, int i, @NotNull PsiLambdaExpression lambdaExpression) {
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
ProgressManager.checkCanceled();
final CandidateInfo conflict = iterator.next();
@@ -192,12 +194,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
- protected boolean nonComparable(CandidateInfo method, CandidateInfo conflict) {
+ protected boolean nonComparable(@NotNull CandidateInfo method, @NotNull CandidateInfo conflict) {
assert method != conflict;
return false;
}
- protected static void checkAccessStaticLevels(List<CandidateInfo> conflicts, boolean checkAccessible) {
+ protected static void checkAccessStaticLevels(@NotNull List<CandidateInfo> conflicts, boolean checkAccessible) {
int conflictsCount = conflicts.size();
int maxCheckLevel = -1;
@@ -350,13 +352,13 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
- private static boolean areTypeParametersAgree(CandidateInfo info) {
+ private static boolean areTypeParametersAgree(@NotNull CandidateInfo info) {
return ((MethodCandidateInfo)info).getPertinentApplicabilityLevel() != MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
}
- private static boolean checkParametersNumber(final List<CandidateInfo> conflicts,
- final int argumentsCount,
- boolean ignoreIfStaticsProblem) {
+ private static boolean checkParametersNumber(@NotNull List<CandidateInfo> conflicts,
+ final int argumentsCount,
+ boolean ignoreIfStaticsProblem) {
boolean atLeastOneMatch = false;
TIntArrayList unmatchedIndices = null;
for (int i = 0; i < conflicts.size(); i++) {
@@ -392,7 +394,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
@MethodCandidateInfo.ApplicabilityLevelConstant
- protected int checkApplicability(List<CandidateInfo> conflicts) {
+ protected int checkApplicability(@NotNull List<CandidateInfo> conflicts) {
@MethodCandidateInfo.ApplicabilityLevelConstant int maxApplicabilityLevel = 0;
boolean toFilter = false;
for (CandidateInfo conflict : conflicts) {
@@ -420,27 +422,29 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return maxApplicabilityLevel;
}
- protected int getPertinentApplicabilityLevel(MethodCandidateInfo conflict) {
+ protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict) {
return conflict.getPertinentApplicabilityLevel();
}
- private static int getCheckAccessLevel(MethodCandidateInfo method){
+ private static int getCheckAccessLevel(@NotNull MethodCandidateInfo method){
boolean visible = method.isAccessible();
return visible ? 1 : 0;
}
- private static int getCheckStaticLevel(MethodCandidateInfo method){
+ private static int getCheckStaticLevel(@NotNull MethodCandidateInfo method){
boolean available = method.isStaticsScopeCorrect();
return (available ? 1 : 0) << 1 |
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
}
+ @NotNull
private PsiType[] getActualParameterTypes() {
- if (myActualParameterTypes == null) {
+ PsiType[] types = myActualParameterTypes;
+ if (types == null) {
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
- myActualParameterTypes = getArgumentTypes();
+ myActualParameterTypes = types = getArgumentTypes();
}
- return myActualParameterTypes;
+ return types;
}
private int getActualParametersLength() {
@@ -451,6 +455,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return myActualParameterTypes.length;
}
+ @NotNull
protected PsiType[] getArgumentTypes() {
return ((PsiExpressionList)myArgumentsList).getExpressionTypes();
}
@@ -470,8 +475,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return TypeConversionUtil.boxingConversionApplicable(parameterType, argType);
}
- private Specifics isMoreSpecific(final MethodCandidateInfo info1,
- final MethodCandidateInfo info2,
+ private Specifics isMoreSpecific(@NotNull MethodCandidateInfo info1,
+ @NotNull MethodCandidateInfo info2,
@MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
@NotNull LanguageLevel languageLevel) {
PsiMethod method1 = info1.getElement();
@@ -684,11 +689,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return Specifics.NEITHER;
}
- private boolean isApplicableTo(PsiType[] types2AtSite,
- PsiMethod method1,
- LanguageLevel languageLevel,
+ private boolean isApplicableTo(@NotNull PsiType[] types2AtSite,
+ @NotNull PsiMethod method1,
+ @NotNull LanguageLevel languageLevel,
boolean varargsPosition,
- final PsiSubstitutor methodSubstitutor1,
+ @NotNull PsiSubstitutor methodSubstitutor1,
PsiMethod method2,
PsiSubstitutor siteSubstitutor1) {
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && method2 != null && method1.getTypeParameters().length > 0 && myArgumentsList instanceof PsiExpressionList) {
@@ -701,7 +706,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
}
- private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) {
+ @NotNull
+ private static PsiType[] typesAtSite(@NotNull PsiType[] types1, @NotNull PsiSubstitutor siteSubstitutor1) {
final PsiType[] types = PsiType.createArray(types1.length);
for (int i = 0; i < types1.length; i++) {
types[i] = siteSubstitutor1.substitute(types1[i]);
@@ -709,11 +715,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return types;
}
- private static PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
- final PsiMethod method,
- final PsiSubstitutor siteSubstitutor,
- final PsiType[] types1,
- final PsiType[] types2,
+ @NotNull
+ private static PsiSubstitutor calculateMethodSubstitutor(@NotNull PsiTypeParameter[] typeParameters,
+ @NotNull PsiMethod method,
+ @NotNull PsiSubstitutor siteSubstitutor,
+ @NotNull PsiType[] types1,
+ @NotNull PsiType[] types2,
@NotNull LanguageLevel languageLevel) {
PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(method.getProject())
.inferTypeArguments(typeParameters, types1, types2, languageLevel);
@@ -742,7 +749,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return substitutor;
}
- public void checkPrimitiveVarargs(final List<CandidateInfo> conflicts,
+ public void checkPrimitiveVarargs(@NotNull List<CandidateInfo> conflicts,
final int argumentsCount) {
if (JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7)) return;
CandidateInfo objectVararg = null;
@@ -778,7 +785,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
@Nullable
- private static PsiType getFunctionalType(int functionalTypeIdx, CandidateInfo candidateInfo) {
+ private static PsiType getFunctionalType(int functionalTypeIdx, @NotNull CandidateInfo candidateInfo) {
final PsiMethod psiMethod = (PsiMethod)candidateInfo.getElement();
LOG.assertTrue(true);
final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters();
@@ -787,8 +794,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return ((MethodCandidateInfo)candidateInfo).getSiteSubstitutor().substitute(param.getType());
}
- private static Specifics isFunctionalTypeMoreSpecific(CandidateInfo method,
- CandidateInfo conflict,
+ @NotNull
+ private static Specifics isFunctionalTypeMoreSpecific(@NotNull CandidateInfo method,
+ @NotNull CandidateInfo conflict,
PsiExpression expr,
int functionalInterfaceIdx) {
if (expr instanceof PsiParenthesizedExpression) {
diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties
index cfc556c4c55c..e4e2303a2be4 100644
--- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties
+++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties
@@ -242,6 +242,7 @@ duplicate.switch.label=Duplicate label ''{0}''
switch.colon.expected.after.case.label=':' expected
illegal.forward.reference=Illegal forward reference
+illegal.self.reference=Illegal self reference
unknown.class=Unknown class: ''{0}''
illegal.type.void=Illegal type: 'void'
diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java
index f30025eeb12b..6ef47262a4c2 100644
--- a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java
+++ b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java
@@ -20,10 +20,12 @@ import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.reflect.Field;
public final class IdeaAntLogger2 extends DefaultLogger {
static SegmentedOutputStream ourErr;
@@ -82,7 +84,7 @@ public final class IdeaAntLogger2 extends DefaultLogger {
}
public synchronized void targetFinished(BuildEvent event) {
- sendException(event);
+ sendException(event, true);
myTargetPriority.sendMessage(TARGET_END, event.getPriority(), event.getException());
}
@@ -91,25 +93,56 @@ public final class IdeaAntLogger2 extends DefaultLogger {
}
public synchronized void taskFinished(BuildEvent event) {
- sendException(event);
+ sendException(event, true);
myTaskPriority.sendMessage(TASK_END, event.getPriority(), event.getException());
}
public synchronized void messageLogged(BuildEvent event) {
- if (sendException(event)) return;
+ final boolean failOnError = isFailOnError(event);
+ if (sendException(event, failOnError)) {
+ return;
+ }
+
int priority = event.getPriority();
- String message = event.getMessage();
- if (priority == Project.MSG_ERR)
+ if (priority == Project.MSG_ERR && !failOnError) {
+ // some ant tasks (like Copy) with 'failOnError' attribute set to 'false'
+ // send warnings with priority level = Project.MSG_ERR
+ // this heuristic corrects the priority level, so that IDEA considers the message not as an error but as a warning
+ priority = Project.MSG_WARN;
+ }
+
+ final String message = event.getMessage();
+
+ if (priority == Project.MSG_ERR) {
myMessagePriority.sendMessage(ERROR, priority, message);
- else
+ }
+ else {
myMessagePriority.sendMessage(MESSAGE, priority, message);
+ }
}
- private boolean sendException(BuildEvent event) {
+ private static boolean isFailOnError(BuildEvent event) {
+ final Task task = event.getTask();
+ if (task != null) {
+ try {
+ final Field field = task.getClass().getDeclaredField("failonerror");
+ field.setAccessible(true);
+ return !Boolean.FALSE.equals(field.get(task));
+ }
+ catch (Exception ignored) {
+ }
+ }
+ return true; // default value
+ }
+
+ private boolean sendException(BuildEvent event, boolean isFailOnError) {
Throwable exception = event.getException();
if (exception != null) {
- myAlwaysSend.sendMessage(EXCEPTION, event.getPriority(), exception);
- return true;
+ if (isFailOnError) {
+ myAlwaysSend.sendMessage(EXCEPTION, event.getPriority(), exception);
+ return true;
+ }
+ myMessagePriority.sendMessage(MESSAGE, Project.MSG_WARN, exception.getMessage());
}
return false;
}
diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml
index 248b1d3b1836..09b0e28aa3fd 100644
--- a/java/java-tests/java-tests.iml
+++ b/java/java-tests/java-tests.iml
@@ -16,7 +16,7 @@
<orderEntry type="library" name="Velocity" level="project" />
<orderEntry type="module" module-name="java-i18n" exported="" />
<orderEntry type="module" module-name="compiler-impl" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="module" module-name="instrumentation-util" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="module" module-name="IntelliLang-java" scope="RUNTIME" />
diff --git a/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java b/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java
index d53d73ed7770..3cf8eb4381a0 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/AddMissingParen_after.java
@@ -3,7 +3,6 @@ class Foo {
abstract void a();
{
- a();
- <caret>
+ a();<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java b/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java
index d53d73ed7770..3cf8eb4381a0 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/AddMissingSemicolon_after.java
@@ -3,7 +3,6 @@ class Foo {
abstract void a();
{
- a();
- <caret>
+ a();<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/ArrayInitializerRBracket_after.java b/java/java-tests/testData/codeInsight/completeStatement/ArrayInitializerRBracket_after.java
index d766b4a44036..2a09299fe603 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/ArrayInitializerRBracket_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/ArrayInitializerRBracket_after.java
@@ -1,6 +1,5 @@
public class Foo {
public void fails() {
- boolean[] a = new boolean[f()];
- <caret>
+ boolean[] a = new boolean[f()];<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/BraceFixeNewLine_after.java b/java/java-tests/testData/codeInsight/completeStatement/BraceFixeNewLine_after.java
index 059822dba58b..7a129a9e7cd4 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/BraceFixeNewLine_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/BraceFixeNewLine_after.java
@@ -3,7 +3,6 @@ public class test {
int k1 = 1;
int k2 = 2;
int[] array = new int[]{k1, k2};
- <caret>
System.out.print(k1);
}
diff --git a/java/java-tests/testData/codeInsight/completeStatement/CdrEndlessLoop_after.java b/java/java-tests/testData/codeInsight/completeStatement/CdrEndlessLoop_after.java
index 07d76498a979..b690a469b8f6 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/CdrEndlessLoop_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/CdrEndlessLoop_after.java
@@ -1,6 +1,5 @@
public class Test {
public int foo(int i) {
- int ii = foo(0);
- <caret>
+ int ii = foo(0);<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/FollowedByComment_after.java b/java/java-tests/testData/codeInsight/completeStatement/FollowedByComment_after.java
index f146a881244e..209898fbdac0 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/FollowedByComment_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/FollowedByComment_after.java
@@ -1,7 +1,6 @@
public class Foo {
public void foo() {
- foo();
- <caret>
+ foo();<caret>
// some line comment
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/IDEA22125_after.java b/java/java-tests/testData/codeInsight/completeStatement/IDEA22125_after.java
index 3579bfdb17f1..61fca2462f1b 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/IDEA22125_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/IDEA22125_after.java
@@ -1,7 +1,6 @@
public class Junk {
public static void main(String[] args) {
- int i = 1; // comment
- <caret>
+ int i = 1; // comment<caret>
}
}
diff --git a/java/java-tests/testData/codeInsight/completeStatement/IDEADEV40479_after.java b/java/java-tests/testData/codeInsight/completeStatement/IDEADEV40479_after.java
index 89767d3ba494..c61c4caa18c1 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/IDEADEV40479_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/IDEADEV40479_after.java
@@ -1,7 +1,6 @@
public class Junk {
public static void main(String[] args) {
- int[] arr = new int[]{1, 2, 3};
- <caret>
+ int[] arr = new int[]{1, 2, 3};<caret>
}
}
diff --git a/java/java-tests/testData/codeInsight/completeStatement/IncompleteCall_after.java b/java/java-tests/testData/codeInsight/completeStatement/IncompleteCall_after.java
index 2aa9baa41b11..608de1eeac93 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/IncompleteCall_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/IncompleteCall_after.java
@@ -1,8 +1,7 @@
public class Foo {
{
- foo();
- <caret>
+ foo();<caret>
foo();
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java
index 77770c0d371c..1d2e3fc6be6f 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/MultilineCall_after.java
@@ -1,7 +1,6 @@
class Test {
Object method() {
method(
- factory());
- <caret>
+ factory());<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/NewInParentheses_after.java b/java/java-tests/testData/codeInsight/completeStatement/NewInParentheses_after.java
index b7512bcd17c2..0bdd9c0d5a21 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/NewInParentheses_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/NewInParentheses_after.java
@@ -1,7 +1,6 @@
class foo {
{
- Object d = ((String) new String());
- <caret>
+ Object d = ((String) new String());<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/Parenthesized_after.java b/java/java-tests/testData/codeInsight/completeStatement/Parenthesized_after.java
index 9b159d219f4a..cecc090aecc5 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/Parenthesized_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/Parenthesized_after.java
@@ -1,7 +1,6 @@
class Foo {
{
- tx2 = (long) (vcx + vw);
- <caret>
+ tx2 = (long) (vcx + vw);<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completeStatement/StringLiteral_after.java b/java/java-tests/testData/codeInsight/completeStatement/StringLiteral_after.java
index 977a63e23430..b76baf554d45 100644
--- a/java/java-tests/testData/codeInsight/completeStatement/StringLiteral_after.java
+++ b/java/java-tests/testData/codeInsight/completeStatement/StringLiteral_after.java
@@ -1,7 +1,6 @@
class foo {
{
- String s = "a";
- <caret>
+ String s = "a";<caret>
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/CharsetName.java b/java/java-tests/testData/codeInsight/completion/normal/CharsetName.java
new file mode 100644
index 000000000000..c932c81751d6
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/CharsetName.java
@@ -0,0 +1,7 @@
+import java.nio.charset.Charset;
+
+public final class FileAttributes {
+ {
+ Charset.forName("utf<caret>")
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/DeepInner.java b/java/java-tests/testData/codeInsight/completion/normal/DeepInner.java
new file mode 100644
index 000000000000..33d1ac441a68
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/DeepInner.java
@@ -0,0 +1,13 @@
+class ClassMain{
+ public static class ClassInner1{
+ public static class ClassInner2{
+
+ }
+ }
+}
+
+class Foo {
+ {
+ new ClassMain.Cla<caret>
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/DeepInner_after.java b/java/java-tests/testData/codeInsight/completion/normal/DeepInner_after.java
new file mode 100644
index 000000000000..f46d6f10dc00
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/DeepInner_after.java
@@ -0,0 +1,13 @@
+class ClassMain{
+ public static class ClassInner1{
+ public static class ClassInner2{
+
+ }
+ }
+}
+
+class Foo {
+ {
+ new ClassMain.ClassInner1.ClassInner2()<caret>
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java
index 4761cce70c89..43e916863b55 100644
--- a/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java
+++ b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java
@@ -8,7 +8,6 @@ class Tester {
}
public void test1() {
- build(new EntityBuilder());
- <caret>
+ build(new EntityBuilder());<caret>
}
}
diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/HonorFirstLetterCase.java b/java/java-tests/testData/codeInsight/completion/normalSorting/HonorFirstLetterCase.java
new file mode 100644
index 000000000000..7edb9cd571f3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normalSorting/HonorFirstLetterCase.java
@@ -0,0 +1,11 @@
+import java.io.*;
+
+class Foo {
+ {
+ pim<caret>
+ }
+}
+
+class PNGImageDecoder {}
+class PImageDecoder {}
+class posIdMap {}
diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferAnnotationsToInterfaceKeyword.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferAnnotationsToInterfaceKeyword.java
new file mode 100644
index 000000000000..7d1d4ff899ef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferAnnotationsToInterfaceKeyword.java
@@ -0,0 +1,4 @@
+class A {
+ @<caret>
+ void foo(){}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferThrownExceptionsInCatch.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferThrownExceptionsInCatch.java
new file mode 100644
index 000000000000..c1d412270715
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferThrownExceptionsInCatch.java
@@ -0,0 +1,15 @@
+import java.io.*;
+
+class Foo {
+ {
+ try {
+ foo();
+ } catch (<caret>)
+ }
+
+ private void foo() throws FileNotFoundException {
+ }
+
+ private void bar() throws ArrayIndexOutOfBoundsException {
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/ConstructorArgsSmartEnter-out.java b/java/java-tests/testData/codeInsight/completion/smartType/ConstructorArgsSmartEnter-out.java
index 484b537fe6de..9d25f937591d 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/ConstructorArgsSmartEnter-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/ConstructorArgsSmartEnter-out.java
@@ -5,7 +5,6 @@ public class MyJavaClass {
{
- List l = new ArrayList(239);
- <caret>
+ List l = new ArrayList(239);<caret>
}
}
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SmartFinish-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SmartFinish-out.java
index 1583beea2183..e95297e009b7 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/SmartFinish-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/SmartFinish-out.java
@@ -2,8 +2,7 @@ public class Foo {
{
Foo foo = null;
- Foo bar = id(foo);
- <caret>
+ Foo bar = id(foo);<caret>
}
Foo id(Foo foo) {return foo;}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/IllegalForwardReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/IllegalForwardReference.java
index 88dd9534444e..45663a186dda 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/IllegalForwardReference.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/IllegalForwardReference.java
@@ -13,7 +13,7 @@ public class a {
int k = 1 + <error descr="Illegal forward reference">ki</error>;
int ki;
- final int fi5 = <error descr="Illegal forward reference">fi5</error> + 1;
+ final int fi5 = <error descr="Illegal self reference">fi5</error> + 1;
}
class a1 {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java
index cd9c7e16e415..8ec18fd42521 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg1.java
@@ -5,14 +5,14 @@ class Neg01<X extends Number> {
<Z> Neg01(X x, Z z) {}
void test() {
- Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
- Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
- Neg01<?> n3 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
- Neg01<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
+ Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
+ Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
+ Neg01<?> n3 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
+ Neg01<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>;
- Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Neg01<?> n7 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- <error descr="Cannot resolve symbol 'Foo'">Foo</error><? super String> n8 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Neg01<?> n7 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ <error descr="Cannot resolve symbol 'Foo'">Foo</error><? super String> n8 = new Neg01<><error descr="'Neg01(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java
index f1a2f75daed1..045ba94144a5 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg2.java
@@ -6,26 +6,26 @@ class Neg02 {
}
void testSimple() {
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> f7 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> f7 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
void testQualified() {
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> f3 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> f3 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> f7 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> f7 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg02.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java
index ac66d2a1d4b7..29295ebbc989 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg3.java
@@ -6,38 +6,38 @@ class Neg03<U> {
}
void testSimple() {
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> f7 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> f7 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
void testQualified_1() {
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> f3 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> f3 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> f7 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> f7 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
void testQualified_2(Neg03<U> n) {
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> f3 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> f3 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> f7 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> f7 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = n.new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java
index 55b50c5b457b..ecf72df10521 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg4.java
@@ -5,14 +5,14 @@ class Neg04 {
Foo(V x) {}
<Z> Foo(V x, Z z) {}
}
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<?> n3 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<?> n3 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>;
- Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<?> n7 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
- Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<?> n7 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
+ Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg7.java
index 84771a652d90..3d356a9e14fc 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg7.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/DiamondNeg7.java
@@ -4,5 +4,5 @@ class Neg07 {
Foo(X x) {}
}
- SuperFoo<String> sf1 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg07.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
+ SuperFoo<String> sf1 = new Foo<><error descr="'Foo(java.lang.Number & java.lang.String)' in 'Neg07.Foo' cannot be applied to '(java.lang.String)'">("")</error>;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA111420.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA111420.java
index eafce26dfa17..d5e43e164b85 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA111420.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA111420.java
@@ -1,7 +1,7 @@
import java.util.List;
public class Test {
- private static final <error descr="Incompatible types. Found: 'java.util.List<java.lang.Class<? extends java.io.Serializable & java.lang.Cloneable>>', required: 'java.util.List<java.lang.Class<?>>'">List<Class<?>> PRIMITIVE_ARRAY_TYPES = asList(byte[].class, int[].class);</error>
+ private static final <error descr="Incompatible types. Found: 'java.util.List<java.lang.Class<? extends java.lang.Cloneable & java.io.Serializable>>', required: 'java.util.List<java.lang.Class<?>>'">List<Class<?>> PRIMITIVE_ARRAY_TYPES = asList(byte[].class, int[].class);</error>
private static final List<?> PRIMITIVE_ARRAY_TYPES1 = asList(byte[].class, int[].class);
public static <T> List<T> asList(T... a) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA124363.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA124363.java
new file mode 100644
index 000000000000..577e19a7916d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA124363.java
@@ -0,0 +1,16 @@
+import java.util.*;
+
+class MyTClass {
+
+ <T> void foo(final List<Object> objects){
+ Collection<? extends T> collection = (Collection<? extends T>) objects;
+ }
+
+ <T> void foo1(final List<Object> objects){
+ Collection<? super T> collection = (Collection<? super T>) objects;
+ }
+
+ <T extends String> void bar(final List<Object> objects){
+ Collection<? extends T> collection = <error descr="Inconvertible types; cannot cast 'java.util.List<java.lang.Object>' to 'java.util.Collection<? extends T>'">(Collection<? extends T>) objects</error>;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA125423.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA125423.java
index d2515eef82eb..868b4dffd7ac 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA125423.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA125423.java
@@ -1,6 +1,19 @@
+import java.util.Comparator;
+import java.util.List;
+
+class Test {
+ public static final Comparator<Object> ORDER_AWARE_COMPARATOR = null;
+
+ public static void orderAwareSort(List<?> data) {
+ sort(data, ORDER_AWARE_COMPARATOR);
+ }
+
+ public static <T> void sort(List<T> list, Comparator<? super T> c) {}
+}
+
class FooBar<T> {
void foo(final FooBar<?> fooBar){
- fooBar.supertype<error descr="'supertype(java.lang.Class<capture<?>>)' in 'FooBar' cannot be applied to '(java.lang.Class<java.lang.Iterable>)'">(Iterable.class)</error>;
+ //fooBar.supertype(Iterable.class);
}
void foo1(final FooBar<? super T> fooBar){
@@ -13,3 +26,4 @@ class FooBar<T> {
void supertype(Class<? super T> superclass) {}
}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126633.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126633.java
new file mode 100644
index 000000000000..19e79fc0eb95
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126633.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+class Test {
+ <T> List<T> test(final List<Object> foo) {
+ return (List<T>) foo;
+ }
+
+ <T> List<List<T>> test1(final List<List<Object>> foo) {
+ return <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.Object>>' to 'java.util.List<java.util.List<T>>'">(List<List<T>>) foo</error>;
+ }
+
+ <T> List<List<List<T>>> test2(final List<List<List<Object>>> foo) {
+ return <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.util.List<java.lang.Object>>>' to 'java.util.List<java.util.List<java.util.List<T>>>'">(List<List<List<T>>>) foo</error>;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126697.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126697.java
new file mode 100644
index 000000000000..895e5690c68e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA126697.java
@@ -0,0 +1,8 @@
+class Test {
+ private static void <warning descr="Private method 'test(java.lang.Short)' is never used">test</warning>(Short s) { System.out.println("Short:" + s); }
+ private static void test(short s) { System.out.println("short:" + s); }
+
+ public static void main(String ... args) {
+ test(true ? new Short((short) 1) : new Byte((byte) 1));
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParent.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParent.java
index 49c8f5bbeaad..3e270f73ee0e 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParent.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParent.java
@@ -7,7 +7,11 @@ class Foo<T> {
List<Foo> elements = getElements(parent);
- for (<error descr="Incompatible types. Found: 'java.lang.Object', required: 'Foo'">Foo foo : getElements(parent)</error>) {
+ /*for (Foo foo : getElements(parent)) {
+ System.out.println(foo);
+ }*/
+
+ for (Foo foo : getElementsArray(parent)) {
System.out.println(foo);
}
}
@@ -15,4 +19,8 @@ class Foo<T> {
public static <E extends Foo<E>> List<E> getElements(E parent) {
return new ArrayList<>();
}
+
+ public static <E extends Foo<E>> E[] getElementsArray(E parent) {
+ return null;
+ }
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParentArrayType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParentArrayType.java
new file mode 100644
index 000000000000..904e37257721
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/RawTypeFromParentArrayType.java
@@ -0,0 +1,14 @@
+import java.util.*;
+
+class Test {
+ protected Class[] getAllInterfaces(final Set<Class> interfaces, final Class[] classes) {
+ return interfaces.toArray(classes);
+ }
+ public static <T extends Collection<String>> T get(T out) {
+ return out;
+ }
+
+ public static void main(String[] args) {
+ Set<String> set = get(new HashSet());
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Intersection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Intersection.java
index 767b54788948..7a6312b3089b 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Intersection.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Intersection.java
@@ -13,8 +13,8 @@ class Test {
{
Object o1 = (Serializable & I) () -> {};
Object o2 = (I & Serializable) () -> {};
- Object o3 = (I & Runnable) <error descr="Multiple non-overriding abstract methods found in Runnable & I">() -> {}</error>;
- Object o4 = (A & Runnable) <error descr="Multiple non-overriding abstract methods found in Runnable & A">() -> {}</error>;
+ Object o3 = (I & Runnable) <error descr="Multiple non-overriding abstract methods found in I & Runnable">() -> {}</error>;
+ Object o4 = (A & Runnable) <error descr="Multiple non-overriding abstract methods found in A & Runnable">() -> {}</error>;
Object o5 = (Runnable & A) <error descr="Multiple non-overriding abstract methods found in Runnable & A">() -> {}</error>;
}
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/RecursiveAccess.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/RecursiveAccess.java
index cf95ac4fbfa6..fce52587f2ae 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/RecursiveAccess.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/RecursiveAccess.java
@@ -1,5 +1,5 @@
public class LambdaTest {
- Op lambda_fib = (n) -> (n < 2) ? 1 : <error descr="Illegal forward reference">lambda_fib</error>.op(n - 1) + <error descr="Illegal forward reference">lambda_fib</error>.op(n - 2);
+ Op lambda_fib = (n) -> (n < 2) ? 1 : <error descr="Illegal self reference">lambda_fib</error>.op(n - 1) + <error descr="Illegal self reference">lambda_fib</error>.op(n - 2);
{
Op lambda_fib = (n) -> (n < 2) ? 1 : <error descr="Variable 'lambda_fib' might not have been initialized">lambda_fib</error>.op(n - 1) + lambda_fib.op(n - 2);
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA119003.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA119003.java
index f56af02e5dd8..01646ddd1896 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA119003.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA119003.java
@@ -3,6 +3,7 @@ package problems;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
+import java.util.function.*;
import static java.util.stream.Collectors.*;
@@ -82,3 +83,32 @@ class Dish {
return name;
}
}
+
+class Test67 {
+
+ static {
+ collectingAndThen(reducing(), Optional::get);
+ collectingAndThen(reducing(), o -> o.get());
+ }
+
+ static <T> List<Optional<T>> reducing() {
+ return null;
+ }
+
+ static <R,RR> void collectingAndThen(List<R> downstream, Function<R,RR> finisher){}
+}
+
+class Test99 {
+
+ {
+ collectingAndThen(reducing((d1, d2) -> d2), Optional::get);
+ }
+
+ public static <COL, R, RR> void collectingAndThen(Collector<COL, R> downstream, Function<R, RR> finisher) {}
+
+ public static <RED> Collector<RED, Optional<RED>> reducing(BinaryOperator<RED> op) {
+ return null;
+ }
+
+ static class Collector<A, C>{}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124961.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124961.java
new file mode 100644
index 000000000000..ab8e99419a27
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124961.java
@@ -0,0 +1,16 @@
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+class Test {
+
+ private static void list(List<? extends CharSequence> l) {
+ Stream<? extends CharSequence> str = map(() -> l.get(0));
+ Stream<? extends CharSequence> str1 = map1(() -> l.get(0));
+ Stream<? extends CharSequence> str2 = map1(() -> l.get(0));
+ }
+
+ static <M> Stream<M> map (Supplier<? extends M> mapper) { return null;}
+ static <M> Stream<M> map1(Supplier<? super M> mapper) { return null;}
+ static <M> Stream<M> map2(Supplier<M> mapper) { return null;}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA125254.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA125254.java
new file mode 100644
index 000000000000..4d74d1424cc3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA125254.java
@@ -0,0 +1,103 @@
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.BiFunction;
+
+class Scratch
+{
+ public static void main(String[] args)
+ {
+ final ExecutorService threadPool = Executors.newCachedThreadPool();
+ final List<EventObject> events = new ArrayList<>();
+ final SoapInterface soap = new SoapInterface();
+
+ events.stream()
+ .map(event -> get(event).apply(soap, event))
+ .map(threadPool::submit)
+ .forEachOrdered(future -> {
+ try
+ {
+ if (! future.get().isError())
+ {
+
+ }
+ else
+ {
+ ;
+ }
+ }
+ catch (InterruptedException | ExecutionException e)
+ {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ public static BiFunction<SoapInterface, Object, Callable<Either<Object, Exception>>> get(Object o)
+ {
+ return (soap, event) -> toEither(
+ () -> {
+ return "value";
+ }
+ );
+ }
+
+ private static Callable<Either<Object, Exception>> toEither(Callable<Object> callable)
+ {
+ return () -> {
+ try
+ {
+ return Either.value(callable.call());
+ }
+ catch (Exception e)
+ {
+ return Either.error(e);
+ }
+ };
+ }
+
+ public static class EventObject { }
+
+ public static class SoapInterface { }
+
+ public static class Either<V, E>
+ {
+ private V value;
+
+ private E error;
+
+ private Either(V value, E error)
+ {
+ this.value = value;
+ this.error = error;
+ }
+
+ public static <V, E> Either<V, E> value(V value)
+ {
+ return new Either<>(value, null);
+ }
+
+ public static <V, E> Either<V, E> error(E error)
+ {
+ return new Either<>(null, error);
+ }
+
+ public V getValue()
+ {
+ return value;
+ }
+
+ public E getError()
+ {
+ return error;
+ }
+
+ public boolean isError()
+ {
+ return error != null;
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126109.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126109.java
new file mode 100644
index 000000000000..0fd7c685535a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126109.java
@@ -0,0 +1,26 @@
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class Test {
+ void foo(final Stream<Person> stream) {
+ final Map<String,List<Person>> mapByFirstLetter = stream.collect(Collectors.groupingBy(p -> "" + p.name.charAt(0)));
+
+ final String vV = mapByFirstLetter.values().stream().map(lp -> lp.stream().map(p -> p.name)
+ .collect(Collectors.joining("/","<",">"))) .collect(Collectors.joining(" : "));
+
+ final String vV2 = mapByFirstLetter.values().stream()
+ .map(lp -> lp.stream().map(Person::getName).collect(Collectors.joining("/","<",">")))
+ .collect(Collectors.joining(" : "));
+ System.out.println("mapByFirstLetter2 : "+ vV2);
+ }
+
+ public static class Person {
+ private String name;
+ public Person(String name) {
+ this.name = name;
+ }
+ public String getName() {return name;}
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126809.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126809.java
new file mode 100644
index 000000000000..df910d96e710
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA126809.java
@@ -0,0 +1,27 @@
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toSet;
+
+class App {
+
+ {
+ final User user = new User("test", Stream.of("TEST").collect(toSet()));
+ Optional.of(user).map(u -> new User(u.getName(),
+ u.getAttributes().stream().filter(a -> !a.equals("TEST")).collect(toSet())));
+ }
+
+ private static final class User {
+ User(final String name, final Set<String> attributes) {
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public Set<String> getAttributes() {
+ return null;
+ }
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java
new file mode 100644
index 000000000000..14ad192c8823
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java
@@ -0,0 +1,25 @@
+import java.util.function.Supplier;
+
+class EnumValues {
+
+ {
+ Supplier<I<ABC>> supplier = () -> new C<>(ABC::values);
+ }
+
+ private static interface I<T> {
+ T get();
+ }
+
+ private static class C<E> implements I<E> {
+ C(Supplier<E[]> supplier) {}
+
+ @Override
+ public E get() {
+ return null;
+ }
+ }
+
+ private static enum ABC {
+ A, B, C
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/MissedApplicableMemberContainingClassSubstitution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/MissedApplicableMemberContainingClassSubstitution.java
new file mode 100644
index 000000000000..7562e457f9aa
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/MissedApplicableMemberContainingClassSubstitution.java
@@ -0,0 +1,54 @@
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+class TestA {
+
+ public static class Entity<K> {
+ K id;
+ public K getId() {
+ return id;
+ }
+ }
+
+ public static class EntityVo {}
+
+ public static class Area extends Entity<Integer> {
+ }
+
+ public static class AreaVo {
+ public AreaVo(Area area, String lang) {
+
+ }
+ }
+
+ public static void main(String[] args) {
+ String language = "da";
+ List<Area> areas = new ArrayList<>();
+ Map<Integer, AreaVo> areaLookup = areas.stream()
+ .collect(Collectors.toMap(Area::getId, area -> new AreaVo(area, language)));
+ }
+
+}
+
+class TestSimple {
+
+ public static class Entity<K> {
+ K id;
+ public K getId() {
+ return id;
+ }
+ }
+
+ public static class Area extends Entity<Integer> {
+ }
+
+ public static <M> Set<M> toMap(Function<Area, M> keyMapper) {
+ return null;
+ }
+
+ {
+ Set<Integer> tMapCollector = toMap(Area::getId);
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/RejectReceiverTypesForConstructorRefs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/RejectReceiverTypesForConstructorRefs.java
new file mode 100644
index 000000000000..0954ed9a72e3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/RejectReceiverTypesForConstructorRefs.java
@@ -0,0 +1,21 @@
+import java.util.function.*;
+
+class ConstructorReferences {
+ public ConstructorReferences() {}
+ public ConstructorReferences(String s) {}
+ public ConstructorReferences(String s1, String s2) {}
+ public ConstructorReferences(ConstructorReferences other) {}
+ public ConstructorReferences(ConstructorReferences other1, ConstructorReferences other2) {}
+
+ public static void main(String[] args) {
+ Supplier<ConstructorReferences> supplier = ConstructorReferences::new;
+ Function<String,ConstructorReferences> function = ConstructorReferences::new;
+ BiFunction<String,String,ConstructorReferences> bifunction = ConstructorReferences::new;
+ UnaryOperator<ConstructorReferences> unaryOperator = ConstructorReferences:: new;
+ Function<ConstructorReferences,ConstructorReferences> unaryOperatorBaseClass = ConstructorReferences::new;
+ BinaryOperator<ConstructorReferences> binaryOperator = ConstructorReferences::new;
+ BiFunction<ConstructorReferences, ConstructorReferences, ConstructorReferences> binaryOperatorBaseClass = ConstructorReferences::new;
+ Consumer<ConstructorReferences> consumer = ConstructorReferences::new;
+ BiConsumer<ConstructorReferences,ConstructorReferences> biconsumer = ConstructorReferences::new;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/Constructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/Constructor.java
new file mode 100644
index 000000000000..fa782b8f177d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/Constructor.java
@@ -0,0 +1,26 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public A() {
+
+ MyElement localElement1 = getElement();
+
+ getProje<caret>ct();
+
+ MyElement localElement2 = getElement();
+
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixAfter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixAfter.java
new file mode 100644
index 000000000000..171715cd7572
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixAfter.java
@@ -0,0 +1,20 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public void m() {
+ fieldElement.getProject();
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixBefore.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixBefore.java
new file mode 100644
index 000000000000..9996e8aea88e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/FixBefore.java
@@ -0,0 +1,20 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public void m() {
+ getProje<caret>ct();
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NestedMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NestedMethod.java
new file mode 100644
index 000000000000..1135da99aa74
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NestedMethod.java
@@ -0,0 +1,36 @@
+import java.lang.Object;
+
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public void m(MyElement paramElement) {
+
+ Object o = new Object() {
+
+ private final MyElement nestedField;
+
+ public void targetMethod(MyElement nestedParamElement) {
+
+ final MyElement localElement1 = getElement();
+
+ getProje<caret>ct ();
+
+ MyElement localElement2 = getElement();
+
+ }
+ }
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NonStaticMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NonStaticMethod.java
new file mode 100644
index 000000000000..6407fa18e304
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/NonStaticMethod.java
@@ -0,0 +1,26 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public void targetMethod(MyElement paramElement) {
+
+ MyElement localElement1 = getElement();
+
+ getProje<caret>ct();
+
+ MyElement localElement2 = getElement();
+
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticInitializer.java
new file mode 100644
index 000000000000..94faa3139b6c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticInitializer.java
@@ -0,0 +1,26 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ static {
+
+ MyElement localElement1 = getElement();
+
+ getProje<caret>ct();
+
+ MyElement localElement2 = getElement();
+
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticMethod.java
new file mode 100644
index 000000000000..b7f033a546d4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/StaticMethod.java
@@ -0,0 +1,26 @@
+public class A {
+
+ Project p;
+ MyElement fieldElement;
+
+ static MyElement staticElement;
+
+ public static void targetMethod(MyElement paramElement) {
+
+ MyElement localElement1 = getElement();
+
+ getProje<caret>ct();
+
+ MyElement localElement2 = getElement();
+
+ }
+
+ interface Project {
+
+ }
+
+ interface MyElement {
+ Project getProject();
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeSelfReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeSelfReference.java
new file mode 100644
index 000000000000..7160a62ffbc3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeSelfReference.java
@@ -0,0 +1,9 @@
+// "Replace with lambda" "false"
+class Test {
+ Runnable runnable = new Runn<caret>able() {
+ @Override
+ public void run() {
+ System.out.println(runnable);
+ }
+ };
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterInsideNestedInner.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterInsideNestedInner.java
new file mode 100644
index 000000000000..9e5835481cb9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterInsideNestedInner.java
@@ -0,0 +1,18 @@
+// "Replace lambda with method reference" "true"
+class Example {
+ class Bar {
+ void foo() {
+ }
+
+ class Foo {
+
+ void bar() {
+ new Object() {
+ void baz() {
+ Runnable runnable = Bar.this::foo;
+ }
+ };
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideAnonymous.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideAnonymous.java
new file mode 100644
index 000000000000..e6ad36c82c9c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideAnonymous.java
@@ -0,0 +1,17 @@
+// "Replace lambda with method reference" "false"
+class Example {
+ {
+ new Object() {
+ void foo() {
+ }
+
+ void bar() {
+ new Object() {
+ void baz() {
+ Runnable runnable = () -> fo<caret>o();
+ }
+ };
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideNestedInner.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideNestedInner.java
new file mode 100644
index 000000000000..553b4330f222
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeInsideNestedInner.java
@@ -0,0 +1,18 @@
+// "Replace lambda with method reference" "true"
+class Example {
+ class Bar {
+ void foo() {
+ }
+
+ class Foo {
+
+ void bar() {
+ new Object() {
+ void baz() {
+ Runnable runnable = () -> fo<caret>o();
+ }
+ };
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterBase.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterBase.java
new file mode 100644
index 000000000000..da423aee9781
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterBase.java
@@ -0,0 +1,16 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (otherCondition) {
+ doAnotherAction();
+ } else if (someCondition) {
+ doSomeAction();
+ } else {
+ defaultAction();
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterManyStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterManyStatements.java
new file mode 100644
index 000000000000..2a70fb4ebbef
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterManyStatements.java
@@ -0,0 +1,20 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (a) {
+ System.out.println(1);
+ } else if (c) {
+ System.out.println(3);
+ } else if (b) {
+ System.out.println(2);
+ } else if (d) {
+ System.out.println(4);
+ } else {
+ System.out.println(5);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterWithoutBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterWithoutBrackets.java
new file mode 100644
index 000000000000..5c87fbc07eee
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/afterWithoutBrackets.java
@@ -0,0 +1,12 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (cond2) m2();
+ else if (cond1) m1();
+ else if (cond3) m3();
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeBase.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeBase.java
new file mode 100644
index 000000000000..146510c19e0f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeBase.java
@@ -0,0 +1,16 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (someCondition) {
+ doSomeAction();
+ } e<caret>lse if (otherCondition) {
+ doAnotherAction();
+ } else {
+ defaultAction();
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeManyStatements.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeManyStatements.java
new file mode 100644
index 000000000000..c1e7c1cac24d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeManyStatements.java
@@ -0,0 +1,20 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (a) {
+ System.out.println(1);
+ } else if (b) {
+ System.out.println(2);
+ } el<caret>se if (c) {
+ System.out.println(3);
+ } else if (d) {
+ System.out.println(4);
+ } else {
+ System.out.println(5);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeNotAvailable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeNotAvailable.java
new file mode 100644
index 000000000000..16a0bc0be56c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeNotAvailable.java
@@ -0,0 +1,10 @@
+// "Swap If Statements" "false"
+class A {
+ void m() {
+ if (someCondition) {
+ doSomeAction();
+ } e<caret>lse {
+ defaultAction();
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeWithoutBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeWithoutBrackets.java
new file mode 100644
index 000000000000..e7b3ac78e794
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements/beforeWithoutBrackets.java
@@ -0,0 +1,12 @@
+// "Swap If Statements" "true"
+class A {
+
+ void m() {
+
+ if (cond1) m1();
+ el<caret>se if (cond2) m2();
+ else if (cond3) m3();
+
+ }
+
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/afterCallAsArgument.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/afterCallAsArgument.java
new file mode 100644
index 000000000000..6ef1870458fb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/afterCallAsArgument.java
@@ -0,0 +1,11 @@
+// "Remove redundant assignment" "true"
+class Test {
+ void foo() {
+ String var;
+ this.bar("someString");
+ }
+
+ void bar(String arg) {
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/beforeCallAsArgument.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/beforeCallAsArgument.java
new file mode 100644
index 000000000000..116cc94e30f4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/unusedAssignment/beforeCallAsArgument.java
@@ -0,0 +1,11 @@
+// "Remove redundant assignment" "true"
+class Test {
+ void foo() {
+ String var;
+ this.bar(v<caret>ar = "someString");
+ }
+
+ void bar(String arg) {
+
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/javadocIG/annotations.html b/java/java-tests/testData/codeInsight/javadocIG/annotations.html
new file mode 100644
index 000000000000..39e57472104c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/annotations.html
@@ -0,0 +1,3 @@
+<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Test"><code>Test</code></a></b></small><PRE><font color=red>@Nullable</font>&nbsp;
+@<a href="psi_element://java.lang.Deprecated"><code>Deprecated</code></a>&nbsp;
+public <a href="psi_element://java.lang.String"><code>String</code></a> <b>field = null</b></PRE></body></html> \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/annotations.java b/java/java-tests/testData/codeInsight/javadocIG/annotations.java
new file mode 100644
index 000000000000..2a3a67458649
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/annotations.java
@@ -0,0 +1,5 @@
+class Test {
+ @Nullable
+ @Deprecated
+ public String field = null;
+} \ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/slice/backward/VarArgsAsAWhole.java b/java/java-tests/testData/codeInsight/slice/backward/VarArgsAsAWhole.java
new file mode 100644
index 000000000000..21ba9ba0053a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/slice/backward/VarArgsAsAWhole.java
@@ -0,0 +1,12 @@
+class VarArgs {
+ private void g() {
+ f<flown111>("d",1,2,3);
+ }
+
+ void f(String value,int... <flown11>i) {
+ v(value, <flown1>i);
+ }
+
+ private void v(String value, int... <caret>ints) {
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/slice/backward/VarArgsPartial.java b/java/java-tests/testData/codeInsight/slice/backward/VarArgsPartial.java
new file mode 100644
index 000000000000..1e59e130fddd
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/slice/backward/VarArgsPartial.java
@@ -0,0 +1,14 @@
+class VarArgs {
+ private static void foo(String value, int...<flown11>ints) {
+ System.out.println(value + " " + java.util.Arrays.asList(ints));
+ int <caret>anInt = <flown1>ints[1];
+ }
+
+ private static void bar(String value, int...<flown1111>ints) {
+ foo(value, <flown111>ints);
+ }
+
+ private static void baz(String value) {
+ bar<flown11111>("d", <flown111111>2, <flown111112>3, <flown111113>4);
+ }
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AssertTrueNotComplex.java b/java/java-tests/testData/inspection/dataFlow/fixture/AssertTrueNotComplex.java
new file mode 100644
index 000000000000..9eb541c05de6
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/AssertTrueNotComplex.java
@@ -0,0 +1,17 @@
+import org.jetbrains.annotations.Contract;
+
+import java.util.List;
+
+abstract class Some {
+ @Contract("_,false->fail")
+ abstract void assertTrue(String s, boolean b);
+
+ void assertContainsAllVariants(List<String> actualVariants, String... expectedVariants) {
+ for (String expectedVariant : expectedVariants) {
+ assertTrue(expectedVariant, actualVariants.contains(expectedVariant));
+ }
+ }
+
+}
+
+
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java
new file mode 100644
index 000000000000..a9f17f7e9a06
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullToNotNull.java
@@ -0,0 +1,14 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+class Bar3 {
+
+ public void foo(@Nullable Object element) {
+ final String elementType = element != null ? element.toString() : null;
+ if (elementType == "") {
+ System.out.println(element.hashCode());
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java
new file mode 100644
index 000000000000..5e3ce3c0b69b
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToNullable.java
@@ -0,0 +1,16 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+class Bar3 {
+
+ public void foo(@Nullable Object element) {
+ final String elementType = element != null ? element.toString() : null;
+ if (elementType == nullableString()) {
+ System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
+ }
+ }
+
+ @Nullable String nullableString() { return null; }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java
new file mode 100644
index 000000000000..b15c6c7a52f7
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/ComparingNullableToUnknown.java
@@ -0,0 +1,16 @@
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+class Bar3 {
+
+ public void foo(@Nullable Object element) {
+ final String elementType = element != null ? element.toString() : null;
+ if (elementType == someString()) {
+ System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
+ }
+ }
+
+ String someString() { return <warning descr="'null' is returned by the method which is not declared as @Nullable">null</warning>; }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/offline/project/src/Test.java b/java/java-tests/testData/inspection/offline/project/src/Test.java
new file mode 100644
index 000000000000..94e0c00069f6
--- /dev/null
+++ b/java/java-tests/testData/inspection/offline/project/src/Test.java
@@ -0,0 +1,52 @@
+/**
+ * User: anna
+ * Date: 25-Apr-2006
+ */
+public class Test {
+ private boolean myFlag = false;
+ @SuppressWarnings({"PointlessBooleanExpression"})
+ boolean foo(){
+ boolean flag = false;
+ if (flag == false){
+ flag = true;
+ }
+ int j = 0;
+ if (myFlag) return false;
+ return flag;
+ }
+
+ /*private int bar() {
+ int i = 0;
+ return i;
+ }*/
+
+
+ private void fooo(){
+ this.fooo();
+ }
+
+ public void deadCode() {
+
+ }
+ public static void main(String[] args){
+ Test test = new Test();
+ }
+
+ public void f() {
+ class D {
+ void b() {
+ Runnable r = new Runnable() {
+ public void run() {
+ int i = 0;
+
+ }
+ };
+ }
+ }
+ }
+
+ void ff() {
+ long d = 5;
+ int a = 0;
+ }
+}
diff --git a/java/java-tests/testData/inspection/offline/res/UnusedAssignment.xml b/java/java-tests/testData/inspection/offline/res/UnusedAssignment.xml
new file mode 100644
index 000000000000..9829cf8555ce
--- /dev/null
+++ b/java/java-tests/testData/inspection/offline/res/UnusedAssignment.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>13</line>
+ <entry_point TYPE="method" FQNAME="Test boolean foo()">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>boolean foo()</name>
+ <name>foo()</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;j&lt;/code&gt; is never used.</description>
+ </problem>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>40</line>
+ <entry_point TYPE="method" FQNAME="Test$2D$1 void run()">
+ <entry_point TYPE="class" FQNAME="Test$2D$1">
+ <entry_point TYPE="method" FQNAME="Test$2D void b()">
+ <entry_point TYPE="class" FQNAME="Test$2D">
+ <entry_point TYPE="method" FQNAME="Test void f()">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ </entry_point>
+ </entry_point>
+ </entry_point>
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>void run()</name>
+ <name>run()</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;i&lt;/code&gt; is never used.</description>
+ </problem>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>49</line>
+ <entry_point TYPE="method" FQNAME="Test void ff()">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>void ff()</name>
+ <name>ff()</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;d&lt;/code&gt; is never used.</description>
+ </problem>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>50</line>
+ <entry_point TYPE="method" FQNAME="Test void ff()">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>void ff()</name>
+ <name>ff()</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;a&lt;/code&gt; is never used.</description>
+ </problem>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>32</line>
+ <entry_point TYPE="method" FQNAME="Test void main(java.lang.String[] args)">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>void main(String[] args)</name>
+ <name>main(String[])</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;test&lt;/code&gt; is never used.</description>
+ </problem>
+ <problem>
+ <file>file://$PROJECT_DIR$/javamodule/src/Test.java</file>
+ <line>38</line>
+ <entry_point TYPE="method" FQNAME="Test$2D void b()">
+ <entry_point TYPE="class" FQNAME="Test$2D">
+ <entry_point TYPE="method" FQNAME="Test void f()">
+ <entry_point TYPE="class" FQNAME="Test" />
+ </entry_point>
+ </entry_point>
+ </entry_point>
+ <module>javamodule</module>
+ <method>
+ <name>void b()</name>
+ <name>b()</name>
+ <package>&lt;default&gt;</package>
+ <class>
+ <name>Test</name>
+ <display_name>Test</display_name>
+ </class>
+ </method>
+ <problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused assignment</problem_class>
+ <description>Variable &lt;code&gt;r&lt;/code&gt; is never used.</description>
+ </problem>
+</problems>
+
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/expected.xml b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/expected.xml
new file mode 100644
index 000000000000..4704d91e891d
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/expected.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems/> \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/src/Test.java b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/src/Test.java
new file mode 100644
index 000000000000..18bf47f111b5
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/generics/ForEachValueIDEA126166/src/Test.java
@@ -0,0 +1,11 @@
+import java.util.ArrayList;
+import java.util.List;
+
+class SomeClass {
+ public void test() {
+ List<?> objects = new ArrayList<>();
+ for (String value : (Iterable<? extends String>) objects) {
+ System.out.println(value);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml b/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml
new file mode 100644
index 000000000000..4704d91e891d
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/expected.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems/> \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java b/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java
new file mode 100644
index 000000000000..bd2236cfe9f1
--- /dev/null
+++ b/java/java-tests/testData/inspection/redundantCast/lambda/ForeachValue/src/Test.java
@@ -0,0 +1,10 @@
+import java.util.Arrays;
+import java.util.Iterator;
+
+class IterableMain {
+ public static void main(final String... args) {
+ for (final String s : (Iterable<String>) XIterator::new) {}
+ }
+
+ public static interface XIterator extends Iterator<String> {}
+} \ No newline at end of file
diff --git a/java/java-tests/testData/inspection/suspiciousCalls/RemoveAll14.java b/java/java-tests/testData/inspection/suspiciousCalls/RemoveAll14.java
new file mode 100644
index 000000000000..f6e2c033b6fc
--- /dev/null
+++ b/java/java-tests/testData/inspection/suspiciousCalls/RemoveAll14.java
@@ -0,0 +1,14 @@
+import java.util.*;
+
+
+class Simple {
+ public static void main(Set set, Set setO) {
+ class O {}
+
+ Map someData = new HashMap();
+
+ set.removeAll(someData.keySet());
+ setO.removeAll(someData.keySet());
+
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
index 82d04fec4659..d64c31b56472 100644
--- a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
+++ b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
@@ -4,6 +4,910 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiRefListStub[EXTENDS_LIST:]
PsiRefListStub[IMPLEMENTS_LIST:]
+ PsiClassStub[name=AsLIFOQueue fqn=java.util.Collections.AsLIFOQueue]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.AbstractQueue<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Queue<E>, java.io.Serializable]
+ PsiFieldStub[serialVersionUID:long=1802017725587941708L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[q:java.util.Deque<E>]
+ PsiModifierListStub[mask=18]
+ PsiMethodStub[cons AsLIFOQueue:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Deque<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[offer:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[poll:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[peek:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[element:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[clear:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[size:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[contains:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[removeAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[retainAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedCollection fqn=java.util.Collections.CheckedCollection]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Collection<E>, java.io.Serializable]
+ PsiFieldStub[serialVersionUID:long=1578914078182001775L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[c:java.util.Collection<E>]
+ PsiModifierListStub[mask=4112]
+ PsiFieldStub[type:java.lang.Class<E>]
+ PsiModifierListStub[mask=4112]
+ PsiFieldStub[zeroLengthElementArray:E[]]
+ PsiModifierListStub[mask=2]
+ PsiMethodStub[typeCheck:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[badElementMsg:java.lang.String]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[cons CheckedCollection:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<E>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[size:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[contains:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[clear:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[removeAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[retainAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[zeroLengthElementArray:E[]]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[checkedCopyOf:java.util.Collection<E>]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<? extends E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[addAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<? extends E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedList fqn=java.util.Collections.CheckedList]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.CheckedCollection<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.List<E>]
+ PsiFieldStub[serialVersionUID:long=65247728283967356L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[list:java.util.List<E>]
+ PsiModifierListStub[mask=4112]
+ PsiMethodStub[cons CheckedList:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.List<E>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[get:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[indexOf:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[lastIndexOf:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[set:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[addAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.util.Collection<? extends E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[listIterator:java.util.ListIterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[listIterator:java.util.ListIterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[subList:java.util.List<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedMap fqn=java.util.Collections.CheckedMap]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Map<K,V>, java.io.Serializable]
+ PsiClassStub[name=CheckedEntrySet fqn=java.util.Collections.CheckedMap.CheckedEntrySet]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Set<java.util.Map.Entry<K,V>>]
+ PsiClassStub[name=CheckedEntry fqn=java.util.Collections.CheckedMap.CheckedEntrySet.CheckedEntry]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Map.Entry<K,V>]
+ PsiFieldStub[e:java.util.Map.Entry<K,V>]
+ PsiModifierListStub[mask=18]
+ PsiFieldStub[valueType:java.lang.Class<T>]
+ PsiModifierListStub[mask=18]
+ PsiMethodStub[cons CheckedEntry:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map.Entry<K,V>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<T>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[getKey:K]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[getValue:V]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[setValue:V]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:V]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[badValueMsg:java.lang.String]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiFieldStub[s:java.util.Set<java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=18]
+ PsiFieldStub[valueType:java.lang.Class<V>]
+ PsiModifierListStub[mask=18]
+ PsiMethodStub[cons CheckedEntrySet:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Set<java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<V>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[size:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[clear:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map.Entry<K,V>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[addAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<? extends java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[contains:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[removeAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[retainAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[batchRemove:boolean]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:boolean]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[checkedEntry:java.util.Collections.CheckedMap.CheckedEntrySet.CheckedEntry<K,V,T>]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map.Entry<K,V>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<T>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiFieldStub[serialVersionUID:long=5742860141034234728L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[m:java.util.Map<K,V>]
+ PsiModifierListStub[mask=18]
+ PsiFieldStub[keyType:java.lang.Class<K>]
+ PsiModifierListStub[mask=4112]
+ PsiFieldStub[valueType:java.lang.Class<V>]
+ PsiModifierListStub[mask=4112]
+ PsiFieldStub[entrySet:java.util.Set<java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=130]
+ PsiMethodStub[typeCheck:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[badKeyMsg:java.lang.String]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[badValueMsg:java.lang.String]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[cons CheckedMap:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map<K,V>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<K>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p3:java.lang.Class<V>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[size:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsKey:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsValue:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[get:V]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:V]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[clear:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[keySet:java.util.Set<K>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[values:java.util.Collection<V>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[put:V]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:K]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:V]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[putAll:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map<? extends K,? extends V>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[entrySet:java.util.Set<java.util.Map.Entry<K,V>>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedRandomAccessList fqn=java.util.Collections.CheckedRandomAccessList]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.CheckedList<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.RandomAccess]
+ PsiFieldStub[serialVersionUID:long=1638200125423088369L]
+ PsiModifierListStub[mask=26]
+ PsiMethodStub[cons CheckedRandomAccessList:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.List<E>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[subList:java.util.List<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedSet fqn=java.util.Collections.CheckedSet]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.CheckedCollection<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Set<E>, java.io.Serializable]
+ PsiFieldStub[serialVersionUID:long=4694047833775013803L]
+ PsiModifierListStub[mask=26]
+ PsiMethodStub[cons CheckedSet:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Set<E>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedSortedMap fqn=java.util.Collections.CheckedSortedMap]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.CheckedMap<K,V>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.SortedMap<K,V>, java.io.Serializable]
+ PsiFieldStub[serialVersionUID:long=1599671320688067438L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[sm:java.util.SortedMap<K,V>]
+ PsiModifierListStub[mask=18]
+ PsiMethodStub[cons CheckedSortedMap:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.SortedMap<K,V>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<K>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p3:java.lang.Class<V>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[comparator:java.util.Comparator<? super K>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[firstKey:K]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[lastKey:K]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[subMap:java.util.SortedMap<K,V>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:K]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:K]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[headMap:java.util.SortedMap<K,V>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:K]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[tailMap:java.util.SortedMap<K,V>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:K]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=CheckedSortedSet fqn=java.util.Collections.CheckedSortedSet]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.CheckedSet<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.SortedSet<E>, java.io.Serializable]
+ PsiFieldStub[serialVersionUID:long=1599911165492914959L]
+ PsiModifierListStub[mask=26]
+ PsiFieldStub[ss:java.util.SortedSet<E>]
+ PsiModifierListStub[mask=18]
+ PsiMethodStub[cons CheckedSortedSet:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.SortedSet<E>]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:java.lang.Class<E>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[comparator:java.util.Comparator<? super E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[first:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[last:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[subSet:java.util.SortedSet<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[headSet:java.util.SortedSet<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[tailSet:java.util.SortedSet<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiClassStub[name=CopiesList fqn=java.util.Collections.CopiesList]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
@@ -12,11 +916,11 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_LIST:java.util.AbstractList<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.RandomAccess, java.io.Serializable]
PsiFieldStub[serialVersionUID:long=2739099268398711800L]
- PsiModifierListStub[mask=4120]
+ PsiModifierListStub[mask=26]
PsiFieldStub[n:int]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiFieldStub[element:E]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons CopiesList:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -38,6 +942,20 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:java.lang.Object]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[indexOf:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[lastIndexOf:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[get:E]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
@@ -45,10 +963,88 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:int]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[subList:java.util.List<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:int]
+ PsiModifierListStub[mask=0]
+ PsiParameterStub[p2:int]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=EmptyEnumeration fqn=java.util.Collections.EmptyEnumeration]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Enumeration<E>]
+ PsiFieldStub[EMPTY_ENUMERATION:java.util.Collections.EmptyEnumeration<java.lang.Object>]
+ PsiModifierListStub[mask=4120]
+ PsiMethodStub[cons EmptyEnumeration:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hasMoreElements:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[nextElement:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=EmptyIterator fqn=java.util.Collections.EmptyIterator]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Iterator<E>]
+ PsiFieldStub[EMPTY_ITERATOR:java.util.Collections.EmptyIterator<java.lang.Object>]
+ PsiModifierListStub[mask=4120]
+ PsiMethodStub[cons EmptyIterator:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hasNext:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[next:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiClassStub[name=EmptyList fqn=java.util.Collections.EmptyList]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
- PsiRefListStub[EXTENDS_LIST:java.util.AbstractList<java.lang.Object>]
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.AbstractList<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.RandomAccess, java.io.Serializable]
PsiFieldStub[serialVersionUID:long=8842843931221139166L]
PsiModifierListStub[mask=26]
@@ -57,11 +1053,26 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[listIterator:java.util.ListIterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[size:int]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[contains:boolean]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
@@ -69,22 +1080,107 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:java.lang.Object]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[get:java.lang.Object]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[get:E]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
PsiParameterStub[p1:int]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[readResolve:java.lang.Object]
PsiModifierListStub[mask=2]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiClassStub[name=EmptyListIterator fqn=java.util.Collections.EmptyListIterator]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.Collections.EmptyIterator<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.ListIterator<E>]
+ PsiFieldStub[EMPTY_ITERATOR:java.util.Collections.EmptyListIterator<java.lang.Object>]
+ PsiModifierListStub[mask=4120]
+ PsiMethodStub[cons EmptyListIterator:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hasPrevious:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[previous:E]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[nextIndex:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[previousIndex:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[set:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiClassStub[name=EmptyMap fqn=java.util.Collections.EmptyMap]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
- PsiRefListStub[EXTENDS_LIST:java.util.AbstractMap<java.lang.Object,java.lang.Object>]
+ PsiTypeParameter[K]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiTypeParameter[V]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.AbstractMap<K,V>]
PsiRefListStub[IMPLEMENTS_LIST:java.io.Serializable]
PsiFieldStub[serialVersionUID:long=6428348081105594320L]
PsiModifierListStub[mask=26]
@@ -117,24 +1213,24 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:java.lang.Object]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[get:java.lang.Object]
+ PsiMethodStub[get:V]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
PsiParameterStub[p1:java.lang.Object]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[keySet:java.util.Set<java.lang.Object>]
+ PsiMethodStub[keySet:java.util.Set<K>]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[values:java.util.Collection<java.lang.Object>]
+ PsiMethodStub[values:java.util.Collection<V>]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[entrySet:java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>>]
+ PsiMethodStub[entrySet:java.util.Set<java.util.Map.Entry<K,V>>]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
@@ -159,7 +1255,9 @@ PsiJavaFileStub [java.util]
PsiClassStub[name=EmptySet fqn=java.util.Collections.EmptySet]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
- PsiRefListStub[EXTENDS_LIST:java.util.AbstractSet<java.lang.Object>]
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.AbstractSet<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.io.Serializable]
PsiFieldStub[serialVersionUID:long=1582296315990362920L]
PsiModifierListStub[mask=26]
@@ -168,7 +1266,7 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[iterator:java.util.Iterator<java.lang.Object>]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
PsiParameterListStub
@@ -178,6 +1276,11 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[contains:boolean]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
@@ -185,6 +1288,27 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:java.lang.Object]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[readResolve:java.lang.Object]
PsiModifierListStub[mask=2]
PsiTypeParameterListStub
@@ -193,12 +1317,12 @@ PsiJavaFileStub [java.util]
PsiClassStub[name=ReverseComparator fqn=java.util.Collections.ReverseComparator]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
- PsiTypeParameter[T]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:]
PsiRefListStub[EXTENDS_LIST:]
PsiRefListStub[IMPLEMENTS_LIST:java.util.Comparator<java.lang.Comparable<java.lang.Object>>, java.io.Serializable]
PsiFieldStub[serialVersionUID:long=7207038068494060240L]
PsiModifierListStub[mask=26]
+ PsiFieldStub[REVERSE_ORDER:java.util.Collections.ReverseComparator]
+ PsiModifierListStub[mask=4120]
PsiMethodStub[cons ReverseComparator:void]
PsiModifierListStub[mask=2]
PsiTypeParameterListStub
@@ -213,6 +1337,11 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p2:java.lang.Comparable<java.lang.Object>]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[readResolve:java.lang.Object]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiClassStub[name=ReverseComparator2 fqn=java.util.Collections.ReverseComparator2]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
@@ -223,7 +1352,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=4374092139857L]
PsiModifierListStub[mask=26]
PsiFieldStub[cmp:java.util.Comparator<T>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons ReverseComparator2:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -240,11 +1369,143 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p2:T]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiClassStub[interface name=SelfComparable fqn=java.util.Collections.SelfComparable]
PsiModifierListStub[mask=1034]
PsiTypeParameterListStub
PsiRefListStub[EXTENDS_LIST:java.lang.Comparable<java.util.Collections.SelfComparable>]
PsiRefListStub[IMPLEMENTS_LIST:]
+ PsiClassStub[name=SetFromMap fqn=java.util.Collections.SetFromMap]
+ PsiModifierListStub[mask=10]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiRefListStub[EXTENDS_LIST:java.util.AbstractSet<E>]
+ PsiRefListStub[IMPLEMENTS_LIST:java.util.Set<E>, java.io.Serializable]
+ PsiFieldStub[m:java.util.Map<E,java.lang.Boolean>]
+ PsiModifierListStub[mask=18]
+ PsiFieldStub[s:java.util.Set<E>]
+ PsiModifierListStub[mask=130]
+ PsiFieldStub[serialVersionUID:long=2454657854757543876L]
+ PsiModifierListStub[mask=26]
+ PsiMethodStub[cons SetFromMap:void]
+ PsiModifierListStub[mask=4096]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map<E,java.lang.Boolean>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[clear:void]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[size:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[isEmpty:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[contains:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[remove:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[add:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:java.lang.Object[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toArray:T[]]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:T[]]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[toString:java.lang.String]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[hashCode:int]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[equals:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Object]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[containsAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[removeAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[retainAll:boolean]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Collection<?>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[readObject:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.io.ObjectInputStream]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:java.io.IOException, java.lang.ClassNotFoundException]
PsiClassStub[name=SingletonList fqn=java.util.Collections.SingletonList]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
@@ -253,7 +1514,7 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_LIST:java.util.AbstractList<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.RandomAccess, java.io.Serializable]
PsiFieldStub[serialVersionUID:long=3093736618740652951L]
- PsiModifierListStub[mask=4120]
+ PsiModifierListStub[mask=26]
PsiFieldStub[element:E]
PsiModifierListStub[mask=18]
PsiMethodStub[cons SingletonList:void]
@@ -263,6 +1524,11 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:E]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[iterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=1]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[size:int]
PsiModifierListStub[mask=1]
PsiTypeParameterListStub
@@ -291,62 +1557,6 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_BOUNDS_LIST:]
PsiRefListStub[EXTENDS_LIST:java.util.AbstractMap<K,V>]
PsiRefListStub[IMPLEMENTS_LIST:java.io.Serializable]
- PsiClassStub[name=ImmutableEntry fqn=java.util.Collections.SingletonMap.ImmutableEntry]
- PsiModifierListStub[mask=10]
- PsiTypeParameterListStub
- PsiTypeParameter[K]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:]
- PsiTypeParameter[V]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:]
- PsiRefListStub[EXTENDS_LIST:]
- PsiRefListStub[IMPLEMENTS_LIST:java.util.Map.Entry<K,V>]
- PsiFieldStub[k:K]
- PsiModifierListStub[mask=4112]
- PsiFieldStub[v:V]
- PsiModifierListStub[mask=4112]
- PsiMethodStub[cons ImmutableEntry:void]
- PsiModifierListStub[mask=4096]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiParameterStub[p1:K]
- PsiModifierListStub[mask=0]
- PsiParameterStub[p2:V]
- PsiModifierListStub[mask=0]
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[getKey:K]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[getValue:V]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[setValue:V]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiParameterStub[p1:V]
- PsiModifierListStub[mask=0]
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[equals:boolean]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiParameterStub[p1:java.lang.Object]
- PsiModifierListStub[mask=0]
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[hashCode:int]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiRefListStub[THROWS_LIST:]
- PsiMethodStub[toString:java.lang.String]
- PsiModifierListStub[mask=1]
- PsiTypeParameterListStub
- PsiParameterListStub
- PsiRefListStub[THROWS_LIST:]
PsiFieldStub[serialVersionUID:long=-6979724477215052911L]
PsiModifierListStub[mask=26]
PsiFieldStub[k:K]
@@ -459,9 +1669,9 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=3053995032091335093L]
PsiModifierListStub[mask=26]
PsiFieldStub[c:java.util.Collection<E>]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiFieldStub[mutex:java.lang.Object]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons SynchronizedCollection:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -566,6 +1776,13 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[writeObject:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.io.ObjectOutputStream]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:java.io.IOException]
PsiClassStub[name=SynchronizedList fqn=java.util.Collections.SynchronizedList]
PsiModifierListStub[mask=4104]
PsiTypeParameterListStub
@@ -574,9 +1791,9 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_LIST:java.util.Collections.SynchronizedCollection<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.List<E>]
PsiFieldStub[serialVersionUID:long=-7754090372962971524L]
- PsiModifierListStub[mask=4120]
+ PsiModifierListStub[mask=26]
PsiFieldStub[list:java.util.List<E>]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons SynchronizedList:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -698,9 +1915,9 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=1978198479659022715L]
PsiModifierListStub[mask=26]
PsiFieldStub[m:java.util.Map<K,V>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=18]
PsiFieldStub[mutex:java.lang.Object]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiFieldStub[keySet:java.util.Set<K>]
PsiModifierListStub[mask=130]
PsiFieldStub[entrySet:java.util.Set<java.util.Map.Entry<K,V>>]
@@ -814,6 +2031,13 @@ PsiJavaFileStub [java.util]
PsiTypeParameterListStub
PsiParameterListStub
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[writeObject:void]
+ PsiModifierListStub[mask=2]
+ PsiTypeParameterListStub
+ PsiParameterListStub
+ PsiParameterStub[p1:java.io.ObjectOutputStream]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:java.io.IOException]
PsiClassStub[name=SynchronizedRandomAccessList fqn=java.util.Collections.SynchronizedRandomAccessList]
PsiModifierListStub[mask=4104]
PsiTypeParameterListStub
@@ -822,7 +2046,7 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_LIST:java.util.Collections.SynchronizedList<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.RandomAccess]
PsiFieldStub[serialVersionUID:long=1530674583602358482L]
- PsiModifierListStub[mask=4120]
+ PsiModifierListStub[mask=26]
PsiMethodStub[cons SynchronizedRandomAccessList:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -902,7 +2126,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=-8798146769416483793L]
PsiModifierListStub[mask=26]
PsiFieldStub[sm:java.util.SortedMap<K,V>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=18]
PsiMethodStub[cons SynchronizedSortedMap:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -967,7 +2191,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=8695801310862127406L]
PsiModifierListStub[mask=26]
PsiFieldStub[ss:java.util.SortedSet<E>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=18]
PsiMethodStub[cons SynchronizedSortedSet:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -1032,7 +2256,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=1820017752578914078L]
PsiModifierListStub[mask=26]
PsiFieldStub[c:java.util.Collection<? extends E>]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons UnmodifiableCollection:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -1136,9 +2360,9 @@ PsiJavaFileStub [java.util]
PsiRefListStub[EXTENDS_LIST:java.util.Collections.UnmodifiableCollection<E>]
PsiRefListStub[IMPLEMENTS_LIST:java.util.List<E>]
PsiFieldStub[serialVersionUID:long=-283967356065247728L]
- PsiModifierListStub[mask=4120]
+ PsiModifierListStub[mask=26]
PsiFieldStub[list:java.util.List<? extends E>]
- PsiModifierListStub[mask=4096]
+ PsiModifierListStub[mask=4112]
PsiMethodStub[cons UnmodifiableList:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -1536,7 +2760,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=-8806743815996713206L]
PsiModifierListStub[mask=26]
PsiFieldStub[sm:java.util.SortedMap<K,? extends V>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=18]
PsiMethodStub[cons UnmodifiableSortedMap:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -1592,7 +2816,7 @@ PsiJavaFileStub [java.util]
PsiFieldStub[serialVersionUID:long=-4929149591599911165L]
PsiModifierListStub[mask=26]
PsiFieldStub[ss:java.util.SortedSet<E>]
- PsiModifierListStub[mask=2]
+ PsiModifierListStub[mask=18]
PsiMethodStub[cons UnmodifiableSortedSet:void]
PsiModifierListStub[mask=4096]
PsiTypeParameterListStub
@@ -1662,8 +2886,6 @@ PsiJavaFileStub [java.util]
PsiModifierListStub[mask=25]
PsiFieldStub[EMPTY_MAP:java.util.Map]
PsiModifierListStub[mask=25]
- PsiFieldStub[REVERSE_ORDER:java.util.Comparator]
- PsiModifierListStub[mask=26]
PsiMethodStub[cons Collections:void]
PsiModifierListStub[mask=2]
PsiTypeParameterListStub
@@ -1693,9 +2915,9 @@ PsiJavaFileStub [java.util]
PsiModifierListStub[mask=9]
PsiTypeParameterListStub
PsiTypeParameter[T]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
PsiParameterListStub
- PsiParameterStub[p1:java.util.List<? extends T>]
+ PsiParameterStub[p1:java.util.List<? extends java.lang.Comparable<? super T>>]
PsiModifierListStub[mask=0]
PsiParameterStub[p2:T]
PsiModifierListStub[mask=0]
@@ -1704,9 +2926,9 @@ PsiJavaFileStub [java.util]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
PsiTypeParameter[T]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
PsiParameterListStub
- PsiParameterStub[p1:java.util.List<? extends T>]
+ PsiParameterStub[p1:java.util.List<? extends java.lang.Comparable<? super T>>]
PsiModifierListStub[mask=0]
PsiParameterStub[p2:T]
PsiModifierListStub[mask=0]
@@ -1715,9 +2937,9 @@ PsiJavaFileStub [java.util]
PsiModifierListStub[mask=10]
PsiTypeParameterListStub
PsiTypeParameter[T]
- PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
PsiParameterListStub
- PsiParameterStub[p1:java.util.List<? extends T>]
+ PsiParameterStub[p1:java.util.List<? extends java.lang.Comparable<? super T>>]
PsiModifierListStub[mask=0]
PsiParameterStub[p2:T]
PsiModifierListStub[mask=0]
@@ -2099,6 +3321,15 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p2:java.lang.Class<E>]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[zeroLengthArray:T[]]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:java.lang.Class<T>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[checkedSet:java.util.Set<E>]
PsiModifierListStub[mask=9]
PsiTypeParameterListStub
@@ -2162,6 +3393,27 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p3:java.lang.Class<V>]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[emptyIterator:java.util.Iterator<T>]
+ PsiModifierListStub[mask=9]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[emptyListIterator:java.util.ListIterator<T>]
+ PsiModifierListStub[mask=9]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[emptyEnumeration:java.util.Enumeration<T>]
+ PsiModifierListStub[mask=9]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[emptySet:java.util.Set<T>]
PsiModifierListStub[mask=25]
PsiTypeParameterListStub
@@ -2194,6 +3446,15 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p1:T]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[singletonIterator:java.util.Iterator<E>]
+ PsiModifierListStub[mask=4104]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:E]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
PsiMethodStub[singletonList:java.util.List<T>]
PsiModifierListStub[mask=9]
PsiTypeParameterListStub
@@ -2262,7 +3523,7 @@ PsiJavaFileStub [java.util]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
PsiMethodStub[eq:boolean]
- PsiModifierListStub[mask=10]
+ PsiModifierListStub[mask=4104]
PsiTypeParameterListStub
PsiParameterListStub
PsiParameterStub[p1:java.lang.Object]
@@ -2290,6 +3551,7 @@ PsiJavaFileStub [java.util]
PsiRefListStub[THROWS_LIST:]
PsiMethodStub[varargs addAll:boolean]
PsiModifierListStub[mask=9]
+ PsiAnnotationStub[@java.lang.SafeVarargs]
PsiTypeParameterListStub
PsiTypeParameter[T]
PsiRefListStub[EXTENDS_BOUNDS_LIST:]
@@ -2299,3 +3561,21 @@ PsiJavaFileStub [java.util]
PsiParameterStub[p2:T...]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[newSetFromMap:java.util.Set<E>]
+ PsiModifierListStub[mask=9]
+ PsiTypeParameterListStub
+ PsiTypeParameter[E]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Map<E,java.lang.Boolean>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
+ PsiMethodStub[asLifoQueue:java.util.Queue<T>]
+ PsiModifierListStub[mask=9]
+ PsiTypeParameterListStub
+ PsiTypeParameter[T]
+ PsiRefListStub[EXTENDS_BOUNDS_LIST:]
+ PsiParameterListStub
+ PsiParameterStub[p1:java.util.Deque<T>]
+ PsiModifierListStub[mask=0]
+ PsiRefListStub[THROWS_LIST:]
diff --git a/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java b/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java
new file mode 100644
index 000000000000..0260f08423c1
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java
@@ -0,0 +1,13 @@
+class Test {
+ public boolean isConsideredFinal(int cl) {
+ return haveSeenAllExp<caret>ectedAtCl(cl);
+ }
+
+ private boolean haveSeenAllExpectedAtCl(int cl) {
+ return cl == cl();
+ }
+
+ int cl() {
+ return 0;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java.after b/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java.after
new file mode 100644
index 000000000000..a7ff12c6344d
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/SameVarMethodNames.java.after
@@ -0,0 +1,9 @@
+class Test {
+ public boolean isConsideredFinal(int cl) {
+ return cl == cl();
+ }
+
+ int cl() {
+ return 0;
+ }
+} \ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/after/Outer.java b/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/after/Outer.java
new file mode 100644
index 000000000000..aafb683292a0
--- /dev/null
+++ b/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/after/Outer.java
@@ -0,0 +1,10 @@
+class Outer {
+ static void foo() {}
+
+ static class Inner {
+ }
+
+ {
+ Runnable r = Outer::foo;
+ }
+}
diff --git a/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/before/Outer.java b/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/before/Outer.java
new file mode 100644
index 000000000000..ae82c7498fff
--- /dev/null
+++ b/java/java-tests/testData/refactoring/moveMembers/fromNestedToOuterMethodRef/before/Outer.java
@@ -0,0 +1,9 @@
+class Outer {
+ static class Inner {
+ static void foo() {}
+ }
+
+ {
+ Runnable r = Inner::foo;
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
index 45a3f818df3f..5d0bcd4eaa8c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy
@@ -26,6 +26,8 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
+import org.jetbrains.annotations.NotNull
+
/**
* @author peter
*/
@@ -94,7 +96,7 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
static class CacheVerifyingContributor extends CompletionContributor {
@Override
- void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(parameters.position, PsiClass)
for (ci in OverrideImplementExploreUtil.getMethodsToOverrideImplement(psiClass, true)) {
assert ci.element.valid
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index a5397a2de68b..8a54c9594144 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -47,7 +47,9 @@ import com.intellij.openapi.extensions.LoadingOrder
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.progress.ProgressManager
+import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.Disposer
+import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.statistics.StatisticsManager
@@ -559,7 +561,7 @@ public interface Test {
static class LongContributor extends CompletionContributor {
@Override
- void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
result.runRemainingContributors(parameters, true)
Thread.sleep 500
}
@@ -892,9 +894,7 @@ class Foo {
void bar(int aaa, int aaaaa) { foo(<caret>) }
} """)
type 'a'
- println myFixture.lookupElementStrings
type 'a'
- println myFixture.lookupElementStrings
type ','
assert myFixture.editor.document.text.contains('foo(aaa, )')
}
@@ -967,7 +967,12 @@ class Foo {
void x__goo() {}
}
'''
- def cls = ((PsiJavaFile)myFixture.file).getClasses()[0]
+ PsiClass cls = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Override
+ public PsiClass compute() {
+ return ((PsiJavaFile)myFixture.file).getClasses()[0];
+ }
+ });
def foo = cls.methods[0]
def goo = cls.methods[2]
type('x')
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java
index 8aa780abbaa2..6eb495d27c26 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaReflectionCompletionTest.java
@@ -64,6 +64,7 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
}
public void testGenerics() throws Exception {
+ myFixture.addFileToProject("a.properties", "foo=bar"); // check that property variants don't override reflection ones
doTest(0, "foo");
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
index c1e6d4182aa5..900555d21ab9 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy
@@ -633,6 +633,19 @@ interface TxANotAnno {}
checkPreferredItems 0, 'fact'
}
+ public void testPreferAnnotationsToInterfaceKeyword() {
+ checkPreferredItems 0, 'Deprecated', 'Override'
+ }
+
+ public void testPreferThrownExceptionsInCatch() {
+ checkPreferredItems 0, 'FileNotFoundException', 'File'
+ }
+
+ public void testHonorFirstLetterCase() {
+ CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE;
+ checkPreferredItems 0, 'posIdMap', 'PImageDecoder', 'PNGImageDecoder'
+ }
+
public void testGlobalStaticMemberStats() {
configureNoCompletion(getTestName(false) + ".java")
myFixture.complete(CompletionType.BASIC, 2)
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
index ba38fd1a45ad..79a94aaa8148 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -792,7 +792,7 @@ public class ListUtils {
public void testDoubleFalse() throws Throwable {
configureByFile(getTestName(false) + ".java");
- assertFirstStringItems("false", "fefefef", "float", "finalize");
+ assertFirstStringItems("fefefef", "false", "float", "finalize");
}
public void testSameNamedVariableInNestedClasses() throws Throwable {
@@ -938,6 +938,13 @@ public class ListUtils {
public void testQualifyInnerMembers() throws Throwable { doTest('\n') }
+ public void testDeepInner() throws Throwable {
+ configure()
+ assert myFixture.lookupElementStrings == ['ClassInner1', 'ClassInner1.ClassInner2']
+ selectItem(lookup.items[1])
+ checkResult()
+ }
+
public void testSuggestExpectedTypeMembers() throws Throwable { doTest('\n') }
public void testSuggestExpectedTypeMembersInCall() throws Throwable { doTest('\n') }
public void testSuggestExpectedTypeMembersInAnno() throws Throwable { doTest('\n') }
@@ -1209,6 +1216,12 @@ class XInternalError {}
public void testConstantInAnno() { doTest() }
+ public void testCharsetName() {
+ myFixture.addClass("package java.nio.charset; public class Charset { public static Charset forName(String s) {} }")
+ configureByTestName()
+ assert myFixture.lookupElementStrings.contains('UTF-8')
+ }
+
public void testInnerClassInExtendsGenerics() {
def text = "package bar; class Foo extends List<Inne<caret>> { public static class Inner {} }"
myFixture.configureFromExistingVirtualFile(myFixture.addClass(text).containingFile.virtualFile)
@@ -1240,7 +1253,7 @@ class XInternalError {}
configure()
def items = myFixture.lookupElements.findAll { it.lookupString == 'String' }
assert items.size() == 1
- assert LookupElementPresentation.renderElement(items[0]).tailText?.contains('java.lang')
+ assert LookupElementPresentation.renderElement(items[0]).tailText == ' (java.lang)'
}
public void testSameSignature() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index 74d2465f43a5..f6be0686d239 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -368,6 +368,9 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA125816() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA57338() { doTest(LanguageLevel.JDK_1_6, JavaSdkVersion.JDK_1_6, false); }
public void testIDEA67600() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
+ public void testIDEA126697() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, true); }
+ public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
+ public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
//jdk should propagate LL 1.4 but actually it provides LL 1.7?!
public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
index 20a5d5139d99..79506280a778 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
@@ -184,6 +184,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
+ public void testRawTypeFromParentArrayType() throws Exception {
+ doTest();
+ }
+
private void doTest() throws Exception {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
index f5e6a651f167..6bd7654b72af 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
@@ -226,6 +226,22 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testIDEA125254() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA124961() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA126109() throws Exception {
+ doTest();
+ }
+
+ public void testIDEA126809() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
index 16af9001cf43..6860bc0c88fa 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java
@@ -261,6 +261,18 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
+ public void testRejectReceiverTypesForConstructorRefs() {
+ doTest();
+ }
+
+ public void testEnumValuesMethod() throws Exception {
+ doTest();
+ }
+
+ public void testMissedApplicableMemberContainingClassSubstitution() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddMethodQualifierTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddMethodQualifierTest.java
new file mode 100644
index 000000000000..48572b2c8068
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddMethodQualifierTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon.quickFix;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.daemon.impl.quickfix.AddMethodQualifierFix;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class AddMethodQualifierTest extends JavaCodeInsightFixtureTestCase {
+
+ @Override
+ protected String getTestDataPath() {
+ return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/";
+ }
+
+ public void testNonStaticMethod() {
+ doTest("fieldElement", "staticElement", "localElement1", "paramElement");
+ }
+
+ public void testStaticMethod() {
+ doTest("staticElement", "localElement1", "paramElement");
+ }
+
+ public void testNestedMethod() {
+ doTest("fieldElement", "localElement1", "nestedField", "nestedParamElement", "staticElement", "paramElement");
+ }
+
+ public void testConstructor() {
+ doTest("fieldElement", "staticElement", "localElement1");
+ }
+
+ public void testStaticInitializer() {
+ doTest("staticElement", "localElement1");
+ }
+
+ public void testFix() {
+ doTestFix();
+ }
+
+ private void doTestFix() {
+ myFixture.configureByFile(getTestName(false) + "Before.java");
+ final AddMethodQualifierFix quickFix = getQuickFix();
+ assertNotNull(quickFix);
+ myFixture.launchAction(quickFix);
+ myFixture.checkResultByFile(getTestName(false) + "After.java");
+ }
+
+ private void doTest(final String... candidatesNames) {
+ myFixture.configureByFile(getTestName(false) + ".java");
+ final AddMethodQualifierFix addMethodQualifierFix = getQuickFix();
+ if (candidatesNames.length == 0) {
+ assertNull(addMethodQualifierFix);
+ return;
+ }
+ assertNotNull(addMethodQualifierFix);
+ final Set<String> actualCandidatesNames = new TreeSet<String>(ContainerUtil.map(addMethodQualifierFix.getCandidates(), new Function<PsiNamedElement, String>() {
+ @Override
+ public String fun(final PsiNamedElement psiNamedElement) {
+ final String name = psiNamedElement.getName();
+ assertNotNull(name);
+ return name;
+ }
+ }));
+ final Set<String> expectedCandidatesNames = new TreeSet<String>(ContainerUtil.list(candidatesNames));
+ assertEquals(expectedCandidatesNames, actualCandidatesNames);
+ }
+
+ @Nullable
+ private AddMethodQualifierFix getQuickFix() {
+ final List<IntentionAction> availableIntentions = myFixture.getAvailableIntentions();
+ AddMethodQualifierFix addMethodQualifierFix = null;
+ for (final IntentionAction availableIntention : availableIntentions) {
+ if (availableIntention instanceof AddMethodQualifierFix) {
+ addMethodQualifierFix = (AddMethodQualifierFix)availableIntention;
+ break;
+ }
+ }
+ return addMethodQualifierFix;
+ }
+
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
index 41d72f7e9a0e..2047f13b795d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.impl.FoldingModelImpl
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiMethod
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.testFramework.LightProjectDescriptor
@@ -592,6 +593,225 @@ class Test {
assert regions[0].placeholderText == '{...}'
}
+ public void "test insert boolean literal argument name"() {
+ def text = """class Groo {
+
+ public void test() {
+ boolean testNow = System.currentTimeMillis() > 34000;
+ int times = 1;
+ float pi = 4;
+ String title = "Testing..."
+ char ch = 'q'
+ File file;
+
+ configure(true, false, 555, 3.141f, "Huge Title", 'c', null);
+ configure(testNow, shouldIgnoreRoots(), fourteen, pi, title, c, file);
+ }
+
+ pubic void configure(boolean testNow, boolean shouldIgnoreRoots, int times, float pi, String title, char terminate, File file) {
+ System.out.println();
+ System.out.println();
+ }
+
+}"""
+ configure text
+ PsiClass fooClass = JavaPsiFacade.getInstance(project).findClass('Groo', GlobalSearchScope.allScope(project))
+
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.size() == 9
+
+ def literals = fooClass.methods[0].body.statements[6].children[0].children[1].children.findAll { it instanceof PsiLiteralExpression }
+ def parameters = fooClass.methods[1].parameterList.parameters
+
+ for (int i = 0; i < literals.size(); i++) {
+ def currentElement = literals[i]
+ def correspondingFolding = regions[i + 1]
+ assert correspondingFolding.startOffset == currentElement.textRange.startOffset && correspondingFolding.endOffset == currentElement.textRange.endOffset
+ assert correspondingFolding.placeholderText == parameters[i].name + ": " + currentElement.text
+ }
+ }
+
+ public void "test do not inline name if setter"() {
+ def text = """class Groo {
+
+ public void test() {
+ setTestNow(false);
+ System.out.println("");
+ }
+
+ pubic void setTestNow(boolean testNow) {
+ System.out.println("");
+ System.out.println("");
+ }
+
+}"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions
+ assert regions.size() == 2
+ }
+
+ public void "test do not collapse varargs"() {
+ def text = """
+public class VarArgTest {
+
+ public void main() {
+ System.out.println("AAA");
+ testBooleanVarargs(13, false);
+ }
+
+ public boolean testBooleanVarargs(int test, boolean... booleans) {
+ int temp = test;
+ return false;
+ }
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.size() == 3
+ checkRangeOffsetByPositionInText(regions[1], text, "13")
+ assert regions[1].placeholderText == "test: 13"
+ }
+
+ public void "test inline if argument length is one (EA-57555)"() {
+ def text = """
+public class CharSymbol {
+
+ public void main() {
+ System.out.println("AAA");
+ count(1, false);
+ }
+
+ public void count(int test, boolean fast) {
+ int temp = test;
+ boolean isFast = fast;
+ }
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.size() == 4
+
+ checkRangeOffsetByPositionInText(regions[1], text, "1")
+ assert regions[1].placeholderText == "test: 1"
+
+ checkRangeOffsetByPositionInText(regions[2], text, "false")
+ assert regions[2].placeholderText == "fast: false"
+ }
+
+ public void "test inline names if literal expression can be assigned to method parameter"() {
+ def text = """
+public class CharSymbol {
+
+ public void main() {
+ Object obj = new Object();
+ count(100, false, "Hi!");
+ }
+
+ public void count(Integer test, Boolean boo, CharSequence seq) {
+ int a = test;
+ Object obj = new Object();
+ }
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.size() == 5
+
+ checkRangeOffsetByPositionInText(regions[1], text, "100")
+ assert regions[1].placeholderText == "test: 100"
+
+ checkRangeOffsetByPositionInText(regions[2], text, "false")
+ assert regions[2].placeholderText == "boo: false"
+
+ checkRangeOffsetByPositionInText(regions[3], text, '"Hi!"')
+ assert regions[3].placeholderText == 'seq: "Hi!"'
+ }
+
+ public void "test inline negative numbers (IDEA-126753)"() {
+ def text = """
+public class CharSymbol {
+
+ public void main() {
+ Object obj = new Object();
+ count(-1, obj);
+ }
+
+ public void count(int test, Object obj) {
+ Object tmp = obj;
+ boolean isFast = false;
+ }
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.size() == 3
+
+ checkRangeOffsetByPositionInText(regions[1], text, "-1")
+ assert regions[1].placeholderText == "test: -1"
+ }
+
+ public void "test inline constructor literal arguments names"() {
+ def text = """
+public class Test {
+
+ public void main() {
+ System.out.println("AAA");
+ Checker r = new Checker(true, false) {
+ @Override
+ void test() {
+ }
+ };
+ }
+
+ abstract class Checker {
+ Checker(boolean applyToFirst, boolean applyToSecond) {}
+ abstract void test();
+ }
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.length == 6
+
+ assert regions[1].placeholderText == "applyToFirst: true"
+ assert regions[2].placeholderText == "applyToSecond: false"
+
+ checkRangeOffsetByPositionInText(regions[1], text, "true")
+ checkRangeOffsetByPositionInText(regions[2], text, "false")
+ }
+
+ public void "test inline anonymous class constructor literal arguments names"() {
+ def text = """
+public class Test {
+
+ Test(int counter, boolean shouldTest) {
+ System.out.println();
+ System.out.println();
+ }
+
+ public static void main() {
+ System.out.println();
+ Test t = new Test(10, false);
+ }
+
+}
+"""
+ configure text
+ def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
+ assert regions.length == 4
+
+ assert regions[2].placeholderText == "counter: 10"
+ assert regions[3].placeholderText == "shouldTest: false"
+
+ checkRangeOffsetByPositionInText(regions[2], text, "10")
+ checkRangeOffsetByPositionInText(regions[3], text, "false")
+ }
+
+ private static def checkRangeOffsetByPositionInText(FoldRegion region, String text, String foldElement) {
+ assert region.startOffset == text.indexOf(foldElement) && region.endOffset == text.indexOf(foldElement) + foldElement.length()
+ }
+
+
private def changeFoldRegions(Closure op) {
myFixture.editor.foldingModel.runBatchFoldingOperationDoNotCollapseCaret(op)
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SwapIfStatementsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SwapIfStatementsTest.java
new file mode 100644
index 000000000000..a973a9775be0
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SwapIfStatementsTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.intention;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class SwapIfStatementsTest extends LightQuickFixParameterizedTestCase {
+
+ @Override
+ protected String getBasePath() {
+ return "/codeInsight/daemonCodeAnalyzer/quickFix/swapIfStatements";
+ }
+
+ @Override
+ protected boolean shouldBeAvailableAfterExecution() {
+ return true;
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index 6df51f02df15..454bb7f97a58 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -76,6 +76,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
doTestField();
}
+ public void testAnnotations() throws Exception {
+ doTestField();
+ }
+
public void testLiteral() throws Exception {
doTestField();
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
index cc50869bc886..3acb9845df66 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
@@ -461,7 +461,7 @@ class Foo {
}
@Override
- protected void invokeTestRunnable(final Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception {
if (name in ["testNavigationActionsDontTerminateTemplate", "testTemplateWithEnd", "testDisappearingVar", "test escape string characters in soutv"]) {
runnable.run();
return;
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
index ab9a5660b8ad..32982f3687df 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/ContractInferenceFromSourceTest.groovy
@@ -171,6 +171,55 @@ class ContractInferenceFromSourceTest extends LightCodeInsightFixtureTestCase {
assert c == []
}
+ public void "test plain delegation"() {
+ def c = inferContracts("""
+ boolean delegating(Object o) {
+ return smth(o);
+ }
+ boolean smth(Object o) {
+ assert o instanceof String;
+ return true;
+ }
+""")
+ assert c == ['null -> fail']
+ }
+
+ public void "test arg swapping delegation"() {
+ def c = inferContracts("""
+ boolean delegating(Object o, Object o1) {
+ return smth(o1, o);
+ }
+ boolean smth(Object o, Object o1) {
+ return o == null && o1 != null;
+ }
+""")
+ assert c == ['_, !null -> false', 'null, null -> false', '!null, null -> true']
+ }
+
+ public void "test negating delegation"() {
+ def c = inferContracts("""
+ boolean delegating(Object o) {
+ return !smth(o);
+ }
+ boolean smth(Object o) {
+ return o == null;
+ }
+""")
+ assert c == ['null -> false', '!null -> true']
+ }
+
+ public void "test delegation with constant"() {
+ def c = inferContracts("""
+ boolean delegating(Object o) {
+ return smth(null);
+ }
+ boolean smth(Object o) {
+ return o == null;
+ }
+""")
+ assert c == ['_ -> true']
+ }
+
private String inferContract(String method) {
return assertOneElement(inferContracts(method))
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index 67987b3ab8eb..833b5196d74a 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -71,6 +71,9 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testGeneratedEquals() throws Throwable { doTest(); }
public void testIDEA84489() throws Throwable { doTest(); }
+ public void testComparingNullToNotNull() { doTest(); }
+ public void testComparingNullableToNullable() { doTest(); }
+ public void testComparingNullableToUnknown() { doTest(); }
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
public void testComparingToNullableShouldNotAffectNullity() throws Throwable { doTest(); }
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
@@ -235,6 +238,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testManySequentialInstanceofsNotComplex() { doTest(); }
public void testLongDisjunctionsNotComplex() { doTest(); }
public void testWhileNotComplex() { doTest(); }
+ public void testAssertTrueNotComplex() { doTest(); }
public void testManyDisjunctiveFieldAssignmentsInLoopNotComplex() { doTest(); }
public void testManyContinuesNotComplex() { doTest(); }
public void testFinallyNotComplex() { doTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java
new file mode 100644
index 000000000000..a1f81da5773b
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
+ */
+
+/*
+ * User: anna
+ * Date: 14-Jan-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.actions.ViewOfflineResultsAction;
+import com.intellij.codeInspection.defUse.DefUseInspection;
+import com.intellij.codeInspection.defUse.DefUseInspectionBase;
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.ex.ToolsImpl;
+import com.intellij.codeInspection.offline.OfflineProblemDescriptor;
+import com.intellij.codeInspection.offlineViewer.OfflineViewParseUtil;
+import com.intellij.codeInspection.ui.InspectionResultsView;
+import com.intellij.codeInspection.ui.InspectionTree;
+import com.intellij.codeInspection.ui.InspectionTreeNode;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.TestSourceBasedTestCase;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class OfflineIRVTest extends TestSourceBasedTestCase {
+ private InspectionResultsView myView;
+ private LocalInspectionToolWrapper myToolWrapper;
+
+ private static String varMessage(String name) {
+ return InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "'"+name+"'");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ HighlightDisplayKey.register(DefUseInspectionBase.SHORT_NAME);
+ myToolWrapper = new LocalInspectionToolWrapper(new DefUseInspection());
+ myView = ViewOfflineResultsAction.showOfflineView(getProject(), parse(), new InspectionProfileImpl("test") {
+ @Override
+ public boolean isToolEnabled(final HighlightDisplayKey key, PsiElement element) {
+ return Comparing.strEqual(key.toString(), DefUseInspectionBase.SHORT_NAME);
+ }
+
+ @Override
+ @NotNull
+ public InspectionToolWrapper[] getInspectionTools(PsiElement element) {
+ return new InspectionToolWrapper[]{myToolWrapper};
+ }
+
+ @Override
+ @NotNull
+ public ModifiableModel getModifiableModel() {
+ return new InspectionProfileImpl("test") {
+ @Override
+ @NotNull
+ public InspectionToolWrapper[] getInspectionTools(PsiElement element) {
+ return new InspectionToolWrapper[]{myToolWrapper};
+ }
+
+ @Override
+ public boolean isToolEnabled(final HighlightDisplayKey key, PsiElement element) {
+ return Comparing.strEqual(key.toString(), DefUseInspectionBase.SHORT_NAME);
+ }
+ };
+ }
+ }, null);
+ myView.getGlobalInspectionContext().getTools().put(
+ myToolWrapper.getShortName(), new ToolsImpl(myToolWrapper, myToolWrapper.getDefaultLevel(), true));
+ myToolWrapper.initialize(myView.getGlobalInspectionContext());
+ }
+
+ private Map<String, Map<String, Set<OfflineProblemDescriptor>>> parse() throws IOException {
+ final String moduleName = getModule().getName();
+ final Map<String, Map<String, Set<OfflineProblemDescriptor>>> map = new HashMap<String, Map<String, Set<OfflineProblemDescriptor>>>();
+ final File res = new File(PathManagerEx.getTestDataPath(), getTestPath() + File.separator + "res");
+ final File[] files = res.listFiles();
+ assert files != null;
+ for (File file : files) {
+ final String name = file.getName();
+ final String problems = FileUtil.loadFile(file);
+ final Map<String, Set<OfflineProblemDescriptor>> descriptors = OfflineViewParseUtil.parse(problems);
+ for (Set<OfflineProblemDescriptor> problemDescriptors : descriptors.values()) {
+ for (OfflineProblemDescriptor descriptor : problemDescriptors) {
+ descriptor.setModule(moduleName);
+ }
+ }
+ map.put(name.substring(0, name.lastIndexOf('.')), descriptors);
+ }
+ return map;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Disposer.dispose(myView);
+ myView = null;
+ myToolWrapper = null;
+ super.tearDown();
+ }
+
+ public void testOfflineView() throws Exception {
+ myView.getGlobalInspectionContext().getUIOptions().SHOW_STRUCTURE = true;
+ InspectionTree tree = updateTree();
+ TreeUtil.expandAll(tree);
+ PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n"
+ + " -Probable bugs\n"
+ + " -" + myToolWrapper + "\n"
+ + " -" + getModule().toString() + "\n"
+ + " -<default>\n"
+ + " -Test\n"
+ + " -foo()\n"
+ + " " + varMessage("j") + "\n"
+ + " -main(String[])\n"
+ + " " + varMessage("test") + "\n"
+ + " -f()\n"
+ + " -D\n"
+ + " -b()\n"
+ + " " + varMessage("r") + "\n"
+ + " -anonymous (java.lang.Runnable)\n"
+ + " -run()\n"
+ + " " + varMessage("i") + "\n"
+ + " -ff()\n"
+ + " " + varMessage("d") + "\n"
+ + " " + varMessage("a") + "\n");
+ myView.getGlobalInspectionContext().getUIOptions().SHOW_STRUCTURE = false;
+ tree = updateTree();
+ PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n"
+ + " -Probable bugs\n"
+ + " -" + myToolWrapper + "\n"
+ + " -Test\n"
+ + " " + varMessage("j") + "\n"
+ + " " + varMessage("test") + "\n"
+ + " " + varMessage("r") + "\n"
+ + " " + varMessage("i") + "\n"
+ + " " + varMessage("d") + "\n"
+ + " " + varMessage("a") + "\n");
+ TreeUtil.selectFirstNode(tree);
+ final InspectionTreeNode root = (InspectionTreeNode)tree.getLastSelectedPathComponent();
+ root.ignoreElement();
+ TreeUtil.traverse(root, new TreeUtil.Traverse() {
+ @Override
+ public boolean accept(final Object node) {
+ assertTrue(((InspectionTreeNode)node).isResolved());
+ return true;
+ }
+ });
+ myView.getGlobalInspectionContext().getUIOptions().FILTER_RESOLVED_ITEMS = true;
+ tree = updateTree();
+ PlatformTestUtil.assertTreeEqual(tree, getProject() + "\n");
+ myView.getGlobalInspectionContext().getUIOptions().FILTER_RESOLVED_ITEMS = false;
+ tree = updateTree();
+ PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n"
+ + " -Probable bugs\n"
+ + " -" + myToolWrapper + "\n"
+ + " -Test\n"
+ + " " + varMessage("j") + "\n"
+ + " " + varMessage("test") + "\n"
+ + " " + varMessage("r") + "\n"
+ + " " + varMessage("i") + "\n"
+ + " " + varMessage("d") + "\n"
+ + " " + varMessage("a") + "\n");
+ }
+
+ private InspectionTree updateTree() {
+ myView.update();
+ final InspectionTree tree = myView.getTree();
+ TreeUtil.expandAll(tree);
+ return tree;
+ }
+
+ @Override
+ protected String getTestPath() {
+ return "inspection/offline";
+ }
+
+ @Override
+ protected String getTestDirectoryName() {
+ return "project";
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java
index 4dd29648e055..a8b27ab21089 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast15Test.java
@@ -49,6 +49,7 @@ public class RedundantCast15Test extends InspectionTestCase {
public void testGetClassProcessing() throws Exception { doTest();}
public void testInstanceOfChecks() throws Exception { doTest();}
public void testForEachValue() throws Exception { doTest();}
+ public void testForEachValueIDEA126166() throws Exception { doTest();}
public void testCaseThrowable() throws Exception { doTest();}
public void testSafeTempVarName() throws Exception { doTest();}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java
index 0a0c5396c6c9..6cb52914fe84 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantCast18Test.java
@@ -18,7 +18,6 @@ package com.intellij.codeInspection;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.redundantCast.RedundantCastInspection;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
@@ -33,6 +32,7 @@ public class RedundantCast18Test extends InspectionTestCase {
public void testLambdaContext() throws Exception { doTest(); }
public void testMethodRefContext() throws Exception { doTest(); }
public void testExpectedSupertype() throws Exception { doTest(); }
+ public void testForeachValue() throws Exception { doTest(); }
@Override
protected Sdk getTestProjectSdk() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/SuspiciousCollectionMethodCalls14Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/SuspiciousCollectionMethodCalls14Test.java
new file mode 100644
index 000000000000..2d30216395ac
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/SuspiciousCollectionMethodCalls14Test.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspection;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+
+public class SuspiciousCollectionMethodCalls14Test extends LightCodeInsightFixtureTestCase {
+ private final SuspiciousCollectionsMethodCallsInspection myTool = new SuspiciousCollectionsMethodCallsInspection();
+
+ @Override
+ protected String getBasePath() {
+ return JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/suspiciousCalls";
+ }
+
+ private void doTest() throws Exception {
+ myFixture.enableInspections(myTool);
+ myFixture.testHighlighting(getTestName(false) + ".java");
+ }
+
+ public void testRemoveAll14() throws Exception { doTest(); }
+
+ @NotNull
+ @Override
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return JAVA_1_4;
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenterTest.java b/java/java-tests/testSrc/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenterTest.java
index ef4b5ea42d8c..498a1172fa9a 100644
--- a/java/java-tests/testSrc/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenterTest.java
+++ b/java/java-tests/testSrc/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenterTest.java
@@ -27,8 +27,8 @@ import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassWriter;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
import java.io.File;
import java.io.IOException;
diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
index 86d79fb41e10..92caad03d8ef 100644
--- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
+++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java
@@ -53,9 +53,11 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.WaitFor;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -284,6 +286,26 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
assertSize(2, findUsages(findModel));
}
+ public void testFindInOpenedFilesIncludesNoneProjectButOpenedFile() throws IOException {
+ File dir = createTempDirectory();
+ File file = new File(dir.getPath(), "A.test1234");
+ file.createNewFile();
+ FileUtil.writeToFile(file, "foo fo foo");
+ VirtualFile nonProjectFile = VfsUtil.findFileByIoFile(file, true);
+ assertNotNull(nonProjectFile);
+
+ FindModel findModel = new FindModel();
+ findModel.setStringToFind("fo");
+ findModel.setWholeWordsOnly(true);
+ findModel.setFromCursor(false);
+ findModel.setGlobal(true);
+ findModel.setMultipleFiles(true);
+ findModel.setCustomScope(true);
+ findModel.setCustomScope(new GlobalSearchScope.FilesScope(myProject, ContainerUtil.list(nonProjectFile)));
+
+ assertSize(1, findUsages(findModel));
+ }
+
public void testWholeWordsInNonIndexedFiles() throws Exception {
createFile(myModule, "A.test123", "foo fo foo");
diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
index fad8e4fd94e9..dabe06ba79fa 100644
--- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy
@@ -1,17 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.navigation
-import com.intellij.ide.util.gotoByName.ChooseByNameBase
-import com.intellij.ide.util.gotoByName.ChooseByNameModel
-import com.intellij.ide.util.gotoByName.ChooseByNamePopup
-import com.intellij.ide.util.gotoByName.GotoClassModel2
-import com.intellij.ide.util.gotoByName.GotoFileModel
-import com.intellij.ide.util.gotoByName.GotoSymbolModel2
+import com.intellij.ide.util.gotoByName.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.util.Disposer
import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.Consumer
import com.intellij.util.concurrency.Semaphore
+import org.jetbrains.annotations.NotNull
+
/**
* @author peter
*/
@@ -135,24 +148,32 @@ class Intf {
}
public void "test goto file can go to dir"() {
- def fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
- def barIndex = myFixture.addFileToProject("bar.txt/bar.txt", "foo")
+ PsiFile fooIndex = myFixture.addFileToProject("foo/index.html", "foo")
+ PsiFile barIndex = myFixture.addFileToProject("bar.txt/bar.txt", "foo")
def popup = createPopup(new GotoFileModel(project), fooIndex)
- assert calcPopupElements(popup, "foo/") == [fooIndex.containingDirectory]
- assert calcPopupElements(popup, "foo\\") == [fooIndex.containingDirectory]
- assert calcPopupElements(popup, "/foo") == [fooIndex.containingDirectory]
- assert calcPopupElements(popup, "\\foo") == [fooIndex.containingDirectory]
+
+ def fooDir
+ def barDir
+ edt {
+ fooDir = fooIndex.containingDirectory
+ barDir = barIndex.containingDirectory
+ }
+
+ assert calcPopupElements(popup, "foo/") == [fooDir]
+ assert calcPopupElements(popup, "foo\\") == [fooDir]
+ assert calcPopupElements(popup, "/foo") == [fooDir]
+ assert calcPopupElements(popup, "\\foo") == [fooDir]
assert calcPopupElements(popup, "foo") == []
assert calcPopupElements(popup, "/index.html") == [fooIndex]
assert calcPopupElements(popup, "\\index.html") == [fooIndex]
assert calcPopupElements(popup, "index.html/") == [fooIndex]
assert calcPopupElements(popup, "index.html\\") == [fooIndex]
- assert calcPopupElements(popup, "bar.txt/") == [barIndex.containingDirectory]
- assert calcPopupElements(popup, "bar.txt\\") == [barIndex.containingDirectory]
- assert calcPopupElements(popup, "/bar.txt") == [barIndex.containingDirectory]
- assert calcPopupElements(popup, "\\bar.txt") == [barIndex.containingDirectory]
+ assert calcPopupElements(popup, "bar.txt/") == [barDir]
+ assert calcPopupElements(popup, "bar.txt\\") == [barDir]
+ assert calcPopupElements(popup, "/bar.txt") == [barDir]
+ assert calcPopupElements(popup, "\\bar.txt") == [barDir]
assert calcPopupElements(popup, "bar.txt") == [barIndex]
popup.close(false)
}
@@ -178,7 +199,10 @@ class Intf {
public void "test super method in jdk"() {
def ourRun = myFixture.addClass("package foo.bar; class Goo implements Runnable { public void run() {} }").methods[0]
- def sdkRun = ourRun.containingClass.interfaces[0].methods[0]
+ def sdkRun
+ edt {
+ sdkRun = ourRun.containingClass.interfaces[0].methods[0]
+ }
assert getPopupElements(new GotoSymbolModel2(project), 'run ', true) == [sdkRun]
assert getPopupElements(new GotoSymbolModel2(project), 'run ', false) == [ourRun]
}
@@ -218,7 +242,7 @@ class Intf {
}
@Override
- protected void invokeTestRunnable(Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runnable.run()
}
}
diff --git a/java/java-tests/testSrc/com/intellij/openapi/editor/impl/FoldingExceptionTest.java b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/FoldingExceptionTest.java
index f40a58b16788..b168bc214014 100644
--- a/java/java-tests/testSrc/com/intellij/openapi/editor/impl/FoldingExceptionTest.java
+++ b/java/java-tests/testSrc/com/intellij/openapi/editor/impl/FoldingExceptionTest.java
@@ -15,11 +15,8 @@
*/
package com.intellij.openapi.editor.impl;
-import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.impl.CodeFoldingPassFactory;
-import com.intellij.mock.MockProgressIndicator;
import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
@@ -43,14 +40,7 @@ public class FoldingExceptionTest extends LightCodeInsightTestCase {
}
private static void runFoldingPass() {
- PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(getProject());
- psiDocumentManager.commitAllDocuments();
- PsiFile psiFile = psiDocumentManager.getPsiFile(myEditor.getDocument());
- assertNotNull(psiFile);
-
- CodeFoldingPassFactory factory = getProject().getComponent(CodeFoldingPassFactory.class);
- TextEditorHighlightingPass highlightingPass = factory.createHighlightingPass(psiFile, myEditor);
- highlightingPass.collectInformation(new MockProgressIndicator());
- highlightingPass.doApplyInformationToEditor();
+ PsiDocumentManager.getInstance(ourProject).commitAllDocuments();
+ EditorTestUtil.runTextEditorHighlightingPass(myEditor, CodeFoldingPassFactory.class);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java
deleted file mode 100644
index dd32222cc7a8..000000000000
--- a/java/java-tests/testSrc/com/intellij/psi/ClsDuplicatesTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.psi;
-
-import com.intellij.JavaTestUtil;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.testFramework.PsiTestCase;
-import com.intellij.testFramework.SkipSlowTestLocally;
-import com.intellij.usageView.UsageViewLongNameLocation;
-import gnu.trove.THashSet;
-import gnu.trove.TObjectHashingStrategy;
-
-import java.util.Set;
-
-@SkipSlowTestLocally
-public class ClsDuplicatesTest extends PsiTestCase {
- private Set<PsiNamedElement> myUnique = new THashSet<PsiNamedElement>(new TObjectHashingStrategy<PsiNamedElement>() {
- @Override
- public int computeHashCode(PsiNamedElement object) {
- String name = object.getName();
- return name == null ? 0 : name.hashCode();
- }
-
- @Override
- public boolean equals(PsiNamedElement o1, PsiNamedElement o2) {
- return o1.getParent() == o2.getParent() &&
- o1.getClass() == o2.getClass() &&
- StringUtil.equals(o1.getName(), o2.getName()) &&
- StringUtil.equals(o1.getText(), o2.getText());
- }
- });
-
- @Override
- protected void tearDown() throws Exception {
- myUnique = null;
- super.tearDown();
- }
-
- @Override
- protected Sdk getTestProjectJdk() {
- return JavaTestUtil.getTestJdk();
- }
-
- public void testDuplicates() throws Exception {
- final PsiPackage rootPackage = JavaPsiFacade.getInstance(getProject()).findPackage("");
- assert rootPackage != null;
-
- final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
- JavaRecursiveElementVisitor visitor = new JavaRecursiveElementVisitor() {
- @Override
- public void visitPackage(PsiPackage aPackage) {
- visit(aPackage);
- for (PsiPackage subPackage : aPackage.getSubPackages(scope)) {
- visitPackage(subPackage);
- }
- for (PsiClass aClass : aPackage.getClasses(scope)) {
- visitClass(aClass);
- }
- }
-
- @Override
- public void visitElement(PsiElement element) {
- if (element instanceof PsiNamedElement) {
- visit((PsiNamedElement)element);
- }
- super.visitElement(element);
- }
-
- @Override
- public void visitClass(PsiClass aClass) {
- super.visitClass(aClass);
- PsiElement parent = aClass.getParent();
- if (parent instanceof PsiFile) {
- myUnique.clear();
- }
- }
- };
-
- rootPackage.accept(visitor);
- }
-
- private void visit(PsiNamedElement element) {
- if (!myUnique.add(element)) {
- String description = ElementDescriptionUtil.getElementDescription(element, UsageViewLongNameLocation.INSTANCE);
- fail("Duplicate Element: " + description + ": " + element.getText());
- }
- }
-}
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index b832e65c7675..c88c8c28c102 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -18,15 +18,18 @@ package com.intellij.psi;
import com.intellij.JavaTestUtil;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.JarFileSystem;
-import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.compiled.ClsFileImpl;
+import com.intellij.psi.impl.compiled.InnerClassSourceStrategy;
+import com.intellij.psi.impl.compiled.StubBuildingVisitor;
+import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
import com.intellij.testFramework.LightIdeaTestCase;
import com.intellij.testFramework.PlatformTestUtil;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.IOException;
@@ -75,6 +78,35 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
doTest(clsPath, txtPath);
}
+ public void testStrayInnersFiltering() throws IOException {
+ String path = JavaTestUtil.getJavaTestDataPath() + "/../../mockJDK-1.8/jre/lib/rt.jar!/java/lang/Class.class";
+ VirtualFile file = StandardFileSystems.jar().findFileByPath(path);
+ assertNotNull(path, file);
+
+ InnerClassSourceStrategy<VirtualFile> strategy = new InnerClassSourceStrategy<VirtualFile>() {
+ @Override
+ public VirtualFile findInnerClass(String innerName, VirtualFile outerClass) {
+ String baseName = outerClass.getNameWithoutExtension();
+ VirtualFile child = outerClass.getParent().findChild(baseName + "$" + innerName + ".class");
+ // stray inner classes should be filtered out
+ assert child != null : innerName + " is not an inner class of " + outerClass;
+ return child;
+ }
+
+ @Override
+ public void accept(VirtualFile innerClass, StubBuildingVisitor<VirtualFile> visitor) {
+ try {
+ byte[] bytes = innerClass.contentsToByteArray();
+ new ClassReader(bytes).accept(visitor, ClassReader.SKIP_FRAMES);
+ }
+ catch (IOException ignored) { }
+ }
+ };
+ PsiJavaFileStubImpl stub = new PsiJavaFileStubImpl("do.not.know.yet", true);
+ StubBuildingVisitor<VirtualFile> visitor = new StubBuildingVisitor<VirtualFile>(file, strategy, stub, 0, null);
+ new ClassReader(file.contentsToByteArray()).accept(visitor, ClassReader.SKIP_FRAMES);
+ }
+
private void doTest() {
doTest(getTestName(false));
}
@@ -85,11 +117,9 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
}
private static void doTest(String clsPath, String txtPath) {
- VirtualFileSystem fs = clsPath.contains("!/") ? JarFileSystem.getInstance() : LocalFileSystem.getInstance();
- VirtualFile vFile = fs.findFileByPath(clsPath);
- assertNotNull(clsPath, vFile);
- PsiFile clsFile = getPsiManager().findFile(vFile);
- assertNotNull(vFile.getPath(), clsFile);
+ VirtualFileSystem fs = clsPath.contains("!/") ? StandardFileSystems.jar() : StandardFileSystems.local();
+ VirtualFile file = fs.findFileByPath(clsPath);
+ assertNotNull(clsPath, file);
String expected;
try {
@@ -100,6 +130,6 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
return;
}
- assertEquals(expected, ((ClsFileImpl)clsFile).getMirror().getText());
+ assertEquals(expected, ClsFileImpl.decompile(file).toString());
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java
index 16392eb601d5..e8317415d8b3 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java
@@ -690,7 +690,6 @@ public class ClsRepositoryUseTest extends PsiTestCase {
final PsiType returnType = methodsWithReturnType.getReturnType();
assert returnType != null : methodsWithReturnType;
assertEquals("pack.Parametrized<? extends T>", returnType.getCanonicalText());
- assertEquals("public pack.Parametrized<? extends T> method() { /* compiled code */ }", methodsWithReturnType.getText());
}
private static void checkEnumConstant(String name, PsiField field, PsiClassType type) {
@@ -740,19 +739,20 @@ public class ClsRepositoryUseTest extends PsiTestCase {
assertEquals(PsiWildcardType.createUnbounded(myPsiManager), substitution);
}
+ @SuppressWarnings("ConstantConditions")
public void testModifiers() throws Exception {
- final PsiClass psiClass = myJavaFacade.findClass("pack.Modifiers", RESOLVE_SCOPE);
+ PsiClass psiClass = myJavaFacade.findClass("pack.Modifiers", RESOLVE_SCOPE);
assertNotNull(psiClass);
- assertEquals("public class Modifiers {\n" +
- " private transient int f1;\n" +
- " private volatile int f2;\n" +
- "\n" +
- " public Modifiers() { /* compiled code */ }\n" +
- "\n" +
- " private void m1(int... i) { /* compiled code */ }\n" +
- "\n" +
- " private synchronized void m2() { /* compiled code */ }\n" +
- "}",
- psiClass.getText().trim());
+
+ PsiField f1 = psiClass.findFieldByName("f1", false);
+ assertEquals("private transient", f1.getModifierList().getText());
+ PsiField f2 = psiClass.findFieldByName("f2", false);
+ assertEquals("private volatile", f2.getModifierList().getText());
+ PsiMethod init = psiClass.findMethodsByName("Modifiers", false)[0];
+ assertEquals("public", init.getModifierList().getText());
+ PsiMethod m1 = psiClass.findMethodsByName("m1", false)[0];
+ assertEquals("private", m1.getModifierList().getText());
+ PsiMethod m2 = psiClass.findMethodsByName("m2", false)[0];
+ assertEquals("private synchronized", m2.getModifierList().getText());
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
index 301a99319cbb..096547c4f4db 100644
--- a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java
@@ -25,10 +25,11 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.source.tree.LazyParseableElement;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
public class MiscPsiTest extends LightCodeInsightFixtureTestCase {
@Override
- protected void invokeTestRunnable(final Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception {
new WriteCommandAction.Simple(getProject()) {
@Override
protected void run() throws Throwable {
diff --git a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
index c9153983344a..021f7f95c480 100644
--- a/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/StubAstSwitchTest.groovy
@@ -73,7 +73,13 @@ class StubAstSwitchTest extends LightCodeInsightFixtureTestCase {
}
CountDownLatch latch = new CountDownLatch(count)
for (c in classList) {
- ApplicationManager.application.executeOnPooledThread { Thread.yield(); c.text; latch.countDown() }
+ ApplicationManager.application.executeOnPooledThread {
+ Thread.yield();
+ ApplicationManager.application.runReadAction {
+ c.text;
+ }
+ latch.countDown()
+ }
for (m in c.methods) {
def parameters = m.parameterList.parameters
for (i in 0..<parameters.size()) {
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
index 302f1b331530..d11a34f6e376 100644
--- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFieldReferenceTest.groovy
@@ -328,9 +328,61 @@ class Second extends First {
)
}
+ void "test IDEA-123875"() {
+ doTest(
+ initial: '''\
+public class RearrangeFail {
+
+ public static final byte[] ENTITIES_END = "</entities>".getBytes();
+ private final Element entitiesEndElement = new Element(ENTITIES_END);
+ public static final byte[] ENTITIES_START = "<entities>".getBytes();
+ private final Element entitiesStartElement = new Element(ENTITIES_START);
+
+}
+''',
+ expected: '''\
+public class RearrangeFail {
+
+ public static final byte[] ENTITIES_END = "</entities>".getBytes();
+ public static final byte[] ENTITIES_START = "<entities>".getBytes();
+ private final Element entitiesEndElement = new Element(ENTITIES_END);
+ private final Element entitiesStartElement = new Element(ENTITIES_START);
+
+}
+''',
+ rules: [
+ rule(PUBLIC, STATIC, FINAL),
+ rule(PRIVATE),
+ ]
+ )
+ }
+ void "test IDEA-125099"() {
+ doTest(
+ initial: '''\
+public class test {
+ private int a = 2;
+ public static final String TEST = "1";
+ public static final String SHOULD_BE_IN_BETWEEN = "2";
+ public static final String USERS_ROLE_ID_COLUMN = TEST;
+}
+''',
+ expected: '''\
+public class test {
+ public static final String TEST = "1";
+ public static final String SHOULD_BE_IN_BETWEEN = "2";
+ public static final String USERS_ROLE_ID_COLUMN = TEST;
+ private int a = 2;
+}
+''',
+ rules: [
+ rule(PUBLIC, STATIC, FINAL),
+ rule(PRIVATE)
+ ]
+ )
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
index 8ea8d3a77112..2461a4601eba 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.file.impl;
@@ -640,4 +655,90 @@ public class PsiEventsTest extends PsiTestCase {
getPsiManager().removePsiTreeChangeListener(listener);
}
}
+
+ public void testPsiEventsComeWhenDocumentAlreadyCommitted() throws Exception {
+ myFile = createFile("A.java", "class A { int i; }");
+ getPsiManager().addPsiTreeChangeListener(new PsiTreeChangeListener() {
+ @Override
+ public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void beforePropertyChange(@NotNull PsiTreeChangeEvent event) {
+ // did not decide whether the doc should be committed at this point
+ //checkCommitted(false, event);
+ }
+
+ @Override
+ public void childAdded(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+
+ @Override
+ public void childRemoved(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+
+ @Override
+ public void childReplaced(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+
+ @Override
+ public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+
+ @Override
+ public void childMoved(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+
+ @Override
+ public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
+ checkCommitted(true, event);
+ }
+ }, myTestRootDisposable);
+
+ PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
+ Document document = documentManager.getDocument(getFile());
+ assertTrue(documentManager.isCommitted(document));
+
+ document.setText("");
+ documentManager.commitAllDocuments();
+ assertTrue(documentManager.isCommitted(document));
+ }
+
+ private void checkCommitted(boolean shouldBeCommitted, PsiTreeChangeEvent event) {
+ PsiFile file = event.getFile();
+ PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject());
+ Document document = documentManager.getDocument(file);
+ assertEquals(shouldBeCommitted, documentManager.isCommitted(document));
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy
index 5e6adfdb4f55..ce04dd0ba20c 100644
--- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy
@@ -20,12 +20,12 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiFile
-import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
+import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ClassInheritorsSearch
import com.intellij.psi.search.searches.OverridingMethodsSearch
+import com.intellij.psi.stubs.StubTreeLoader
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
/**
@@ -150,14 +150,12 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
Collection<VirtualFile> pkgDirs = pkg.directories.collect { it.virtualFile }
Collection<VirtualFile> pkgChildren = pkgDirs.collect { it.children as List }.flatten()
- PsiFile javaSrc = psiManager.findFile(pkgChildren.find { it.name == 'LibraryClass.java' })
- assert !javaSrc.contentsLoaded
- assert !javaSrc.stub
+ VirtualFile javaSrc = pkgChildren.find { it.name == 'LibraryClass.java' }
+ checkFileIsNotLoadedAndHasNoIndexedStub(javaSrc)
assert pkg.containsClassNamed('LibraryClass')
- assert !javaSrc.contentsLoaded
- assert !javaSrc.stub
- assert !javaSrc.node.parsed
+ checkFileIsNotLoadedAndHasNoIndexedStub(javaSrc)
+ assert !((PsiFileImpl)psiManager.findFile(javaSrc)).treeElement
}
@Override
@@ -174,7 +172,7 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
def localFile = myFixture.copyFileToProject(testDataPathForTest + File.separator + "Foo.java", 'Foo.java')
assert localFile != null
- checkFileIsNotLoadedAndHasNoStub(localFile)
+ checkFileIsNotLoadedAndHasNoIndexedStub(localFile)
assert facade.findClasses('Foo', scope).size() == 0
PsiTestUtil.addLibrary(myModule, 'cas', lib.path, [] as String[], ["/classesAndSources.jar!/"] as String[])
@@ -187,14 +185,16 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
assert facade.findClasses('LibraryClass', scope).size() == 0
- checkFileIsNotLoadedAndHasNoStub(vfile)
+ checkFileIsNotLoadedAndHasNoIndexedStub(vfile)
}
- private void checkFileIsNotLoadedAndHasNoStub(VirtualFile vfile) {
- def file = PsiManager.getInstance(project).findFile(vfile);
+ private void checkFileIsNotLoadedAndHasNoIndexedStub(VirtualFile vfile) {
+ PsiFileImpl file = psiManager.findFile(vfile);
assert file != null
assert !file.contentsLoaded
- assert !file.stub
+ assert !StubTreeLoader.instance.readFromVFile(project, vfile)
+ assert !StubTreeLoader.instance.canHaveStub(vfile)
+ assert file.stub // from text
}
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java
index 83e8fa10aed9..b34486fcf110 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java
@@ -187,6 +187,18 @@ public class MoveMembersTest extends MultiFileTestCase {
doTest("Outer.Inner", "Outer", true, VisibilityUtil.ESCALATE_VISIBILITY, 0);
}
+ public void testFromNestedToOuterMethodRef() throws Exception {
+ final LanguageLevelProjectExtension projectExtension = LanguageLevelProjectExtension.getInstance(getProject());
+ final LanguageLevel oldLevel = projectExtension.getLanguageLevel();
+ try {
+ projectExtension.setLanguageLevel(LanguageLevel.HIGHEST);
+ doTest("Outer.Inner", "Outer", true, VisibilityUtil.ESCALATE_VISIBILITY, 0);
+ }
+ finally {
+ projectExtension.setLanguageLevel(oldLevel);
+ }
+ }
+
@NotNull
@Override
protected String getTestRoot() {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
index c77b344f6722..99de5eb68dc4 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
@@ -264,6 +264,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
doTest();
}
+ public void testSameVarMethodNames() throws Exception {
+ doTest();
+ }
+
private void doTestInlineThisOnly() {
@NonNls String fileName = "/refactoring/inlineMethod/" + getTestName(false) + ".java";
configureByFile(fileName);
diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
index 180a8ee3c66a..514348e5913b 100644
--- a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java
@@ -1,12 +1,29 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.roots;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.module.impl.ModuleEx;
import com.intellij.openapi.module.impl.scopes.LibraryScope;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.ModuleTestCase;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
@@ -207,4 +224,28 @@ public class ModuleScopesTest extends ModuleTestCase {
addLibrary(myModule, DependencyScope.COMPILE);
assertTrue(myModule.getModuleWithDependenciesAndLibrariesScope(false).contains(file));
}
+
+ public void testScopeEquality() {
+ Module module = createModule("a.iml", StdModuleTypes.JAVA);
+ addDependentModule(module, DependencyScope.COMPILE);
+ addLibrary(module, DependencyScope.COMPILE);
+
+ GlobalSearchScope deps = module.getModuleWithDependentsScope();
+ GlobalSearchScope depsTests = module.getModuleTestsWithDependentsScope();
+
+ assertFalse(deps.equals(depsTests));
+ assertFalse(depsTests.equals(deps));
+
+ ((ModuleEx)module).clearScopesCache();
+
+ GlobalSearchScope deps2 = module.getModuleWithDependentsScope();
+ GlobalSearchScope depsTests2 = module.getModuleTestsWithDependentsScope();
+
+ assertFalse(deps2.equals(depsTests2));
+ assertFalse(depsTests2.equals(deps2));
+ assertNotSame(deps, deps2);
+ assertNotSame(depsTests, depsTests2);
+ assertEquals(deps, deps2);
+ assertEquals(depsTests, depsTests2);
+ }
}
diff --git a/java/java-tests/testSrc/com/intellij/slicer/SliceBackwardTest.java b/java/java-tests/testSrc/com/intellij/slicer/SliceBackwardTest.java
index 513fcec9d347..2f6ea959a1a6 100644
--- a/java/java-tests/testSrc/com/intellij/slicer/SliceBackwardTest.java
+++ b/java/java-tests/testSrc/com/intellij/slicer/SliceBackwardTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -179,6 +179,8 @@ public class SliceBackwardTest extends SliceTestCase {
public void testArrayElements() throws Exception { doTest();}
public void testAnonArray() throws Exception { doTest();}
public void testVarArgs() throws Exception { doTest();}
+ public void testVarArgsAsAWhole() throws Exception { doTest();}
+ public void testVarArgsPartial() throws Exception { doTest();}
public void testListTrackToArray() throws Exception { doTest();}
}
diff --git a/java/jdkAnnotations/java/awt/annotations.xml b/java/jdkAnnotations/java/awt/annotations.xml
index 9fbbebaabc5b..a1ea3a596052 100644
--- a/java/jdkAnnotations/java/awt/annotations.xml
+++ b/java/jdkAnnotations/java/awt/annotations.xml
@@ -71,6 +71,18 @@
<item name="java.awt.CardLayout void show(java.awt.Container, java.lang.String) 1">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
+ <item name='java.awt.Component java.awt.Point getLocation()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.awt.Component java.awt.Point location()'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.awt.Component void setLocation(java.awt.Point) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
+ <item name='java.awt.Container void add(java.awt.Component, java.lang.Object) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
<item name="java.awt.Container void addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 0">
<annotation name="org.jetbrains.annotations.NonNls" />
</item>
@@ -233,5 +245,8 @@
<val name="flagsFromClass" val="java.awt.event.InputEvent.class" />
</annotation>
</item>
+ <item name='java.awt.Window void setLocation(java.awt.Point) 0'>
+ <annotation name='org.jetbrains.annotations.NotNull'/>
+ </item>
</root>
diff --git a/java/mockJDK-1.7/jre/lib/rt.jar b/java/mockJDK-1.7/jre/lib/rt.jar
index 83d84402c386..09859acbfcf1 100644
--- a/java/mockJDK-1.7/jre/lib/rt.jar
+++ b/java/mockJDK-1.7/jre/lib/rt.jar
Binary files differ
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
index 9a05e8d3633c..30b9bfb30c01 100644
--- a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
@@ -19,6 +19,8 @@ import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.testFramework.fixtures.CompletionAutoPopupTester
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+import org.jetbrains.annotations.NotNull
+
/**
* @author peter
*/
@@ -38,7 +40,7 @@ abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCa
return false;
}
- @Override protected void invokeTestRunnable(Runnable runnable) {
+ @Override protected void invokeTestRunnable(@NotNull Runnable runnable) {
myTester.runWithAutoPopupEnabled(runnable)
}
diff --git a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
index 952cbc46fdcb..8ec8e3f6ebdd 100644
--- a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java
@@ -485,7 +485,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
return debuggerSession;
}
- private static class MockConfiguration implements ModuleRunConfiguration {
+ public static class MockConfiguration implements ModuleRunConfiguration {
@Override
@NotNull
public Module[] getModules() {
@@ -521,7 +521,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
@Override
@NotNull
public ConfigurationType getType() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return UnknownConfigurationType.INSTANCE;
}
@Override
diff --git a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
index db072f4ce97a..49db796244dd 100644
--- a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java
@@ -27,14 +27,15 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTree;
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
-import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.util.Pair;
+import com.intellij.ui.treeStructure.Tree;
import com.sun.jdi.Value;
+import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -160,46 +161,52 @@ public abstract class DescriptorTestCase extends DebuggerTestCase {
}
protected void expandAll(final DebuggerTree tree, final Runnable runnable) {
- doExpandAll(tree, runnable, new HashSet<Value>(), null);
+ expandAll(tree, runnable, new HashSet<Value>(), null);
}
protected interface NodeFilter {
- boolean shouldExpand(DebuggerTreeNode node);
+ boolean shouldExpand(TreeNode node);
}
-
- protected void expandAll(final DebuggerTree tree, final Runnable runnable, NodeFilter filter) {
- doExpandAll(tree, runnable, new HashSet<Value>(), filter);
+
+ protected void expandAll(final DebuggerTree tree, final Runnable runnable, final Set<Value> alreadyExpanded, final NodeFilter filter) {
+ expandAll(tree, runnable, alreadyExpanded, filter, tree.getDebuggerContext().getSuspendContext());
}
- private void doExpandAll(final DebuggerTree tree, final Runnable runnable, final Set<Value> alreadyExpanded, final NodeFilter filter) {
- invokeRatherLater(tree.getDebuggerContext().getSuspendContext(), new Runnable() {
+ protected void expandAll(final Tree tree,
+ final Runnable runnable,
+ final Set<Value> alreadyExpanded,
+ final NodeFilter filter,
+ final SuspendContextImpl context) {
+ invokeRatherLater(context, new Runnable() {
@Override
public void run() {
boolean anyCollapsed = false;
for(int i = 0; i < tree.getRowCount(); i++) {
- final DebuggerTreeNodeImpl treeNode = (DebuggerTreeNodeImpl)tree.getPathForRow(i).getLastPathComponent();
+ final TreeNode treeNode = (TreeNode)tree.getPathForRow(i).getLastPathComponent();
if(tree.isCollapsed(i) && !treeNode.isLeaf()) {
- final NodeDescriptor nodeDescriptor = treeNode.getDescriptor();
- boolean shouldExpand = filter == null || filter.shouldExpand(treeNode);
- if (shouldExpand) {
- // additional checks to prevent infinite expand
- if (nodeDescriptor instanceof ValueDescriptor) {
- final Value value = ((ValueDescriptor)nodeDescriptor).getValue();
- shouldExpand = !alreadyExpanded.contains(value);
- if (shouldExpand) {
- alreadyExpanded.add(value);
+ if (treeNode instanceof DebuggerTreeNodeImpl) {
+ final NodeDescriptor nodeDescriptor = ((DebuggerTreeNodeImpl)treeNode).getDescriptor();
+ boolean shouldExpand = filter == null || filter.shouldExpand(treeNode);
+ if (shouldExpand) {
+ // additional checks to prevent infinite expand
+ if (nodeDescriptor instanceof ValueDescriptor) {
+ final Value value = ((ValueDescriptor)nodeDescriptor).getValue();
+ shouldExpand = !alreadyExpanded.contains(value);
+ if (shouldExpand) {
+ alreadyExpanded.add(value);
+ }
}
}
- }
- if (shouldExpand) {
- anyCollapsed = true;
- tree.expandRow(i);
+ if (shouldExpand) {
+ anyCollapsed = true;
+ tree.expandRow(i);
+ }
}
}
}
if (anyCollapsed) {
- doExpandAll(tree, runnable, alreadyExpanded, filter);
+ expandAll(tree, runnable, alreadyExpanded, filter, context);
}
else {
runnable.run();
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
index 8ae8848fabf1..2125daa8af4d 100644
--- a/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/NewProjectWizardTestCase.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.ide.projectWizard;
import com.intellij.ide.util.newProjectWizard.AbstractProjectWizard;
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
index dd94962cddfd..25751535842a 100644
--- a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.ide.projectWizard;
import com.intellij.ide.actions.ImportModuleAction;
@@ -43,7 +58,6 @@ import java.util.List;
*/
@SuppressWarnings("unchecked")
public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> extends PlatformTestCase {
-
protected static final String DEFAULT_SDK = "default";
protected final List<Sdk> mySdks = new ArrayList<Sdk>();
protected T myWizard;
@@ -118,7 +132,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
throw new RuntimeException(currentStep + " is not validated");
}
}
- myWizard.doOk();
+ myWizard.doFinishAction();
}
protected void createWizard(Project project) throws IOException {
@@ -147,6 +161,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
for (final Sdk jdk : jdks) {
if (projectSdk != jdk) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
public void run() {
ProjectJdkTable.getInstance().removeJdk(jdk);
}
@@ -157,6 +172,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
protected void setupJdk() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
public void run() {
ProjectJdkTable jdkTable = ProjectJdkTable.getInstance();
Sdk defaultJdk = new SimpleJavaSdkType().createJdk(DEFAULT_SDK, SystemProperties.getJavaHome());
@@ -181,6 +197,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
public void tearDown() throws Exception {
if (myWizard != null) {
Disposer.dispose(myWizard.getDisposable());
+ myWizard = null;
}
if (myCreatedProject != null) {
myProjectManager.closeProject(myCreatedProject);
@@ -190,8 +207,10 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
Disposer.dispose(myCreatedProject);
}
});
+ myCreatedProject = null;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
public void run() {
for (Sdk sdk : mySdks) {
ProjectJdkTable.getInstance().removeJdk(sdk);
@@ -199,6 +218,9 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
}
});
SelectTemplateSettings.getInstance().setLastTemplate(null, null);
+ UIUtil.dispatchAllInvocationEvents();
+ Thread.sleep(2000); //wait for JBCardLayout release timers
+ UIUtil.dispatchAllInvocationEvents();
super.tearDown();
}
@@ -233,6 +255,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
protected Sdk createSdk(String name, SdkTypeId sdkType) {
final Sdk sdk = ProjectJdkTable.getInstance().createSdk(name, sdkType);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
public void run() {
ProjectJdkTable.getInstance().addJdk(sdk);
}
diff --git a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
index 6af8389b8abe..00780b9b76ce 100644
--- a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
+++ b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
@@ -227,14 +227,11 @@ public class CompilerTester {
@Override
public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
- System.out.println("ErrorReportingCallback.finished");
try {
for (CompilerMessageCategory category : CompilerMessageCategory.values()) {
- System.out.println("category = " + category);
CompilerMessage[] messages = compileContext.getMessages(category);
for (CompilerMessage message : messages) {
final String text = message.getMessage();
- System.out.println("message = " + message);
if (category != CompilerMessageCategory.INFORMATION || !(text.startsWith("Compilation completed successfully") || text.startsWith("Using javac"))) {
myMessages.add(message);
}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
index 5d986128ee66..3699fe36aff5 100644
--- a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
@@ -36,6 +36,18 @@ import java.io.File;
* @author peter
*/
public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{
+ public static final LightProjectDescriptor JAVA_1_4 = new DefaultLightProjectDescriptor() {
+ @Override
+ public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+ model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
+ }
+ };
+ public static final LightProjectDescriptor JAVA_1_5 = new DefaultLightProjectDescriptor() {
+ @Override
+ public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+ model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
+ }
+ };
public static final LightProjectDescriptor JAVA_1_6 = new DefaultLightProjectDescriptor() {
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml
index 22e65e9607ee..565691fb134e 100644
--- a/jps/jps-builders/jps-builders.iml
+++ b/jps/jps-builders/jps-builders.iml
@@ -12,7 +12,7 @@
<orderEntry type="module" module-name="forms_rt" />
<orderEntry type="module" module-name="forms-compiler" />
<orderEntry type="module" module-name="instrumentation-util" />
- <orderEntry type="library" exported="" name="asm4" level="project" />
+ <orderEntry type="library" exported="" name="asm5" level="project" />
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" name="NanoXML" level="project" />
<orderEntry type="library" name="jgoodies-forms" level="project" />
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
index ce3c2a4fc269..16a3da40fca1 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Callbacks.java
@@ -15,7 +15,7 @@
*/
package org.jetbrains.jps.builders.java.dependencyView;
-import org.jetbrains.asm4.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.File;
import java.util.Collection;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
index 21818f540cc7..2cbfe0592f3a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassRepr.java
@@ -20,8 +20,8 @@ import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.*;
import java.lang.annotation.RetentionPolicy;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
index 03dddda7183f..01013e05186a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ClassfileAnalyzer.java
@@ -19,9 +19,9 @@ import com.intellij.openapi.util.Pair;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TIntHashSet;
-import org.jetbrains.asm4.*;
-import org.jetbrains.asm4.signature.SignatureReader;
-import org.jetbrains.asm4.signature.SignatureVisitor;
+import org.jetbrains.org.objectweb.asm.*;
+import org.jetbrains.org.objectweb.asm.signature.SignatureReader;
+import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
import java.lang.annotation.RetentionPolicy;
import java.util.EnumSet;
@@ -55,7 +55,7 @@ class ClassfileAnalyzer {
private class ClassCrawler extends ClassVisitor {
private class AnnotationRetentionPolicyCrawler extends AnnotationVisitor {
private AnnotationRetentionPolicyCrawler() {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
}
public void visit(String name, Object value) {
@@ -79,7 +79,7 @@ class ClassfileAnalyzer {
private class AnnotationTargetCrawler extends AnnotationVisitor {
private AnnotationTargetCrawler() {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
}
public void visit(String name, Object value) {
@@ -108,7 +108,7 @@ class ClassfileAnalyzer {
private final TIntHashSet myUsedArguments = new TIntHashSet();
private AnnotationCrawler(final TypeRepr.ClassType type, final ElemType target) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
this.myType = type;
this.myTarget = target;
final Set<ElemType> targets = myAnnotationTargets.get(type);
@@ -160,9 +160,7 @@ class ClassfileAnalyzer {
return "()D;";
}
- final String s = "()L" + name + ";";
-
- return s;
+ return "()L" + name + ";";
}
public void visit(String name, Object value) {
@@ -171,10 +169,7 @@ class ClassfileAnalyzer {
if (value instanceof Type) {
final String className = ((Type)value).getClassName().replace('.', '/');
-
- if (className != null) {
- myUsages.add(UsageRepr.createClassUsage(myContext, myContext.get(className)));
- }
+ myUsages.add(UsageRepr.createClassUsage(myContext, myContext.get(className)));
}
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, myType.className, methodDescr));
@@ -220,9 +215,8 @@ class ClassfileAnalyzer {
}
}
- private final SignatureVisitor mySignatureCrawler = new SignatureVisitor(Opcodes.ASM4) {
+ private final SignatureVisitor mySignatureCrawler = new SignatureVisitor(Opcodes.ASM5) {
public void visitFormalTypeParameter(String name) {
- return;
}
public SignatureVisitor visitClassBound() {
@@ -254,11 +248,9 @@ class ClassfileAnalyzer {
}
public void visitBaseType(char descriptor) {
- return;
}
public void visitTypeVariable(String name) {
- return;
}
public SignatureVisitor visitArrayType() {
@@ -266,11 +258,9 @@ class ClassfileAnalyzer {
}
public void visitInnerClassType(String name) {
- return;
}
public void visitTypeArgument() {
- return;
}
public SignatureVisitor visitTypeArgument(char wildcard) {
@@ -316,7 +306,7 @@ class ClassfileAnalyzer {
final Map<TypeRepr.ClassType, Set<ElemType>> myAnnotationTargets = new THashMap<TypeRepr.ClassType, Set<ElemType>>();
public ClassCrawler(final int fn) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
myFileName = fn;
}
@@ -407,7 +397,7 @@ class ClassfileAnalyzer {
myFields.add(new FieldRepr(myContext, access, myContext.get(n), myContext.get(desc), myContext.get(signature), value));
}
- return new FieldVisitor(Opcodes.ASM4) {
+ return new FieldVisitor(Opcodes.ASM5) {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(myContext, myContext.get(desc)), ElemType.FIELD);
@@ -421,7 +411,7 @@ class ClassfileAnalyzer {
processSignature(signature);
- return new MethodVisitor(Opcodes.ASM4) {
+ return new MethodVisitor(Opcodes.ASM5) {
@Override
public void visitEnd() {
if ((access & Opcodes.ACC_SYNTHETIC) == 0 || (access & Opcodes.ACC_BRIDGE) > 0) {
@@ -438,7 +428,7 @@ class ClassfileAnalyzer {
@Override
public AnnotationVisitor visitAnnotationDefault() {
- return new AnnotationVisitor(Opcodes.ASM4) {
+ return new AnnotationVisitor(Opcodes.ASM5) {
public void visit(String name, Object value) {
defaultValue.set(value);
}
@@ -531,7 +521,7 @@ class ClassfileAnalyzer {
}
@Override
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
final int methodName = myContext.get(name);
final int methodOwner = myContext.get(owner);
@@ -539,7 +529,7 @@ class ClassfileAnalyzer {
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner, desc));
addClassUsage(TypeRepr.getType(myContext, Type.getReturnType(desc)));
- super.visitMethodInsn(opcode, owner, name, desc);
+ super.visitMethodInsn(opcode, owner, name, desc, itf);
}
private void addClassUsage(final TypeRepr.AbstractType type) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Difference.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Difference.java
index d96cf7c7b59e..95ed983a9181 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Difference.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Difference.java
@@ -16,7 +16,7 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.openapi.util.Pair;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.util.*;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
index a0c4b60f3f69..a397d4b87a55 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java
@@ -23,10 +23,10 @@ import com.intellij.util.io.IntInlineKeyDescriptor;
import gnu.trove.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
import org.jetbrains.jps.incremental.storage.FileKeyDescriptor;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.FileNotFoundException;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
index 72ad7557cd0b..fea3d8a3d8d8 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/MethodRepr.java
@@ -19,8 +19,8 @@ import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.Type;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Type;
import java.io.DataInput;
import java.io.DataOutput;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
index a7e70f67dcbc..2810863de840 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Proto.java
@@ -16,8 +16,8 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataInputOutputUtil;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.DataInput;
import java.io.DataOutput;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
index 18582a8bc373..afb5cc958a93 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/ProtoMember.java
@@ -16,8 +16,8 @@
package org.jetbrains.jps.builders.java.dependencyView;
import com.intellij.util.io.DataInputOutputUtil;
-import org.jetbrains.asm4.Type;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Type;
import java.io.DataInput;
import java.io.DataOutput;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
index af85d75f344f..da4d71baff1a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/TypeRepr.java
@@ -19,8 +19,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataInputOutputUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.Type;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Type;
import java.io.DataInput;
import java.io.DataOutput;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
index 5059152e6a63..e7b376980fae 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/UsageRepr.java
@@ -20,8 +20,8 @@ import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.Type;
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
+import org.jetbrains.org.objectweb.asm.Type;
import java.io.DataInput;
import java.io.DataOutput;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/AsmUtil.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/AsmUtil.java
index 4082d9542698..14552a8173d3 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/AsmUtil.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/AsmUtil.java
@@ -17,7 +17,7 @@ package org.jetbrains.jps.classFilesIndex;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.asm4.Type;
+import org.jetbrains.org.objectweb.asm.Type;
import java.util.Set;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFileIndexer.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFileIndexer.java
index 827183e3fb82..e7b3212543e1 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFileIndexer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFileIndexer.java
@@ -18,8 +18,8 @@ package org.jetbrains.jps.classFilesIndex.indexer.api;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.ClassReader;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.util.Map;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndexWriter.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndexWriter.java
index 932ddb1b64ef..95e92f0f7478 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndexWriter.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndexWriter.java
@@ -15,15 +15,14 @@
*/
package org.jetbrains.jps.classFilesIndex.indexer.api;
-import com.intellij.openapi.diagnostic.Log;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.PersistentHashMap;
-import org.jetbrains.asm4.ClassReader;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.classFilesIndex.indexer.api.storage.ClassFilesIndexStorageBase;
import org.jetbrains.jps.classFilesIndex.indexer.api.storage.ClassFilesIndexStorageWriter;
import org.jetbrains.jps.incremental.CompileContext;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.File;
import java.io.IOException;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndicesBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndicesBuilder.java
index 92fd4d9351b5..384e4cb6a193 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndicesBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/api/ClassFilesIndicesBuilder.java
@@ -17,26 +17,22 @@ package org.jetbrains.jps.classFilesIndex.indexer.api;
import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
-import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.incremental.BinaryContent;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.CompiledClass;
import org.jetbrains.jps.incremental.instrumentation.BaseInstrumentingBuilder;
-import org.jetbrains.jps.model.java.JpsJavaExtensionService;
-import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.service.JpsServiceManager;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
-import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/MethodsUsageIndexer.java b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/MethodsUsageIndexer.java
index 7caa11b18fa4..4853cb5b109c 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/MethodsUsageIndexer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/classFilesIndex/indexer/impl/MethodsUsageIndexer.java
@@ -17,15 +17,14 @@ package org.jetbrains.jps.classFilesIndex.indexer.impl;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorIntegerDescriptor;
-import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.*;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.classFilesIndex.AsmUtil;
import org.jetbrains.jps.classFilesIndex.TObjectIntHashMapExternalizer;
import org.jetbrains.jps.classFilesIndex.indexer.api.ClassFileIndexer;
+import org.jetbrains.org.objectweb.asm.*;
import java.util.HashMap;
import java.util.Map;
@@ -45,9 +44,9 @@ public class MethodsUsageIndexer extends ClassFileIndexer<Integer, TObjectIntHas
public Map<Integer, TObjectIntHashMap<EnumeratedMethodIncompleteSignature>> map(final ClassReader inputData, final Mappings mappings) {
final Map<Integer, TObjectIntHashMap<EnumeratedMethodIncompleteSignature>> map =
new HashMap<Integer, TObjectIntHashMap<EnumeratedMethodIncompleteSignature>>();
- final MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4) {
+ final MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM5) {
@Override
- public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
final Type returnType = Type.getReturnType(desc);
if (AsmUtil.isPrimitiveOrArrayOfPrimitives(returnType.getDescriptor()) || "<init>".equals(name)) {
return;
@@ -69,7 +68,7 @@ public class MethodsUsageIndexer extends ClassFileIndexer<Integer, TObjectIntHas
}
}
};
- inputData.accept(new ClassVisitor(Opcodes.ASM4) {
+ inputData.accept(new ClassVisitor(Opcodes.ASM5) {
@Override
public MethodVisitor visitMethod(final int access,
final String name,
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
index a22c5f25b8d4..95279d5df6d2 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java
@@ -141,6 +141,11 @@ final class BuildSession implements Runnable, CanceledStatus {
CustomBuilderMessage builderMessage = (CustomBuilderMessage)buildMessage;
response = CmdlineProtoUtil.createCustomBuilderMessage(builderMessage.getBuilderId(), builderMessage.getMessageType(), builderMessage.getMessageText());
}
+ else if (buildMessage instanceof BuilderStatisticsMessage) {
+ BuilderStatisticsMessage message = (BuilderStatisticsMessage)buildMessage;
+ LOG.info("Build duration: '" + message.getBuilderName() + "' builder took " + message.getElapsedTimeMs() + " ms");
+ response = null;
+ }
else if (!(buildMessage instanceof BuildingTargetProgressMessage)) {
float done = -1.0f;
if (buildMessage instanceof ProgressMessage) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
index c89cb50397fb..3e5d2514c5a2 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java
@@ -30,14 +30,14 @@ import io.netty.util.NetUtil;
import jsr166e.extra.SequenceLock;
import net.n3.nanoxml.IXMLBuilder;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceTransformer;
import org.jetbrains.jps.javac.JavacServer;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.impl.JpsModelImpl;
import org.jetbrains.jps.model.serialization.JpsProjectLoader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
import javax.tools.*;
import java.io.File;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java
index 2dd177501fdf..882ec81062be 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java
@@ -21,9 +21,7 @@ import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.*;
-import org.jetbrains.jps.builders.impl.BuildOutputConsumerImpl;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
-import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase;
import org.jetbrains.jps.builders.logging.ProjectBuilderLogger;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
@@ -87,24 +85,6 @@ public class BuildOperations {
pd.fsState.markInitialScanPerformed(target);
}
- public static <R extends BuildRootDescriptor, T extends BuildTarget<R>>
- void buildTarget(final T target, final CompileContext context, TargetBuilder<?, ?> builder) throws ProjectBuildException, IOException {
-
- if (builder.getTargetTypes().contains(target.getTargetType())) {
- DirtyFilesHolder<R, T> holder = new DirtyFilesHolderBase<R, T>(context) {
- @Override
- public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
- context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
- }
- };
- //noinspection unchecked
- BuildOutputConsumerImpl outputConsumer = new BuildOutputConsumerImpl(target, context);
- ((TargetBuilder<R, T>)builder).build(target, holder, outputConsumer, context);
- outputConsumer.fireFileGeneratedEvent();
- context.checkCanceled();
- }
- }
-
public static void markTargetsUpToDate(CompileContext context, BuildTargetChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final BuildFSState fsState = pd.fsState;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
index a981fa0e910e..baa67a0216d8 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.concurrency.BoundedTaskExecutor;
import com.intellij.util.containers.ConcurrentHashSet;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.MappingFailedException;
import com.intellij.util.io.PersistentEnumerator;
@@ -37,6 +38,7 @@ import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.api.GlobalOptions;
import org.jetbrains.jps.api.RequestFuture;
import org.jetbrains.jps.builders.*;
+import org.jetbrains.jps.builders.impl.BuildOutputConsumerImpl;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
@@ -70,6 +72,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -113,6 +116,7 @@ public class IncProjectBuilder {
private final float myTotalTargetsWork;
private final int myTotalModuleLevelBuilderCount;
private final List<Future> myAsyncTasks = Collections.synchronizedList(new ArrayList<Future>());
+ private final ConcurrentMap<Builder, AtomicLong> myElapsedTimeNanosByBuilder = ContainerUtil.newConcurrentMap();
public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry, Map<String, String> builderParams, CanceledStatus cs,
@Nullable Callbacks.ConstantAffectionResolver constantSearch, final boolean isTestMode) {
@@ -356,6 +360,7 @@ public class IncProjectBuilder {
context.processMessage(new ProgressMessage("Running 'after' tasks"));
runTasks(context, myBuilderRegistry.getAfterTasks());
TimingLog.LOG.debug("'after' tasks finished");
+ sendElapsedTimeMessages(context);
}
finally {
for (TargetBuilder builder : myBuilderRegistry.getTargetBuilders()) {
@@ -369,6 +374,12 @@ public class IncProjectBuilder {
}
+ private void sendElapsedTimeMessages(CompileContext context) {
+ for (Map.Entry<Builder, AtomicLong> entry : myElapsedTimeNanosByBuilder.entrySet()) {
+ context.processMessage(new BuilderStatisticsMessage(entry.getKey().getPresentableName(), entry.getValue().get()/1000000));
+ }
+ }
+
private void startTempDirectoryCleanupTask() {
final File systemRoot = Utils.getSystemRoot();
final String tempPath = System.getProperty("java.io.tmpdir", null);
@@ -822,12 +833,32 @@ public class IncProjectBuilder {
final List<TargetBuilder<?, ?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
for (TargetBuilder<?, ?> builder : builders) {
- BuildOperations.buildTarget(target, context, builder);
+ buildTarget(target, context, builder);
updateDoneFraction(context, 1.0f / builders.size());
}
return true;
}
+ private <R extends BuildRootDescriptor, T extends BuildTarget<R>>
+ void buildTarget(final T target, final CompileContext context, TargetBuilder<?, ?> builder) throws ProjectBuildException, IOException {
+
+ if (builder.getTargetTypes().contains(target.getTargetType())) {
+ DirtyFilesHolder<R, T> holder = new DirtyFilesHolderBase<R, T>(context) {
+ @Override
+ public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
+ context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
+ }
+ };
+ //noinspection unchecked
+ BuildOutputConsumerImpl outputConsumer = new BuildOutputConsumerImpl(target, context);
+ long start = System.nanoTime();
+ ((TargetBuilder<R, T>)builder).build(target, holder, outputConsumer, context);
+ incBuilderElapsedTime(builder, System.nanoTime() - start);
+ outputConsumer.fireFileGeneratedEvent();
+ context.checkCanceled();
+ }
+ }
+
private static <T extends BuildRootDescriptor>
void cleanOldOutputs(final CompileContext context, final BuildTarget<T> target) throws ProjectBuildException, IOException {
if (!context.getScope().isBuildForced(target)) {
@@ -1105,7 +1136,9 @@ public class IncProjectBuilder {
for (ModuleLevelBuilder builder : builders) {
processDeletedPaths(context, chunk.getTargets());
+ long start = System.nanoTime();
final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk, dirtyFilesHolder, outputConsumer);
+ incBuilderElapsedTime(builder, System.nanoTime() - start);
doneSomething |= (buildResult != ModuleLevelBuilder.ExitCode.NOTHING_DONE);
@@ -1169,6 +1202,13 @@ public class IncProjectBuilder {
return doneSomething;
}
+ private void incBuilderElapsedTime(Builder builder, long timeNanos) {
+ if (!myElapsedTimeNanosByBuilder.containsKey(builder)) {
+ myElapsedTimeNanosByBuilder.putIfAbsent(builder, new AtomicLong());
+ }
+ myElapsedTimeNanosByBuilder.get(builder).addAndGet(timeNanos);
+ }
+
private static void saveInstrumentedClasses(ChunkBuildOutputConsumerImpl outputConsumer) throws IOException {
for (CompiledClass compiledClass : outputConsumer.getCompiledClasses().values()) {
if (compiledClass.isDirty()) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java
index c03ebcb800ec..69ba370c2515 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/BaseInstrumentingBuilder.java
@@ -20,8 +20,6 @@ import com.intellij.compiler.instrumentation.InstrumenterClassWriter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.incremental.BinaryContent;
import org.jetbrains.jps.incremental.BuilderCategory;
@@ -29,6 +27,8 @@ import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.CompiledClass;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
/**
* @author Eugene Zhuravlev
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
index af1c974b84a2..551c3ce2f308 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
@@ -19,16 +19,16 @@ import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.ClassWriter;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -140,7 +140,7 @@ public abstract class ClassProcessingBuilder extends ModuleLevelBuilder {
public static int getClassFileVersion(ClassReader reader) {
final Ref<Integer> result = new Ref<Integer>(0);
- reader.accept(new ClassVisitor(Opcodes.ASM4) {
+ reader.accept(new ClassVisitor(Opcodes.ASM5) {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
result.set(version);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java
index f23b122aa29a..f46b6a54414e 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/NotNullInstrumentingBuilder.java
@@ -19,9 +19,6 @@ import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassWriter;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.BinaryContent;
@@ -30,6 +27,9 @@ import org.jetbrains.jps.incremental.CompiledClass;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.File;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java
index e481a0265ad4..19bd9f142082 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/OutputFilesSink.java
@@ -19,7 +19,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.ClassReader;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.incremental.BinaryContent;
@@ -31,8 +30,9 @@ import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.javac.OutputFileConsumer;
import org.jetbrains.jps.javac.OutputFileObject;
+import org.jetbrains.org.objectweb.asm.ClassReader;
-import javax.tools.JavaFileObject;
+import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuilderStatisticsMessage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuilderStatisticsMessage.java
new file mode 100644
index 000000000000..f58546f64cec
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuilderStatisticsMessage.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.incremental.messages;
+
+/**
+ * @author nik
+ */
+public class BuilderStatisticsMessage extends BuildMessage {
+ private final String myBuilderName;
+ private final long myElapsedTimeMs;
+
+ public BuilderStatisticsMessage(String builderName, long elapsedTimeMs) {
+ super(builderName + " elapsed " + elapsedTimeMs + "ms", Kind.INFO);
+ myBuilderName = builderName;
+ myElapsedTimeMs = elapsedTimeMs;
+ }
+
+ public String getBuilderName() {
+ return myBuilderName;
+ }
+
+ public long getElapsedTimeMs() {
+ return myElapsedTimeMs;
+ }
+}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java
index 0b2e90533b24..35834335332d 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java
@@ -23,6 +23,7 @@ import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleType;
import org.jetbrains.jps.model.module.JpsSdkReferencesTable;
import org.jetbrains.jps.model.module.JpsTypedModule;
+import org.jetbrains.jps.model.runConfiguration.JpsRunConfiguration;
import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType;
import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration;
@@ -61,6 +62,9 @@ public interface JpsProject extends JpsCompositeElement, JpsReferenceableElement
Iterable<JpsTypedRunConfiguration<P>> getRunConfigurations(JpsRunConfigurationType<P> type);
@NotNull
+ List<JpsRunConfiguration> getRunConfigurations();
+
+ @NotNull
<P extends JpsElement>
JpsTypedRunConfiguration<P> addRunConfiguration(@NotNull String name, @NotNull JpsRunConfigurationType<P> type, @NotNull P properties);
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java
index e210fc5836cd..56d2b985bf75 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java
@@ -134,6 +134,12 @@ public class JpsProjectImpl extends JpsRootElementBase<JpsProjectImpl> implement
@NotNull
@Override
+ public List<JpsRunConfiguration> getRunConfigurations() {
+ return getRunConfigurationsCollection().getElements();
+ }
+
+ @NotNull
+ @Override
public <P extends JpsElement> JpsTypedRunConfiguration<P> addRunConfiguration(@NotNull String name,
@NotNull JpsRunConfigurationType<P> type,
@NotNull P properties) {
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java
index 3b5a5e4a707e..81b0c8298813 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java
@@ -134,7 +134,7 @@ public class JpsProjectLoader extends JpsLoaderBase {
artifactsTimingLog.run();
if (hasRunConfigurationSerializers()) {
- Runnable runConfTimingLog = TimingLog.startActivity("loading artifacts");
+ Runnable runConfTimingLog = TimingLog.startActivity("loading run configurations");
for (File configurationFile : listXmlFiles(new File(dir, "runConfigurations"))) {
JpsRunConfigurationSerializer.loadRunConfigurations(myProject, loadRootElement(configurationFile));
}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java
index 6e619dc4c88c..b20ddf0ff9ae 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java
@@ -21,6 +21,7 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
@@ -45,17 +46,21 @@ public class JpsRunConfigurationSerializer {
String typeId = configurationTag.getAttributeValue("type");
JpsRunConfigurationPropertiesSerializer<?> serializer = serializers.get(typeId);
+ String name = configurationTag.getAttributeValue("name");
if (serializer != null) {
- loadRunConfiguration(configurationTag, serializer, project);
+ loadRunConfiguration(name, configurationTag, serializer, project);
+ }
+ else {
+ project.addRunConfiguration(name, new JpsUnknownRunConfigurationType(typeId), JpsElementFactory.getInstance().createDummyElement());
}
}
}
- private static <P extends JpsElement> void loadRunConfiguration(Element configurationTag,
+ private static <P extends JpsElement> void loadRunConfiguration(final String name, Element configurationTag,
JpsRunConfigurationPropertiesSerializer<P> serializer,
JpsProject project) {
P properties = serializer.loadProperties(configurationTag);
- project.addRunConfiguration(configurationTag.getAttributeValue("name"), serializer.getType(), properties);
+ project.addRunConfiguration(name, serializer.getType(), properties);
}
}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsUnknownRunConfigurationType.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsUnknownRunConfigurationType.java
new file mode 100644
index 000000000000..ea666571b3f9
--- /dev/null
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsUnknownRunConfigurationType.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.model.serialization.runConfigurations;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.JpsDummyElement;
+import org.jetbrains.jps.model.ex.JpsElementTypeWithDummyProperties;
+import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType;
+
+/**
+ * @author nik
+ */
+public class JpsUnknownRunConfigurationType extends JpsElementTypeWithDummyProperties implements JpsRunConfigurationType<JpsDummyElement> {
+ private final String myTypeId;
+
+ public JpsUnknownRunConfigurationType(@NotNull String typeId) {
+ myTypeId = typeId;
+ }
+
+ @NotNull
+ public String getTypeId() {
+ return myTypeId;
+ }
+}
diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java
index 44cc637ab2f4..dc260e1f6551 100644
--- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java
+++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsRunConfigurationsSerializationTest.java
@@ -16,9 +16,13 @@
package org.jetbrains.jps.model.serialization;
import com.intellij.util.containers.ContainerUtil;
+import junit.framework.AssertionFailedError;
import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationProperties;
import org.jetbrains.jps.model.java.runConfiguration.JpsApplicationRunConfigurationType;
+import org.jetbrains.jps.model.runConfiguration.JpsRunConfiguration;
+import org.jetbrains.jps.model.runConfiguration.JpsRunConfigurationType;
import org.jetbrains.jps.model.runConfiguration.JpsTypedRunConfiguration;
+import org.jetbrains.jps.model.serialization.runConfigurations.JpsUnknownRunConfigurationType;
import java.util.List;
@@ -47,5 +51,19 @@ public class JpsRunConfigurationsSerializationTest extends JpsSerializationTestC
JpsTypedRunConfiguration<JpsApplicationRunConfigurationProperties> main = configurations.get(1);
assertEquals("Main", main.getName());
assertEquals("xxx.Main", main.getProperties().getMainClass());
+
+ List<JpsRunConfiguration> all = myProject.getRunConfigurations();
+ JpsRunConfiguration junit = findByName(all, "test");
+ JpsRunConfigurationType type = ((JpsTypedRunConfiguration)junit).getType();
+ assertEquals("JUnit", assertInstanceOf(type, JpsUnknownRunConfigurationType.class).getTypeId());
+ }
+
+ private static JpsRunConfiguration findByName(List<JpsRunConfiguration> configurations, String name) {
+ for (JpsRunConfiguration configuration : configurations) {
+ if (configuration.getName().equals(name)) {
+ return configuration;
+ }
+ }
+ throw new AssertionFailedError("'" + name + "' run configuration not found");
}
}
diff --git a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
index 6f7d41b2a080..e4d446f808dd 100644
--- a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
+++ b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java
@@ -31,6 +31,7 @@ import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.cmdline.JpsModelLoader;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.messages.BuildMessage;
+import org.jetbrains.jps.incremental.messages.BuilderStatisticsMessage;
import org.jetbrains.jps.incremental.messages.BuildingTargetProgressMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.model.JpsModel;
@@ -295,7 +296,12 @@ public class JpsGantProjectBuilder {
warning(text);
break;
case INFO:
- if (!text.isEmpty()) {
+ if (msg instanceof BuilderStatisticsMessage) {
+ BuilderStatisticsMessage message = (BuilderStatisticsMessage)msg;
+ myBuildInfoPrinter.printStatisticsMessage(JpsGantProjectBuilder.this, "Compilation time '" + message.getBuilderName() + "', ms",
+ String.valueOf(message.getElapsedTimeMs()));
+ }
+ else if (!text.isEmpty()) {
info(text);
}
break;
diff --git a/lib/asm-all.jar b/lib/asm-all.jar
index 0257ef24af13..800313398c81 100644
--- a/lib/asm-all.jar
+++ b/lib/asm-all.jar
Binary files differ
diff --git a/lib/freemarker.jar b/lib/freemarker.jar
new file mode 100644
index 000000000000..8b93b176e309
--- /dev/null
+++ b/lib/freemarker.jar
Binary files differ
diff --git a/lib/guava-14.0.1.jar b/lib/guava-14.0.1.jar
deleted file mode 100644
index 3a3d9258e3b9..000000000000
--- a/lib/guava-14.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/guava-17.0.jar b/lib/guava-17.0.jar
new file mode 100644
index 000000000000..661fc7473f87
--- /dev/null
+++ b/lib/guava-17.0.jar
Binary files differ
diff --git a/lib/netty-all-4.1.0.Alpha1.jar b/lib/netty-all-4.1.0.Alpha1.jar
deleted file mode 100644
index ef99234e5fc2..000000000000
--- a/lib/netty-all-4.1.0.Alpha1.jar
+++ /dev/null
Binary files differ
diff --git a/lib/netty-all-4.1.0.Beta1.jar b/lib/netty-all-4.1.0.Beta1.jar
new file mode 100644
index 000000000000..cbd8b2cb6d33
--- /dev/null
+++ b/lib/netty-all-4.1.0.Beta1.jar
Binary files differ
diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt
index 92b9434f6f34..77d0b5b11961 100644
--- a/lib/required_for_dist.txt
+++ b/lib/required_for_dist.txt
@@ -12,11 +12,12 @@ commons-net-3.1.jar
httpcore-4.3.1.jar
httpclient-4.3.2.jar
fluent-hc-4.3.2.jar
+freemarker.jar
httpmime-4.3.2.jar
ecj-4.3.2.jar
groovy-all-2.2.1.jar
gson-2.2.4.jar
-guava-14.0.1.jar
+guava-17.0.jar
hamcrest-core-1.3.jar
hamcrest-library-1.3.jar
jaxen-1.1.3.jar
@@ -47,7 +48,7 @@ microba.jar
miglayout-swing.jar
nanoxml-2.2.3.jar
nekohtml-1.9.14.jar
-netty-all-4.1.0.Alpha1.jar
+netty-all-4.1.0.Beta1.jar
oromatcher.jar
picocontainer.jar
protobuf-2.5.0.jar
diff --git a/lib/src/guava-14.0.1-sources.jar b/lib/src/guava-14.0.1-sources.jar
deleted file mode 100644
index 55c848e59bda..000000000000
--- a/lib/src/guava-14.0.1-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/src/guava-17.0-sources.jar b/lib/src/guava-17.0-sources.jar
new file mode 100644
index 000000000000..2dab5249ffa4
--- /dev/null
+++ b/lib/src/guava-17.0-sources.jar
Binary files differ
diff --git a/lib/src/netty-all-4.1.0.Alpha1-sources.jar b/lib/src/netty-all-4.1.0.Alpha1-sources.jar
deleted file mode 100644
index a3fff4f2fe59..000000000000
--- a/lib/src/netty-all-4.1.0.Alpha1-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/src/netty-all-4.1.0.Beta1-sources.jar b/lib/src/netty-all-4.1.0.Beta1-sources.jar
new file mode 100644
index 000000000000..48e83c77330f
--- /dev/null
+++ b/lib/src/netty-all-4.1.0.Beta1-sources.jar
Binary files differ
diff --git a/native/MacLauncher/Launcher.m b/native/MacLauncher/Launcher.m
index 716f8b7a02de..630cf741fdab 100644
--- a/native/MacLauncher/Launcher.m
+++ b/native/MacLauncher/Launcher.m
@@ -106,9 +106,9 @@ NSArray *allVms() {
}
if (! jvmBundlePaths.count > 0 ) {
NSBundle *bundle = [NSBundle mainBundle];
- NSString *appDir = bundle.bundlePath;
+ NSString *appDir = [bundle.bundlePath stringByAppendingPathComponent:@"Contents"];
- appendJvmBundlesAt([appDir stringByAppendingPathComponent:@"jre"], jvmBundlePaths);
+ appendJvmBundlesAt([appDir stringByAppendingPathComponent:@"/jre"], jvmBundlePaths);
if (jvmBundlePaths.count > 0) return jvmBundlePaths;
appendJvmBundlesAt([NSHomeDirectory() stringByAppendingPathComponent:@"Library/Java/JavaVirtualMachines"], jvmBundlePaths);
@@ -226,10 +226,23 @@ NSString *getDefaultPropertiesFilePath() {
return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/bin/idea.properties"];
}
-NSString *getDefaultVMOptionsFilePath() {
- return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/bin/idea.vmoptions"];
+// NSString *getDefaultVMOptionsFilePath() {
+// return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@fileName];
+
+NSString *getDefaultFilePath(NSString *fileName) {
+ NSString *fullFileName = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents"];
+ fullFileName = [fullFileName stringByAppendingString:fileName];
+ NSLog(@"fullFileName is: %@", fullFileName);
+ if ([[NSFileManager defaultManager] fileExistsAtPath:fullFileName]) {
+ NSLog(@"fullFileName exists: %@", fullFileName);
+ } else{
+ fullFileName = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:fileName];
+ NSLog(@"fullFileName exists: %@", fullFileName);
+ }
+ return fullFileName;
}
+
NSString *getVMOptionsFilePath() {
return [getPreferencesFolderPath() stringByAppendingString:@"/idea.vmoptions"];
}
@@ -237,7 +250,8 @@ NSString *getVMOptionsFilePath() {
NSArray *parseVMOptions() {
NSArray *inConfig=[VMOptionsReader readFile:getVMOptionsFilePath()];
if (inConfig) return inConfig;
- return [VMOptionsReader readFile:getDefaultVMOptionsFilePath()];
+ //return [VMOptionsReader readFile:getDefaultVMOptionsFilePath()];
+ return [VMOptionsReader readFile:getDefaultFilePath(@"/bin/idea.vmoptions")];
}
NSDictionary *parseProperties() {
diff --git a/native/fsNotifier/mac/fsnotifier.c b/native/fsNotifier/mac/fsnotifier.c
index 1f774c40c489..45c383a9fcce 100644
--- a/native/fsNotifier/mac/fsnotifier.c
+++ b/native/fsNotifier/mac/fsnotifier.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,6 +16,8 @@
#include <CoreServices/CoreServices.h>
#include <pthread.h>
+#include <stdio.h>
+#include <strings.h>
#include <sys/mount.h>
#define PRIVATE_DIR "/private/"
@@ -25,7 +27,7 @@ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static bool report_private = true;
static void reportEvent(char *event, char *path) {
- int len = 0;
+ size_t len = 0;
if (path != NULL) {
len = strlen(path);
for (char* p = path; *p != '\0'; p++) {
@@ -36,7 +38,7 @@ static void reportEvent(char *event, char *path) {
}
pthread_mutex_lock(&lock);
- if (report_private || strncasecmp(path, PRIVATE_DIR, PRIVATE_LEN) != 0) {
+ if (path == NULL || report_private || strncasecmp(path, PRIVATE_DIR, PRIVATE_LEN) != 0) {
fputs(event, stdout);
fputc('\n', stdout);
if (path != NULL) {
@@ -84,7 +86,7 @@ static void PrintMountedFileSystems(CFArrayRef roots) {
if (fsCount == -1) return;
struct statfs fs[fsCount];
- fsCount = getfsstat(fs, sizeof(struct statfs) * fsCount, MNT_NOWAIT);
+ fsCount = getfsstat(fs, (int)(sizeof(struct statfs) * fsCount), MNT_NOWAIT);
if (fsCount == -1) return;
CFMutableArrayRef mounts = CFArrayCreateMutable(NULL, 0, NULL);
@@ -92,11 +94,11 @@ static void PrintMountedFileSystems(CFArrayRef roots) {
for (int i = 0; i < fsCount; i++) {
if ((fs[i].f_flags & MNT_LOCAL) != MNT_LOCAL) {
char *mount = fs[i].f_mntonname;
- int mountLen = strlen(mount);
+ size_t mountLen = strlen(mount);
for (int j = 0; j < CFArrayGetCount(roots); j++) {
char *root = (char *)CFArrayGetValueAtIndex(roots, j);
- int rootLen = strlen(root);
+ size_t rootLen = strlen(root);
if (rootLen >= mountLen && strncmp(root, mount, mountLen) == 0) {
// root under mount point
diff --git a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
index dac770921aa5..f1255edc01f6 100644
--- a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
+++ b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
@@ -38,6 +38,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopesCore;
@@ -239,6 +240,29 @@ public class AnalysisScope {
myFilesSet = new HashSet<VirtualFile>();
accept(createFileSearcher());
}
+ else if (myType == VIRTUAL_FILES) {
+ final HashSet<VirtualFile> files = new HashSet<VirtualFile>();
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+ for (Iterator<VirtualFile> iterator = myFilesSet.iterator(); iterator.hasNext(); ) {
+ final VirtualFile vFile = iterator.next();
+ VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor() {
+ @NotNull
+ @Override
+ public Result visitFileEx(@NotNull VirtualFile file) {
+ boolean ignored = fileIndex.isIgnored(file);
+ if (!ignored && !file.isDirectory()) {
+ files.add(file);
+ }
+ return ignored ? SKIP_CHILDREN : CONTINUE;
+ }
+ });
+
+ if (vFile.isDirectory()) {
+ iterator.remove();
+ }
+ }
+ myFilesSet.addAll(files);
+ }
}
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
index 0b8d36431d54..8d0f1da9d024 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
@@ -16,17 +16,23 @@
package com.intellij.codeInspection;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import com.intellij.util.ResourceUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.SerializationFilter;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializationException;
import com.intellij.util.xmlb.XmlSerializer;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectHashingStrategy;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
@@ -38,15 +44,14 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
-import java.util.Collection;
-import java.util.Set;
+import java.util.*;
/**
* @author anna
* @since 28-Nov-2005
*/
@SuppressWarnings("JavadocReference")
-public abstract class InspectionProfileEntry {
+public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name");
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry");
@@ -56,6 +61,77 @@ public abstract class InspectionProfileEntry {
private static final Object BLACK_LIST_LOCK = new Object();
private Boolean myUseNewSerializer = null;
+ @NonNls
+ @Nullable
+ public String getAlternativeID() {
+ return null;
+ }
+
+ @Override
+ public boolean isSuppressedFor(@NotNull PsiElement element) {
+ Set<InspectionSuppressor> suppressors = getSuppressors(element);
+ for (InspectionSuppressor suppressor : suppressors) {
+ if (suppressor != null && isSuppressed(suppressor, element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected String getSuppressId() {
+ return getShortName();
+ }
+
+ @NotNull
+ @Override
+ public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
+ if (element != null) {
+ THashSet<SuppressQuickFix> fixes = new THashSet<SuppressQuickFix>(new TObjectHashingStrategy<SuppressQuickFix>() {
+ @Override
+ public int computeHashCode(SuppressQuickFix object) {
+ return object.getName().hashCode();
+ }
+
+ @Override
+ public boolean equals(SuppressQuickFix o1, SuppressQuickFix o2) {
+ return o1.getName().equals(o2.getName());
+ }
+ });
+ Set<InspectionSuppressor> suppressors = getSuppressors(element);
+ for (InspectionSuppressor suppressor : suppressors) {
+ if (suppressor != null) {
+ SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
+ fixes.addAll(Arrays.asList(actions));
+ }
+ }
+ return fixes.toArray(new SuppressQuickFix[fixes.size()]);
+ }
+ return SuppressQuickFix.EMPTY_ARRAY;
+ }
+
+ private boolean isSuppressed(@Nullable InspectionSuppressor suppressor, @NotNull PsiElement element) {
+ if (suppressor == null) return false;
+ String toolId = getSuppressId();
+ if (suppressor.isSuppressedFor(element, toolId)) {
+ return true;
+ }
+ final String alternativeId = getAlternativeID();
+ return alternativeId != null && !alternativeId.equals(toolId) && suppressor.isSuppressedFor(element, alternativeId);
+ }
+
+ private static Set<InspectionSuppressor> getSuppressors(@NotNull PsiElement element) {
+ FileViewProvider viewProvider = element.getContainingFile().getViewProvider();
+ if (viewProvider instanceof TemplateLanguageFileViewProvider) {
+ LinkedHashSet<InspectionSuppressor> suppressors = new LinkedHashSet<InspectionSuppressor>();
+ ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(viewProvider.getBaseLanguage()));
+ for (Language language : viewProvider.getLanguages()) {
+ ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(language));
+ }
+ return suppressors;
+ }
+ return Collections.singleton(LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()));
+ }
+
public void cleanup(Project project) {
}
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionSuppressor.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionSuppressor.java
new file mode 100644
index 000000000000..94cd5483b291
--- /dev/null
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionSuppressor.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public interface InspectionSuppressor {
+ /**
+ * @see com.intellij.codeInspection.CustomSuppressableInspectionTool#isSuppressedFor(com.intellij.psi.PsiElement)
+ */
+ boolean isSuppressedFor(@NotNull PsiElement element, String toolId);
+
+ /**
+ * @see com.intellij.codeInspection.BatchSuppressableTool#getBatchSuppressActions(com.intellij.psi.PsiElement)
+ */
+ SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, String toolShortName);
+}
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/LanguageInspectionSuppressors.java b/platform/analysis-api/src/com/intellij/codeInspection/LanguageInspectionSuppressors.java
new file mode 100644
index 000000000000..52772416dfca
--- /dev/null
+++ b/platform/analysis-api/src/com/intellij/codeInspection/LanguageInspectionSuppressors.java
@@ -0,0 +1,12 @@
+package com.intellij.codeInspection;
+
+import com.intellij.lang.LanguageExtension;
+
+public class LanguageInspectionSuppressors extends LanguageExtension<InspectionSuppressor> {
+ public static final LanguageInspectionSuppressors INSTANCE = new LanguageInspectionSuppressors();
+
+ private LanguageInspectionSuppressors() {
+ super("com.intellij.lang.inspectionSuppressor");
+ }
+
+} \ No newline at end of file
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
index db7d8c4bd806..b4cba852eba2 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/LocalInspectionTool.java
@@ -71,6 +71,11 @@ public abstract class LocalInspectionTool extends InspectionProfileEntry {
return getShortName();
}
+ @Override
+ protected String getSuppressId() {
+ return getID();
+ }
+
@NonNls
@Nullable
public String getAlternativeID() {
diff --git a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
index 072e12114bc6..647cd728c6ac 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
@@ -82,6 +82,7 @@ public class GlobalSearchScopesCore {
return false;
}
+ @NotNull
@Override
public String getDisplayName() {
return mySet.getName();
@@ -137,6 +138,7 @@ public class GlobalSearchScopesCore {
return false;
}
+ @NotNull
@Override
public String getDisplayName() {
return PsiBundle.message("psi.search.scope.production.files");
@@ -176,6 +178,7 @@ public class GlobalSearchScopesCore {
return false;
}
+ @NotNull
@Override
public String getDisplayName() {
return PsiBundle.message("psi.search.scope.test.files");
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java
index 471f0e10ff09..0bb406f23545 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/FileStatusMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -90,6 +90,13 @@ public class FileStatusMap implements Disposable {
}
}
+ public boolean isMarkedDirtyDefensively(@NotNull Document document) {
+ synchronized(myDocumentToStatusMap) {
+ FileStatus status = myDocumentToStatusMap.get(document);
+ return status != null && status.defensivelyMarked;
+ }
+ }
+
private static class FileStatus {
public boolean defensivelyMarked; // file marked dirty without knowledge of specific dirty region. Subsequent markScopeDirty can refine dirty scope, not extend it
private boolean wolfPassFinished;
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
index aae907de0bc1..483f3c5b2839 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
@@ -835,16 +835,18 @@ public class HighlightInfo implements Segment {
if (suppressActions != null) {
ContainerUtil.addAll(newOptions, suppressActions);
}
+ } else {
+ SuppressQuickFix[] suppressFixes = wrappedTool.getBatchSuppressActions(element);
+ if (suppressFixes.length > 0) {
+ ContainerUtil.addAll(newOptions, ContainerUtil.map(suppressFixes, new Function<SuppressQuickFix, IntentionAction>() {
+ @Override
+ public IntentionAction fun(SuppressQuickFix fix) {
+ return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
+ }
+ }));
+ }
}
- if (wrappedTool instanceof BatchSuppressableTool) {
- final SuppressQuickFix[] suppressActions = ((BatchSuppressableTool)wrappedTool).getBatchSuppressActions(element);
- ContainerUtil.addAll(newOptions, ContainerUtil.map(suppressActions, new Function<SuppressQuickFix, IntentionAction>() {
- @Override
- public IntentionAction fun(SuppressQuickFix fix) {
- return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
- }
- }));
- }
+
}
if (myProblemGroup instanceof SuppressableProblemGroup) {
final IntentionAction[] suppressActions = ((SuppressableProblemGroup)myProblemGroup).getSuppressActions(element);
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressionUtil.java b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressionUtil.java
index 51ec4bbc2a1a..4f1de6622a1f 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/SuppressionUtil.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/SuppressionUtil.java
@@ -194,18 +194,6 @@ public class SuppressionUtil extends SuppressionUtilCore {
}
public static boolean inspectionResultSuppressed(@NotNull PsiElement place, @NotNull LocalInspectionTool tool) {
- if (tool instanceof CustomSuppressableInspectionTool) {
- return ((CustomSuppressableInspectionTool)tool).isSuppressedFor(place);
- }
- if (tool instanceof BatchSuppressableTool) {
- return ((BatchSuppressableTool)tool).isSuppressedFor(place);
- }
- String alternativeId;
- String id;
-
- return isSuppressed(place, id = tool.getID()) ||
- (alternativeId = tool.getAlternativeID()) != null &&
- !alternativeId.equals(id) &&
- isSuppressed(place, alternativeId);
+ return tool.isSuppressedFor(place);
}
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
index c417f72e5b34..0fbd048f4929 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtilCore;
import com.intellij.openapi.util.Computable;
@@ -84,7 +85,7 @@ public class RefManagerImpl extends RefManager {
private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock();
- public RefManagerImpl(@NotNull Project project, AnalysisScope scope, @NotNull GlobalInspectionContext context) {
+ public RefManagerImpl(@NotNull Project project, @Nullable AnalysisScope scope, @NotNull GlobalInspectionContext context) {
myDeclarationsFound = false;
myProject = project;
myScope = scope;
@@ -99,6 +100,14 @@ public class RefManagerImpl extends RefManager {
myLanguageExtensions.put(extension.getLanguage(), extension);
}
}
+ if (scope != null) {
+ for (Module module : ModuleManager.getInstance(getProject()).getModules()) {
+ //init all ref modules in scope
+ if (scope.containsModule(module)) {
+ getRefModule(module);
+ }
+ }
+ }
}
@NotNull
@@ -294,7 +303,8 @@ public class RefManagerImpl extends RefManager {
public void findAllDeclarations() {
if (!myDeclarationsFound) {
long before = System.currentTimeMillis();
- getScope().accept(myProjectIterator);
+ final AnalysisScope scope = getScope();
+ scope.accept(myProjectIterator);
myDeclarationsFound = true;
LOG.info("Total duration of processing project usages:" + (System.currentTimeMillis() - before));
@@ -559,15 +569,31 @@ public class RefManagerImpl extends RefManager {
if (module == null) {
return null;
}
- if (myModules == null) {
- myModules = new THashMap<Module, RefModule>();
+ myLock.readLock().lock();
+ try {
+ if (myModules != null) {
+ RefModule refModule = myModules.get(module);
+ if (refModule != null) {
+ return refModule;
+ }
+ }
+ }
+ finally {
+ myLock.readLock().unlock();
}
- RefModule refModule = myModules.get(module);
- if (refModule == null) {
- refModule = new RefModuleImpl(module, this);
+
+ myLock.writeLock().lock();
+ try {
+ if (myModules == null) {
+ myModules = new THashMap<Module, RefModule>();
+ }
+ final RefModule refModule = new RefModuleImpl(module, this);
myModules.put(module, refModule);
+ return refModule;
+ }
+ finally {
+ myLock.writeLock().unlock();
}
- return refModule;
}
@Override
diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java
index 05cbe635cf7d..fd72b556b709 100755
--- a/platform/bootstrap/src/com/intellij/idea/Main.java
+++ b/platform/bootstrap/src/com/intellij/idea/Main.java
@@ -31,6 +31,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
+import java.util.Locale;
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "MethodNamesDifferingOnlyByCase"})
@@ -133,7 +134,7 @@ public class Main {
private static void installPatch() throws IOException {
String platform = System.getProperty(PLATFORM_PREFIX_PROPERTY, "idea");
- String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase();
+ String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase(Locale.US);
String tempDir = System.getProperty("java.io.tmpdir");
// always delete previous patch copy
@@ -165,6 +166,7 @@ public class Main {
args.add(Restarter.createTempExecutable(launcher).getPath());
}
+ //noinspection SpellCheckingInspection
Collections.addAll(args,
System.getProperty("java.home") + "/bin/java".replace('/', File.separatorChar),
"-Xmx500m",
diff --git a/platform/core-api/src/com/intellij/concurrency/JobScheduler.java b/platform/core-api/src/com/intellij/concurrency/JobScheduler.java
index 850c868a67ec..a7e16644363c 100644
--- a/platform/core-api/src/com/intellij/concurrency/JobScheduler.java
+++ b/platform/core-api/src/com/intellij/concurrency/JobScheduler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -70,11 +70,11 @@ public abstract class JobScheduler {
private static Object info(Runnable r) {
if (!(r instanceof FutureTask)) return r;
- Object sync = ReflectionUtil.getField(FutureTask.class, r, Object.class, "sync"); // FutureTask.sync in <=JDK7
+ Object sync = ReflectionUtil.getField(FutureTask.class, r, null, "sync"); // FutureTask.sync in <=JDK7
Object o = sync == null ? r : sync;
Object callable = ReflectionUtil.getField(o.getClass(), o, Callable.class, "callable"); // FutureTask.callable or Sync.callable
if (callable == null) return null;
- Object task = ReflectionUtil.getField(callable.getClass(), callable, Object.class, "task"); // java.util.concurrent.Executors.RunnableAdapter.task
+ Object task = ReflectionUtil.getField(callable.getClass(), callable, null, "task"); // java.util.concurrent.Executors.RunnableAdapter.task
return task == null ? callable : task;
}
diff --git a/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java b/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java
index 067badf894bb..406e4745d771 100644
--- a/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java
+++ b/platform/core-api/src/com/intellij/lang/folding/CompositeFoldingBuilder.java
@@ -22,11 +22,13 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
/**
* Used by LanguageFolding class if more than one FoldingBuilder were specified
@@ -52,11 +54,14 @@ public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAwa
@NotNull
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
final List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
+ final Set<TextRange> rangesCoveredByDescriptors = ContainerUtil.newHashSet();
for (FoldingBuilder builder : myBuilders) {
for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(builder, root, document, quick)) {
- descriptor.getElement().putUserData(FOLDING_BUILDER, builder);
- descriptors.add(descriptor);
+ if (rangesCoveredByDescriptors.add(descriptor.getRange())) {
+ descriptor.getElement().putUserData(FOLDING_BUILDER, builder);
+ descriptors.add(descriptor);
+ }
}
}
diff --git a/platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java b/platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java
index b0ad393bec35..21c866325dcf 100644
--- a/platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java
+++ b/platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java
@@ -18,7 +18,6 @@ package com.intellij.lang.folding;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.FoldingGroup;
-import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.ObjectUtils;
@@ -94,12 +93,11 @@ public class FoldingDescriptor {
@Nullable FoldingGroup group,
Set<Object> dependencies,
boolean neverExpands) {
- assert range.getStartOffset() + 1 < range.getEndOffset() : range + ", text: " + node.getText() + ", language = " + node.getPsi().getLanguage();
+ assert range.getLength() > 0 : range + ", text: " + node.getText() + ", language = " + node.getPsi().getLanguage();
myElement = node;
- ProperTextRange.assertProperRange(range);
+ TextRange.assertProperRange(range);
myRange = range;
myGroup = group;
- assert getRange().getLength() >= 2 : "range:" + getRange();
myDependencies = dependencies;
assert !myDependencies.contains(null);
myNeverExpands = neverExpands;
diff --git a/platform/core-api/src/com/intellij/openapi/application/CachedSingletonsRegistry.java b/platform/core-api/src/com/intellij/openapi/application/CachedSingletonsRegistry.java
index 8e392189c003..7a9b73138a0f 100644
--- a/platform/core-api/src/com/intellij/openapi/application/CachedSingletonsRegistry.java
+++ b/platform/core-api/src/com/intellij/openapi/application/CachedSingletonsRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,10 +19,10 @@
*/
package com.intellij.openapi.application;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@@ -54,8 +54,6 @@ public class CachedSingletonsRegistry {
}
private static void cleanupClass(Class<?> aClass) throws Exception {
- Field field = aClass.getDeclaredField("ourInstance");
- field.setAccessible(true);
- field.set(null, null);
+ ReflectionUtil.resetField(aClass, null, "ourInstance");
}
}
diff --git a/platform/core-api/src/com/intellij/openapi/progress/Task.java b/platform/core-api/src/com/intellij/openapi/progress/Task.java
index 835076f66f09..47b3375e9071 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/Task.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/Task.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -189,6 +189,7 @@ public abstract class Task implements TaskInfo, Progressive {
return false;
}
+ @NotNull
public DumbModeAction getDumbModeAction() {
return DumbModeAction.NOTHING;
}
diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbModeTask.java b/platform/core-api/src/com/intellij/openapi/project/DumbModeTask.java
index 360e7626669b..56fab1229f48 100644
--- a/platform/core-api/src/com/intellij/openapi/project/DumbModeTask.java
+++ b/platform/core-api/src/com/intellij/openapi/project/DumbModeTask.java
@@ -15,14 +15,18 @@
*/
package com.intellij.openapi.project;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
-public abstract class DumbModeTask {
+public abstract class DumbModeTask implements Disposable {
public abstract void performInDumbMode(@NotNull ProgressIndicator indicator);
+ @Override
+ public void dispose() {
+ }
}
diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbService.java b/platform/core-api/src/com/intellij/openapi/project/DumbService.java
index a690091518e9..ad5c36a5d3e2 100644
--- a/platform/core-api/src/com/intellij/openapi/project/DumbService.java
+++ b/platform/core-api/src/com/intellij/openapi/project/DumbService.java
@@ -176,7 +176,9 @@ public abstract class DumbService {
return new ArrayList<T>(collection);
}
- public abstract void queueTask(DumbModeTask task);
+ public abstract void queueTask(@NotNull DumbModeTask task);
+
+ public abstract void cancelTask(@NotNull DumbModeTask task);
public abstract JComponent wrapGently(@NotNull JComponent dumbUnawareContent, @NotNull Disposable parentDisposable);
diff --git a/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java b/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java
index 65641580d05b..cc3810d90bb6 100644
--- a/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java
+++ b/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java
@@ -190,7 +190,7 @@ public class ActionCallback implements Disposable {
@NotNull
public ActionCallback create() {
- if (myCallbacks.isEmpty()) {
+ if (isEmpty()) {
return DONE;
}
@@ -202,6 +202,14 @@ public class ActionCallback implements Disposable {
return result;
}
+ public boolean isEmpty() {
+ return myCallbacks.isEmpty();
+ }
+
+ public int getSize() {
+ return myCallbacks.size();
+ }
+
@NotNull
public ActionCallback getWhenProcessed() {
final ActionCallback result = new ActionCallback(myCallbacks.size());
diff --git a/platform/core-api/src/com/intellij/openapi/util/AsyncResult.java b/platform/core-api/src/com/intellij/openapi/util/AsyncResult.java
index b517d96c0bda..2d0a4a834fe0 100644
--- a/platform/core-api/src/com/intellij/openapi/util/AsyncResult.java
+++ b/platform/core-api/src/com/intellij/openapi/util/AsyncResult.java
@@ -33,6 +33,15 @@ public class AsyncResult<T> extends ActionCallback {
protected T myResult;
+ public AsyncResult() {
+ }
+
+ AsyncResult(int countToDone, @Nullable T result) {
+ super(countToDone);
+
+ myResult = result;
+ }
+
@NotNull
public AsyncResult<T> setDone(T result) {
myResult = result;
diff --git a/platform/core-api/src/com/intellij/openapi/util/CollectingAsyncResult.java b/platform/core-api/src/com/intellij/openapi/util/CollectingAsyncResult.java
new file mode 100644
index 000000000000..3d22b169d224
--- /dev/null
+++ b/platform/core-api/src/com/intellij/openapi/util/CollectingAsyncResult.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util;
+
+import com.intellij.util.Consumer;
+import com.intellij.util.SmartList;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Please note - rejected results are not collected.
+ */
+public final class CollectingAsyncResult<T> {
+ private final List<AsyncResult<T>> asyncResults = new SmartList<AsyncResult<T>>();
+
+ public void add(@NotNull AsyncResult<T> callback) {
+ asyncResults.add(callback);
+ }
+
+ @NotNull
+ public AsyncResult<List<T>> create() {
+ int size = asyncResults.size();
+ if (size == 0) {
+ return AsyncResult.doneList();
+ }
+
+ final List<T> results = size == 1 ? new SmartList<T>() : new ArrayList<T>(size);
+ final AsyncResult<List<T>> totalResult = new AsyncResult<List<T>>(asyncResults.size(), results);
+ Consumer<T> resultConsumer = new Consumer<T>() {
+ @Override
+ public void consume(T result) {
+ synchronized (results) {
+ results.add(result);
+ }
+ totalResult.setDone();
+ }
+ };
+ for (AsyncResult<T> subResult : asyncResults) {
+ subResult.doWhenDone(resultConsumer).notifyWhenRejected(totalResult);
+ }
+ return totalResult;
+ }
+
+ public boolean isEmpty() {
+ return asyncResults.isEmpty();
+ }
+} \ No newline at end of file
diff --git a/platform/core-api/src/com/intellij/openapi/util/CompositeModificationTracker.java b/platform/core-api/src/com/intellij/openapi/util/CompositeModificationTracker.java
new file mode 100644
index 000000000000..9b35bd3db0f2
--- /dev/null
+++ b/platform/core-api/src/com/intellij/openapi/util/CompositeModificationTracker.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.util;
+
+import org.jetbrains.annotations.NotNull;
+
+public class CompositeModificationTracker extends SimpleModificationTracker {
+ @NotNull private final ModificationTracker myAdditionalTracker;
+
+ public CompositeModificationTracker(@NotNull ModificationTracker tracker) {
+ myAdditionalTracker = tracker;
+ }
+
+ @Override
+ public long getModificationCount() {
+ return super.getModificationCount() + myAdditionalTracker.getModificationCount();
+ }
+}
diff --git a/platform/core-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java b/platform/core-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java
index d6e2aee74ac7..071a37e5bdbe 100644
--- a/platform/core-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java
+++ b/platform/core-api/src/com/intellij/openapi/util/KeyedExtensionCollector.java
@@ -51,7 +51,7 @@ public class KeyedExtensionCollector<T, KeyT> {
public KeyedExtensionCollector(@NonNls @NotNull String epName) {
myEpName = epName;
- lock = new String("lock for KeyedExtensionCollector " + epName);
+ lock = "lock for KeyedExtensionCollector " + epName;
resetAreaListener();
}
@@ -181,47 +181,45 @@ public class KeyedExtensionCollector<T, KeyT> {
@Nullable
private ExtensionPoint<KeyedLazyInstance<T>> getPoint() {
ExtensionPoint<KeyedLazyInstance<T>> point = myPoint;
- if (point == null) {
- if (Extensions.getRootArea().hasExtensionPoint(myEpName)) {
- ExtensionPointName<KeyedLazyInstance<T>> typesafe = ExtensionPointName.create(myEpName);
- myPoint = point = Extensions.getRootArea().getExtensionPoint(typesafe);
- myListener = new ExtensionPointAndAreaListener<KeyedLazyInstance<T>>() {
- @Override
- public void extensionAdded(@NotNull final KeyedLazyInstance<T> bean, @Nullable final PluginDescriptor pluginDescriptor) {
- synchronized (lock) {
- if (bean.getKey() == null) {
- if (pluginDescriptor != null) {
- throw new PluginException("No key specified for extension of class " + bean.getInstance().getClass(),
- pluginDescriptor.getPluginId());
- }
- LOG.error("No key specified for extension of class " + bean.getInstance().getClass());
- return;
- }
- myCache.remove(bean.getKey());
- for (ExtensionPointListener<T> listener : myListeners) {
- listener.extensionAdded(bean.getInstance(), null);
+ if (point == null && Extensions.getRootArea().hasExtensionPoint(myEpName)) {
+ ExtensionPointName<KeyedLazyInstance<T>> typesafe = ExtensionPointName.create(myEpName);
+ myPoint = point = Extensions.getRootArea().getExtensionPoint(typesafe);
+ myListener = new ExtensionPointAndAreaListener<KeyedLazyInstance<T>>() {
+ @Override
+ public void extensionAdded(@NotNull final KeyedLazyInstance<T> bean, @Nullable final PluginDescriptor pluginDescriptor) {
+ synchronized (lock) {
+ if (bean.getKey() == null) {
+ if (pluginDescriptor != null) {
+ throw new PluginException("No key specified for extension of class " + bean.getInstance().getClass(),
+ pluginDescriptor.getPluginId());
}
+ LOG.error("No key specified for extension of class " + bean.getInstance().getClass());
+ return;
+ }
+ myCache.remove(bean.getKey());
+ for (ExtensionPointListener<T> listener : myListeners) {
+ listener.extensionAdded(bean.getInstance(), null);
}
}
+ }
- @Override
- public void extensionRemoved(@NotNull final KeyedLazyInstance<T> bean, @Nullable final PluginDescriptor pluginDescriptor) {
- synchronized (lock) {
- myCache.remove(bean.getKey());
- for (ExtensionPointListener<T> listener : myListeners) {
- listener.extensionRemoved(bean.getInstance(), null);
- }
+ @Override
+ public void extensionRemoved(@NotNull final KeyedLazyInstance<T> bean, @Nullable final PluginDescriptor pluginDescriptor) {
+ synchronized (lock) {
+ myCache.remove(bean.getKey());
+ for (ExtensionPointListener<T> listener : myListeners) {
+ listener.extensionRemoved(bean.getInstance(), null);
}
}
+ }
- @Override
- public void areaReplaced(final ExtensionsArea area) {
- resetAreaListener();
- }
- };
+ @Override
+ public void areaReplaced(final ExtensionsArea area) {
+ resetAreaListener();
+ }
+ };
- point.addExtensionPointListener(myListener);
- }
+ point.addExtensionPointListener(myListener);
}
return point;
}
diff --git a/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java b/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java
index 06d8fcc6e1a9..5232dc439b90 100644
--- a/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java
+++ b/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java
@@ -15,18 +15,29 @@
*/
package com.intellij.openapi.util;
+import com.intellij.Patches;
+
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
/**
* Created by Max Medvedev on 28/03/14
*/
public class SimpleModificationTracker implements ModificationTracker {
- private long myCounter;
+ static {
+ // field made public to workaround bug in JDK7 when AtomicIntegerFieldUpdater can't be created for private field, even from within its own class
+ // fixed in JDK8
+ assert Patches.JDK_BUG_ID_7103570;
+ }
+ public volatile int myCounter;
@Override
public long getModificationCount() {
return myCounter;
}
+ private static final AtomicIntegerFieldUpdater<SimpleModificationTracker> UPDATER = AtomicIntegerFieldUpdater.newUpdater(SimpleModificationTracker.class, "myCounter");
+
public void incModificationCount() {
- myCounter++;
+ UPDATER.incrementAndGet(this);
}
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/InvalidVirtualFileAccessException.java b/platform/core-api/src/com/intellij/openapi/vfs/InvalidVirtualFileAccessException.java
index 7c67ea422a23..53502f99bfed 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/InvalidVirtualFileAccessException.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/InvalidVirtualFileAccessException.java
@@ -23,6 +23,10 @@ public class InvalidVirtualFileAccessException extends RuntimeException {
super(composeMessage(file));
}
+ public InvalidVirtualFileAccessException(String message) {
+ super(message);
+ }
+
private static String composeMessage(VirtualFile file) {
String url = file.getUrl();
String message = "Accessing invalid virtual file: " + url;
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
index bd4c9212aa74..cd0f15f3796c 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
@@ -129,7 +129,7 @@ public class VfsUtilCore {
if (length > 0) {
length++;
}
- length += parent.getName().length();
+ length += parent.getNameSequence().length();
parent = parent.getParent();
}
@@ -141,7 +141,7 @@ public class VfsUtilCore {
if (index < length) {
chars[--index] = separator;
}
- String name = parent.getName();
+ CharSequence name = parent.getNameSequence();
for (int i = name.length() - 1; i >= 0; i--) {
chars[--index] = name.charAt(i);
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
index 0725d7a1ea0e..e4c3e5c502f5 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
@@ -31,9 +31,12 @@ import java.io.OutputStream;
import java.nio.charset.Charset;
/**
- * Represents a file in <code>{@link VirtualFileSystem}</code>. A particular file is represented by the same
- * <code>VirtualFile</code> instance for the entire lifetime of the IntelliJ IDEA process, unless the file
- * is deleted, in which case {@link #isValid()} for the instance will return <code>false</code>.
+ * Represents a file in <code>{@link VirtualFileSystem}</code>. A particular file is represented by equal
+ * <code>VirtualFile</code> instances for the entire lifetime of the IntelliJ IDEA process, unless the file
+ * is deleted, in which case {@link #isValid()} will return <code>false</code>.
+ * <p/>
+ * VirtualFile instances are created on request, so there can be several instances corresponding to the same file.
+ * All of them are equal, have the same hashCode and use shared storage for all related data, including user data (see {@link com.intellij.openapi.util.UserDataHolder}).
* <p/>
* If an in-memory implementation of VirtualFile is required, {@link com.intellij.testFramework.LightVirtualFile}
* can be used.
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/impl/ArchiveHandler.java b/platform/core-api/src/com/intellij/openapi/vfs/impl/ArchiveHandler.java
index 835208afe64c..33e857cf3de9 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/impl/ArchiveHandler.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/impl/ArchiveHandler.java
@@ -110,7 +110,7 @@ public abstract class ArchiveHandler {
}
else {
try {
- map = createEntriesMap();
+ map = Collections.unmodifiableMap(createEntriesMap());
}
catch (IOException e) {
myCorrupted = true;
@@ -119,7 +119,7 @@ public abstract class ArchiveHandler {
}
}
- myEntries = new SoftReference<Map<String, EntryInfo>>(Collections.unmodifiableMap(map));
+ myEntries = new SoftReference<Map<String, EntryInfo>>(map);
}
}
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileContentChangeEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileContentChangeEvent.java
index cc1614c16ecd..3c9dbb6c6bdd 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileContentChangeEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileContentChangeEvent.java
@@ -60,6 +60,7 @@ public class VFileContentChangeEvent extends VFileEvent {
return "VfsEvent[update: " + myFile.getUrl() + "]";
}
+ @NotNull
@Override
public String getPath() {
return myFile.getPath();
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCopyEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCopyEvent.java
index 50ac2c99cc51..5ea519067db8 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCopyEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCopyEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -29,7 +29,7 @@ public class VFileCopyEvent extends VFileEvent {
private final VirtualFile myNewParent;
private final String myNewChildName;
- public VFileCopyEvent(final Object requestor, final VirtualFile file, final VirtualFile newParent, final String newChildName) {
+ public VFileCopyEvent(final Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent, @NotNull String newChildName) {
super(requestor, false);
myFile = file;
myNewParent = newParent;
@@ -37,23 +37,28 @@ public class VFileCopyEvent extends VFileEvent {
}
@Override
+ @NotNull
public VirtualFile getFile() {
return myFile;
}
+ @NotNull
public VirtualFile getNewParent() {
return myNewParent;
}
+ @NotNull
public String getNewChildName() {
return myNewChildName;
}
+ @Override
@NonNls
public String toString() {
return "VfsEvent[copy " + myFile +" to " + myNewParent + " as " + myNewChildName +"]";
}
+ @NotNull
@Override
public String getPath() {
return myNewParent.getPath() + "/" + myNewChildName;
@@ -70,6 +75,7 @@ public class VFileCopyEvent extends VFileEvent {
return myFile.isValid() && myNewParent.findChild(myNewChildName) == null;
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -83,9 +89,9 @@ public class VFileCopyEvent extends VFileEvent {
return true;
}
+ @Override
public int hashCode() {
- int result;
- result = myFile.hashCode();
+ int result = myFile.hashCode();
result = 31 * result + myNewParent.hashCode();
result = 31 * result + myNewChildName.hashCode();
return result;
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java
index e3a9b9040e32..c730b9b9fe6b 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileCreateEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -24,9 +24,9 @@ import org.jetbrains.annotations.NotNull;
* @author max
*/
public class VFileCreateEvent extends VFileEvent {
- private final VirtualFile myParent;
+ @NotNull private final VirtualFile myParent;
private final boolean myDirectory;
- private final String myChildName;
+ @NotNull private final String myChildName;
private final boolean myReCreation;
private VirtualFile myCreatedFile;
@@ -51,6 +51,7 @@ public class VFileCreateEvent extends VFileEvent {
myReCreation = isReCreation;
}
+ @NotNull
public String getChildName() {
return myChildName;
}
@@ -59,6 +60,7 @@ public class VFileCreateEvent extends VFileEvent {
return myDirectory;
}
+ @NotNull
public VirtualFile getParent() {
return myParent;
}
@@ -74,6 +76,7 @@ public class VFileCreateEvent extends VFileEvent {
myChildName + " in " + myParent.getUrl() + "]";
}
+ @NotNull
@Override
public String getPath() {
return myParent.getPath() + "/" + myChildName;
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileDeleteEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileDeleteEvent.java
index 10b03e082575..f1ed38a12e9b 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileDeleteEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileDeleteEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -40,11 +40,13 @@ public class VFileDeleteEvent extends VFileEvent {
return myFile;
}
+ @Override
@NonNls
public String toString() {
return "VfsEvent[deleted: " + myFile.getUrl() + "]";
}
+ @NotNull
@Override
public String getPath() {
return myFile.getPath();
@@ -61,6 +63,7 @@ public class VFileDeleteEvent extends VFileEvent {
return myFile.isValid();
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -70,6 +73,7 @@ public class VFileDeleteEvent extends VFileEvent {
return myFile.equals(event.myFile);
}
+ @Override
public int hashCode() {
return myFile.hashCode();
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileEvent.java
index 3e931a588d7d..22eb1f3a3fb8 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -41,6 +41,7 @@ public abstract class VFileEvent {
return myRequestor;
}
+ @NotNull
public abstract String getPath();
/**
@@ -58,6 +59,8 @@ public abstract class VFileEvent {
public abstract boolean isValid();
+ @Override
public abstract int hashCode();
+ @Override
public abstract boolean equals(Object o);
}
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileMoveEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileMoveEvent.java
index 42ff9d42d8a0..dd145f88bc69 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileMoveEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFileMoveEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +30,7 @@ public class VFileMoveEvent extends VFileEvent {
private final VirtualFile myOldParent;
private final VirtualFile myNewParent;
- public VFileMoveEvent(final Object requestor, @NotNull final VirtualFile file, final VirtualFile newParent) {
+ public VFileMoveEvent(final Object requestor, @NotNull VirtualFile file, @NotNull VirtualFile newParent) {
super(requestor, false);
myFile = file;
myNewParent = newParent;
@@ -43,6 +43,7 @@ public class VFileMoveEvent extends VFileEvent {
return myFile;
}
+ @NotNull
public VirtualFile getNewParent() {
return myNewParent;
}
@@ -51,11 +52,13 @@ public class VFileMoveEvent extends VFileEvent {
return myOldParent;
}
+ @Override
@NonNls
public String toString() {
return "VfsEvent[move " + myFile.getName() +" from " + myOldParent + " to " + myNewParent + "]";
}
+ @NotNull
@Override
public String getPath() {
return myFile.getPath();
@@ -72,6 +75,7 @@ public class VFileMoveEvent extends VFileEvent {
return myFile.isValid() && Comparing.equal(myFile.getParent(), myOldParent) && myOldParent.isValid();
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -85,9 +89,9 @@ public class VFileMoveEvent extends VFileEvent {
return true;
}
+ @Override
public int hashCode() {
- int result;
- result = myFile.hashCode();
+ int result = myFile.hashCode();
result = 31 * result + myOldParent.hashCode();
result = 31 * result + myNewParent.hashCode();
return result;
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFilePropertyChangeEvent.java b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFilePropertyChangeEvent.java
index 360ce833a28b..90d10a76d3a8 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFilePropertyChangeEvent.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/newvfs/events/VFilePropertyChangeEvent.java
@@ -91,6 +91,7 @@ public class VFilePropertyChangeEvent extends VFileEvent {
return myPropertyName;
}
+ @NotNull
@Override
public String getPath() {
return myFile.getPath();
@@ -131,6 +132,7 @@ public class VFilePropertyChangeEvent extends VFileEvent {
return result;
}
+ @Override
@NotNull
@NonNls
public String toString() {
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java b/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java
index 8d057b5b1343..f727c1ce9e7d 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/pointers/VirtualFilePointerManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,12 +17,12 @@ package com.intellij.openapi.vfs.pointers;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public abstract class VirtualFilePointerManager implements Disposable, ModificationTracker {
+public abstract class VirtualFilePointerManager extends SimpleModificationTracker implements Disposable {
public static VirtualFilePointerManager getInstance() {
return ServiceManager.getService(VirtualFilePointerManager.class);
}
diff --git a/platform/lang-api/src/com/intellij/patterns/ElementPatternBean.java b/platform/core-api/src/com/intellij/patterns/ElementPatternBean.java
index 354524c9e6fc..26bfae2fb375 100644
--- a/platform/lang-api/src/com/intellij/patterns/ElementPatternBean.java
+++ b/platform/core-api/src/com/intellij/patterns/ElementPatternBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/lang-api/src/com/intellij/patterns/compiler/PatternCompiler.java b/platform/core-api/src/com/intellij/patterns/compiler/PatternCompiler.java
index 628549eb9b38..1de7678a095d 100644
--- a/platform/lang-api/src/com/intellij/patterns/compiler/PatternCompiler.java
+++ b/platform/core-api/src/com/intellij/patterns/compiler/PatternCompiler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/lang-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java b/platform/core-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java
index bf92cfc8f679..df859544cbfe 100644
--- a/platform/lang-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java
+++ b/platform/core-api/src/com/intellij/patterns/compiler/PatternCompilerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-api/src/com/intellij/psi/FileResolveScopeProvider.java b/platform/core-api/src/com/intellij/psi/FileResolveScopeProvider.java
index 966b10728bba..e1fbc72c3709 100644
--- a/platform/core-api/src/com/intellij/psi/FileResolveScopeProvider.java
+++ b/platform/core-api/src/com/intellij/psi/FileResolveScopeProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@
package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
/**
* Implemented by PSI files which must have non-standard resolve scope for elements contained in them.
@@ -24,6 +25,7 @@ import com.intellij.psi.search.GlobalSearchScope;
* @author yole
*/
public interface FileResolveScopeProvider {
+ @NotNull
GlobalSearchScope getFileResolveScope();
boolean ignoreReferencedElementAccessibility();
}
diff --git a/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java b/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java
index 60fdf43dad58..55169f9fb07b 100644
--- a/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java
+++ b/platform/core-api/src/com/intellij/psi/FileViewProviderFactory.java
@@ -26,5 +26,6 @@ import org.jetbrains.annotations.NotNull;
* @author yole
*/
public interface FileViewProviderFactory {
+ @NotNull
FileViewProvider createFileViewProvider(@NotNull VirtualFile file, Language language, @NotNull PsiManager manager, boolean eventSystemEnabled);
} \ No newline at end of file
diff --git a/platform/core-api/src/com/intellij/psi/MultiRangeReference.java b/platform/core-api/src/com/intellij/psi/MultiRangeReference.java
index 1eace6c88c39..feb57c31cae0 100644
--- a/platform/core-api/src/com/intellij/psi/MultiRangeReference.java
+++ b/platform/core-api/src/com/intellij/psi/MultiRangeReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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,9 +20,11 @@
package com.intellij.psi;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface MultiRangeReference extends PsiReference {
+ @NotNull
List<TextRange> getRanges();
}
diff --git a/platform/core-api/src/com/intellij/psi/PackagePrefixFileSystemItem.java b/platform/core-api/src/com/intellij/psi/PackagePrefixFileSystemItem.java
index 0f86473450bc..4ed023e85330 100644
--- a/platform/core-api/src/com/intellij/psi/PackagePrefixFileSystemItem.java
+++ b/platform/core-api/src/com/intellij/psi/PackagePrefixFileSystemItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,10 +15,13 @@
*/
package com.intellij.psi;
+import org.jetbrains.annotations.NotNull;
+
/**
* User: anna
* Date: 7/15/13
*/
public interface PackagePrefixFileSystemItem extends PsiFileSystemItem {
+ @NotNull
PsiDirectory getDirectory();
}
diff --git a/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java b/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java
index 2d9c675464c7..9708eb75ee95 100644
--- a/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java
+++ b/platform/core-api/src/com/intellij/psi/PsiReferenceContributor.java
@@ -1,7 +1,23 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
/**
* Via implementing this extension it's possible to provide references ({@link com.intellij.psi.PsiReference}) to
@@ -28,7 +44,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
public abstract class PsiReferenceContributor implements Disposable {
public static final ExtensionPointName<PsiReferenceContributor> EP_NAME = ExtensionPointName.create("com.intellij.psi.referenceContributor");
- public abstract void registerReferenceProviders(PsiReferenceRegistrar registrar);
+ public abstract void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar);
@Override
public void dispose() {
diff --git a/platform/lang-api/src/com/intellij/psi/PsiReferenceProviderBean.java b/platform/core-api/src/com/intellij/psi/PsiReferenceProviderBean.java
index a45f911d6c03..9ccd791edc59 100644
--- a/platform/lang-api/src/com/intellij/psi/PsiReferenceProviderBean.java
+++ b/platform/core-api/src/com/intellij/psi/PsiReferenceProviderBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-api/src/com/intellij/psi/PsiReferenceService.java b/platform/core-api/src/com/intellij/psi/PsiReferenceService.java
index a83ff97c19ae..d6433a59f3cb 100644
--- a/platform/core-api/src/com/intellij/psi/PsiReferenceService.java
+++ b/platform/core-api/src/com/intellij/psi/PsiReferenceService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -44,6 +44,7 @@ public abstract class PsiReferenceService {
* fail-fast checks in case the pattern takes long to match.
* @return the references
*/
+ @NotNull
public abstract List<PsiReference> getReferences(@NotNull final PsiElement element, @NotNull final Hints hints);
public PsiReference[] getContributedReferences(@NotNull final PsiElement element) {
diff --git a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java
index d3ae32aa871c..7f7f05512b9c 100644
--- a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java
@@ -30,9 +30,7 @@ public class DelegatingGlobalSearchScope extends GlobalSearchScope {
private final Object myEquality;
public DelegatingGlobalSearchScope(@NotNull GlobalSearchScope baseScope) {
- super(baseScope.getProject());
- myBaseScope = baseScope;
- myEquality = ArrayUtil.EMPTY_OBJECT_ARRAY;
+ this(baseScope, ArrayUtil.EMPTY_OBJECT_ARRAY);
}
public DelegatingGlobalSearchScope(@NotNull GlobalSearchScope baseScope, @NotNull Object... equality) {
@@ -71,6 +69,7 @@ public class DelegatingGlobalSearchScope extends GlobalSearchScope {
return myBaseScope.isSearchOutsideRootModel();
}
+ @NotNull
@Override
public String getDisplayName() {
return myBaseScope.getDisplayName();
diff --git a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java
index b73cb5d69beb..0b74f65ae63f 100644
--- a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java
@@ -30,10 +30,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
public abstract class GlobalSearchScope extends SearchScope implements ProjectAwareFileFilter {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.GlobalSearchScope");
@@ -266,6 +263,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
@NotNull
public static GlobalSearchScope fileScope(@NotNull Project project, final VirtualFile virtualFile, @Nullable final String displayName) {
return new FileScope(project, virtualFile) {
+ @NotNull
@Override
public String getDisplayName() {
return displayName == null ? super.getDisplayName() : displayName;
@@ -282,6 +280,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
public static GlobalSearchScope filesScope(@NotNull Project project, @NotNull Collection<VirtualFile> files, @Nullable final String displayName) {
if (files.isEmpty()) return EMPTY_SCOPE;
return files.size() == 1? fileScope(project, files.iterator().next(), displayName) : new FilesScope(project, files) {
+ @NotNull
@Override
public String getDisplayName() {
return displayName == null ? super.getDisplayName() : displayName;
@@ -310,6 +309,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
return new IntersectionScope(this, scope, null);
}
+ @NotNull
@Override
public String getDisplayName() {
if (myDisplayName == null) {
@@ -392,6 +392,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
myDisplayName = displayName;
}
+ @NotNull
@Override
public String getDisplayName() {
if (myDisplayName == null) {
@@ -582,8 +583,8 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
public static final GlobalSearchScope EMPTY_SCOPE = new EmptyScope();
- private static class FileScope extends GlobalSearchScope {
- private final VirtualFile myVirtualFile;
+ private static class FileScope extends GlobalSearchScope implements Iterable<VirtualFile> {
+ private final VirtualFile myVirtualFile; // files can be out of project roots
private final Module myModule;
private FileScope(@NotNull Project project, VirtualFile virtualFile) {
@@ -616,10 +617,15 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
public String toString() {
return "File :"+myVirtualFile;
}
+
+ @Override
+ public Iterator<VirtualFile> iterator() {
+ return Collections.singletonList(myVirtualFile).iterator();
+ }
}
- public static class FilesScope extends GlobalSearchScope {
- private final Collection<VirtualFile> myFiles;
+ public static class FilesScope extends GlobalSearchScope implements Iterable<VirtualFile> {
+ private final Collection<VirtualFile> myFiles; // files can be out of project roots
public FilesScope(final Project project, @NotNull Collection<VirtualFile> files) {
super(project);
@@ -662,5 +668,10 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
List<VirtualFile> files = myFiles.size() <= 20 ? new ArrayList<VirtualFile>(myFiles) : new ArrayList<VirtualFile>(myFiles).subList(0,20);
return "Files: ("+ files +")";
}
+
+ @Override
+ public Iterator<VirtualFile> iterator() {
+ return myFiles.iterator();
+ }
}
}
diff --git a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
index 7b94ad197eba..4f645e528271 100644
--- a/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/LocalSearchScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -85,6 +85,7 @@ public class LocalSearchScope extends SearchScope {
return myIgnoreInjectedPsi;
}
+ @NotNull
@Override
public String getDisplayName() {
return myDisplayName == null ? super.getDisplayName() : myDisplayName;
@@ -242,7 +243,7 @@ public class LocalSearchScope extends SearchScope {
return false;
}
- public boolean containsRange(PsiFile file, TextRange range) {
+ public boolean containsRange(PsiFile file, @NotNull TextRange range) {
for (PsiElement element : getScope()) {
if (file == element.getContainingFile() && element.getTextRange().contains(range)) {
return true;
diff --git a/platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoryScope.java b/platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoriesScope.java
index 069017dc7b5b..0cf15e6970c2 100644
--- a/platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoryScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/NonClasspathDirectoriesScope.java
@@ -19,18 +19,21 @@ package com.intellij.psi.search;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import java.util.Collection;
import java.util.List;
+import java.util.Set;
/**
* @author peter
*/
-public class NonClasspathDirectoryScope extends GlobalSearchScope {
- private final VirtualFile myRoot;
+public class NonClasspathDirectoriesScope extends GlobalSearchScope {
+ private final Set<VirtualFile> myRoots;
- public NonClasspathDirectoryScope(@NotNull VirtualFile root) {
- myRoot = root;
+ public NonClasspathDirectoriesScope(@NotNull Collection<VirtualFile> roots) {
+ myRoots = ContainerUtil.newHashSet(roots);
}
@Override
@@ -44,16 +47,12 @@ public class NonClasspathDirectoryScope extends GlobalSearchScope {
return EMPTY_SCOPE;
}
- GlobalSearchScope scope = new NonClasspathDirectoryScope(roots.get(0));
- for (int i = 1; i < roots.size(); i++) {
- scope = scope.uniteWith(new NonClasspathDirectoryScope(roots.get(i)));
- }
- return scope;
+ return new NonClasspathDirectoriesScope(roots);
}
@Override
public boolean contains(@NotNull VirtualFile file) {
- return VfsUtilCore.isAncestor(myRoot, file, false);
+ return VfsUtilCore.isUnder(file, myRoots);
}
@Override
@@ -74,11 +73,11 @@ public class NonClasspathDirectoryScope extends GlobalSearchScope {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof NonClasspathDirectoryScope)) return false;
+ if (!(o instanceof NonClasspathDirectoriesScope)) return false;
- NonClasspathDirectoryScope that = (NonClasspathDirectoryScope)o;
+ NonClasspathDirectoriesScope that = (NonClasspathDirectoriesScope)o;
- if (!myRoot.equals(that.myRoot)) return false;
+ if (!myRoots.equals(that.myRoots)) return false;
return true;
}
@@ -86,7 +85,7 @@ public class NonClasspathDirectoryScope extends GlobalSearchScope {
@Override
public int hashCode() {
int result = super.hashCode();
- result = 31 * result + myRoot.hashCode();
+ result = 31 * result + myRoots.hashCode();
return result;
}
}
diff --git a/platform/core-api/src/com/intellij/psi/search/SearchScope.java b/platform/core-api/src/com/intellij/psi/search/SearchScope.java
index 62843d57e437..07aa61216e37 100644
--- a/platform/core-api/src/com/intellij/psi/search/SearchScope.java
+++ b/platform/core-api/src/com/intellij/psi/search/SearchScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -29,10 +29,12 @@ public abstract class SearchScope {
*
* @return hashCode value semantically identical to one from Object but not native
*/
+ @Override
public int hashCode() {
return myHashCode;
}
+ @NotNull
public String getDisplayName() {
return PsiBundle.message("search.scope.unknown");
}
diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java
index 01fb0486e477..4ced12477ba4 100644
--- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java
+++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java
@@ -75,7 +75,7 @@ public class StubSerializationHelper {
public void serialize(@NotNull Stub rootStub, @NotNull OutputStream stream) throws IOException {
BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream();
- FileLocalStringEnumerator storage = new FileLocalStringEnumerator();
+ FileLocalStringEnumerator storage = new FileLocalStringEnumerator(true);
StubOutputStream stubOutputStream = new StubOutputStream(out, storage);
doSerialize(rootStub, stubOutputStream);
@@ -98,18 +98,19 @@ public class StubSerializationHelper {
@NotNull
public Stub deserialize(@NotNull InputStream stream) throws IOException, SerializerNotFoundException {
- FileLocalStringEnumerator storage = new FileLocalStringEnumerator();
+ FileLocalStringEnumerator storage = new FileLocalStringEnumerator(false);
StubInputStream inputStream = new StubInputStream(stream, storage);
- final int size = DataInputOutputUtil.readINT(inputStream);
+ final int numberOfStrings = DataInputOutputUtil.readINT(inputStream);
byte[] buffer = IOUtil.allocReadWriteUTFBuffer();
+ storage.myStrings.ensureCapacity(numberOfStrings);
- int i = 1;
- while(i <= size) {
+ int i = 0;
+ while(i < numberOfStrings) {
String s = myStringInterner.get(IOUtil.readUTFFast(buffer, inputStream));
storage.myStrings.add(s);
- storage.myEnumerates.put(s, i);
++i;
}
+
return deserialize(inputStream, null);
}
@@ -139,12 +140,18 @@ public class StubSerializationHelper {
}
private static class FileLocalStringEnumerator implements AbstractStringEnumerator {
- private final TObjectIntHashMap<String> myEnumerates = new TObjectIntHashMap<String>();
+ private final TObjectIntHashMap<String> myEnumerates;
private final ArrayList<String> myStrings = new ArrayList<String>();
+ FileLocalStringEnumerator(boolean forSavingStub) {
+ if (forSavingStub) myEnumerates = new TObjectIntHashMap<String>();
+ else myEnumerates = null;
+ }
+
@Override
public int enumerate(@Nullable String value) throws IOException {
if (value == null) return 0;
+ assert myEnumerates != null; // enumerate possible only when writing stub
int i = myEnumerates.get(value);
if (i == 0) {
myEnumerates.put(value, i = myStrings.size() + 1);
diff --git a/platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java b/platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java
index c5fa9d6cd8db..02b555c7e9e8 100644
--- a/platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java
+++ b/platform/core-api/src/com/intellij/psi/util/PsiModificationTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.util.messages.Topic;
+import org.jetbrains.annotations.NotNull;
public interface PsiModificationTracker extends ModificationTracker {
class SERVICE {
@@ -60,8 +61,14 @@ public interface PsiModificationTracker extends ModificationTracker {
long getOutOfCodeBlockModificationCount();
+ @NotNull
+ ModificationTracker getOutOfCodeBlockModificationTracker();
+
long getJavaStructureModificationCount();
+ @NotNull
+ ModificationTracker getJavaStructureModificationTracker();
+
interface Listener {
void modificationCountChanged();
}
diff --git a/platform/core-api/src/com/intellij/util/FileIconKey.java b/platform/core-api/src/com/intellij/util/FileIconKey.java
index 286a6147d832..8548393aabb2 100644
--- a/platform/core-api/src/com/intellij/util/FileIconKey.java
+++ b/platform/core-api/src/com/intellij/util/FileIconKey.java
@@ -15,10 +15,14 @@
*/
package com.intellij.util;
+import com.intellij.lang.Language;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Konstantin Bulenkov
@@ -27,9 +31,11 @@ class FileIconKey {
private final VirtualFile myFile;
private final Project myProject;
@Iconable.IconFlags private final int myFlags;
+ @Nullable private final Language myInitialLanguage;
FileIconKey(@NotNull VirtualFile file, final Project project, @Iconable.IconFlags int flags) {
myFile = file;
+ myInitialLanguage = myFile instanceof LightVirtualFile ? ((LightVirtualFile)myFile).getLanguage() : null;
myProject = project;
myFlags = flags;
}
@@ -43,6 +49,7 @@ class FileIconKey {
if (myFlags != that.myFlags) return false;
if (!myFile.equals(that.myFile)) return false;
+ if (!Comparing.equal(myInitialLanguage, that.myInitialLanguage)) return false;
if (myProject != null ? !myProject.equals(that.myProject) : that.myProject != null) return false;
return true;
diff --git a/platform/core-api/src/com/intellij/util/IconUtil.java b/platform/core-api/src/com/intellij/util/IconUtil.java
index 28ff9df4186b..07b5fca6b7e4 100644
--- a/platform/core-api/src/com/intellij/util/IconUtil.java
+++ b/platform/core-api/src/com/intellij/util/IconUtil.java
@@ -371,6 +371,13 @@ public class IconUtil {
}
public static Icon scale(@NotNull final Icon source, double _scale) {
+ final int hiDPIscale;
+ if (source instanceof ImageIcon) {
+ Image image = ((ImageIcon)source).getImage();
+ hiDPIscale = RetinaImage.isAppleHiDPIScaledImage(image) || image instanceof JBHiDPIScaledImage ? 2 : 1;
+ } else {
+ hiDPIscale = 1;
+ }
final double scale = Math.min(32, Math.max(.1, _scale));
return new Icon() {
@Override
@@ -389,12 +396,12 @@ public class IconUtil {
@Override
public int getIconWidth() {
- return (int)(source.getIconWidth() * scale);
+ return (int)(source.getIconWidth() * scale) / hiDPIscale;
}
@Override
public int getIconHeight() {
- return (int)(source.getIconHeight() * scale);
+ return (int)(source.getIconHeight() * scale) / hiDPIscale;
}
};
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index 5172e155cd14..7e4ff81b69a1 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -29,6 +29,7 @@ public class PlatformUtilsCore {
public static final String PHP_PREFIX = "PhpStorm";
public static final String WEB_PREFIX = "WebStorm";
public static final String FLEX_PREFIX = "Flex";
+ public static final String DBE_PREFIX = "0xDBE";
public static String getPlatformPrefix() {
return getPlatformPrefix(IDEA_PREFIX);
@@ -81,4 +82,8 @@ public class PlatformUtilsCore {
public static boolean isWebStorm() {
return WEB_PREFIX.equals(getPlatformPrefix());
}
+
+ public static boolean isDatabaseIDE() {
+ return DBE_PREFIX.equals(getPlatformPrefix());
+ }
}
diff --git a/platform/core-api/src/com/intellij/util/QueryFactory.java b/platform/core-api/src/com/intellij/util/QueryFactory.java
index 80155a51fa08..e00f61cdc4e6 100644
--- a/platform/core-api/src/com/intellij/util/QueryFactory.java
+++ b/platform/core-api/src/com/intellij/util/QueryFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -57,6 +57,7 @@ public class QueryFactory<Result, Parameters> {
* @param parameters of the search
* @return query to perform the search. Obtained results are automatically filtered wrt. equals() relation.
*/
+ @NotNull
public final Query<Result> createUniqueResultsQuery(@NotNull Parameters parameters) {
return new UniqueResultsQuery<Result, Result>(createQuery(parameters));
}
@@ -66,6 +67,7 @@ public class QueryFactory<Result, Parameters> {
* @param hashingStrategy strategy to factor results
* @return query to perform the search. Obtained results are automatically filtered wrt. equals() relation.
*/
+ @NotNull
public final Query<Result> createUniqueResultsQuery(@NotNull Parameters parameters,
@NotNull TObjectHashingStrategy<Result> hashingStrategy) {
return new UniqueResultsQuery<Result, Result>(createQuery(parameters), hashingStrategy);
@@ -78,6 +80,7 @@ public class QueryFactory<Result, Parameters> {
* @return query to perform the search. Obtained results are mapped to whatever objects that are automatically filtered wrt. equals()
* relation. Storing mapped objects instead of original elements may be wise wrt to memory consumption.
*/
+ @NotNull
public final <T> Query<Result> createUniqueResultsQuery(@NotNull Parameters parameters,
@NotNull TObjectHashingStrategy<T> hashingStrategy,
@NotNull Function<Result, T> mapper) {
diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
index 2d204dc21458..7f04b192c640 100644
--- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
+++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
@@ -22,9 +22,10 @@ import com.intellij.lang.impl.PsiBuilderFactoryImpl;
import com.intellij.mock.MockApplication;
import com.intellij.mock.MockApplicationEx;
import com.intellij.mock.MockFileDocumentManagerImpl;
-import com.intellij.mock.MockReferenceProvidersRegistry;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.command.impl.CoreCommandProcessor;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.impl.DocumentImpl;
@@ -52,6 +53,7 @@ import com.intellij.psi.PsiReferenceService;
import com.intellij.psi.PsiReferenceServiceImpl;
import com.intellij.psi.impl.meta.MetaRegistry;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
+import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl;
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.meta.MetaDataRegistrar;
import com.intellij.psi.stubs.BinaryFileStubBuilders;
@@ -76,23 +78,22 @@ import java.util.concurrent.TimeoutException;
*/
public class CoreApplicationEnvironment {
private final CoreFileTypeRegistry myFileTypeRegistry;
- private final CoreEncodingRegistry myEncodingRegistry;
protected final MockApplication myApplication;
private final CoreLocalFileSystem myLocalFileSystem;
protected final VirtualFileSystem myJarFileSystem;
- private final Disposable myParentDisposable;
+ @NotNull private final Disposable myParentDisposable;
public CoreApplicationEnvironment(@NotNull Disposable parentDisposable) {
myParentDisposable = parentDisposable;
Extensions.cleanRootArea(myParentDisposable);
myFileTypeRegistry = new CoreFileTypeRegistry();
- myEncodingRegistry = new CoreEncodingRegistry();
+ CoreEncodingRegistry encodingRegistry = new CoreEncodingRegistry();
myApplication = createApplication(myParentDisposable);
ApplicationManager.setApplication(myApplication,
new StaticGetter<FileTypeRegistry>(myFileTypeRegistry),
- new StaticGetter<EncodingRegistry>(myEncodingRegistry),
+ new StaticGetter<EncodingRegistry>(encodingRegistry),
myParentDisposable);
myLocalFileSystem = createLocalFileSystem();
myJarFileSystem = createJarFileSystem();
@@ -112,12 +113,12 @@ public class CoreApplicationEnvironment {
registerComponentInstance(appContainer, VirtualFileManager.class, virtualFileManager);
registerApplicationService(VirtualFilePointerManager.class, createVirtualFilePointerManager());
- myApplication.registerService(DefaultASTFactory.class, new CoreASTFactory());
- myApplication.registerService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
- myApplication.registerService(ReferenceProvidersRegistry.class, new MockReferenceProvidersRegistry());
- myApplication.registerService(StubTreeLoader.class, new CoreStubTreeLoader());
- myApplication.registerService(PsiReferenceService.class, new PsiReferenceServiceImpl());
- myApplication.registerService(MetaDataRegistrar.class, new MetaRegistry());
+ registerApplicationService(DefaultASTFactory.class, new CoreASTFactory());
+ registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
+ registerApplicationService(ReferenceProvidersRegistry.class, new ReferenceProvidersRegistryImpl());
+ registerApplicationService(StubTreeLoader.class, new CoreStubTreeLoader());
+ registerApplicationService(PsiReferenceService.class, new PsiReferenceServiceImpl());
+ registerApplicationService(MetaDataRegistrar.class, new MetaRegistry());
registerApplicationExtensionPoint(ContentBasedFileSubstitutor.EP_NAME, ContentBasedFileSubstitutor.class);
registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
@@ -127,8 +128,9 @@ public class CoreApplicationEnvironment {
ProgressIndicatorProvider.ourInstance = createProgressIndicatorProvider();
- myApplication.registerService(JobLauncher.class, createJobLauncher());
- myApplication.registerService(CodeFoldingSettings.class, new CodeFoldingSettings());
+ registerApplicationService(JobLauncher.class, createJobLauncher());
+ registerApplicationService(CodeFoldingSettings.class, new CodeFoldingSettings());
+ registerApplicationService(CommandProcessor.class, new CoreCommandProcessor());
}
public <T> void registerApplicationService(@NotNull Class<T> serviceInterface, @NotNull T serviceImplementation) {
@@ -256,32 +258,33 @@ public class CoreApplicationEnvironment {
return myApplication;
}
+ @NotNull
public Disposable getParentDisposable() {
return myParentDisposable;
}
- public <T> void registerApplicationComponent(final Class<T> interfaceClass, final T implementation) {
+ public <T> void registerApplicationComponent(@NotNull Class<T> interfaceClass, @NotNull T implementation) {
registerComponentInstance(myApplication.getPicoContainer(), interfaceClass, implementation);
}
- public void registerFileType(FileType fileType, String extension) {
+ public void registerFileType(@NotNull FileType fileType, @NotNull String extension) {
myFileTypeRegistry.registerFileType(fileType, extension);
}
- public void registerParserDefinition(ParserDefinition definition) {
+ public void registerParserDefinition(@NotNull ParserDefinition definition) {
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
}
- public static <T> void registerComponentInstance(final MutablePicoContainer container, final Class<T> key, final T implementation) {
+ public static <T> void registerComponentInstance(@NotNull MutablePicoContainer container, @NotNull Class<T> key, @NotNull T implementation) {
container.unregisterComponent(key);
container.registerComponentInstance(key, implementation);
}
- public <T> void addExplicitExtension(final LanguageExtension<T> instance, final Language language, final T object) {
+ public <T> void addExplicitExtension(@NotNull LanguageExtension<T> instance, @NotNull Language language, @NotNull T object) {
doAddExplicitExtension(instance, language, object);
}
- public void registerParserDefinition(Language language, ParserDefinition parserDefinition) {
+ public void registerParserDefinition(@NotNull Language language, @NotNull ParserDefinition parserDefinition) {
addExplicitExtension(LanguageParserDefinitions.INSTANCE, language, parserDefinition);
}
@@ -303,7 +306,7 @@ public class CoreApplicationEnvironment {
doAddExplicitExtension(instance, aClass, object);
}
- public <T> void addExtension(ExtensionPointName<T> name, final T extension) {
+ public <T> void addExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
final ExtensionPoint<T> extensionPoint = Extensions.getRootArea().getExtensionPoint(name);
extensionPoint.registerExtension(extension);
Disposer.register(myParentDisposable, new Disposable() {
@@ -315,28 +318,31 @@ public class CoreApplicationEnvironment {
}
- public static <T> void registerExtensionPoint(final ExtensionsArea area, final ExtensionPointName<T> extensionPointName,
- final Class<? extends T> aClass) {
+ public static <T> void registerExtensionPoint(@NotNull ExtensionsArea area,
+ @NotNull ExtensionPointName<T> extensionPointName,
+ @NotNull Class<? extends T> aClass) {
final String name = extensionPointName.getName();
registerExtensionPoint(area, name, aClass);
}
- public static <T> void registerExtensionPoint(ExtensionsArea area, String name, Class<? extends T> aClass) {
+ public static <T> void registerExtensionPoint(@NotNull ExtensionsArea area, @NotNull String name, @NotNull Class<? extends T> aClass) {
if (!area.hasExtensionPoint(name)) {
ExtensionPoint.Kind kind = aClass.isInterface() || (aClass.getModifiers() & Modifier.ABSTRACT) != 0 ? ExtensionPoint.Kind.INTERFACE : ExtensionPoint.Kind.BEAN_CLASS;
area.registerExtensionPoint(name, aClass.getName(), kind);
}
}
- public static <T> void registerApplicationExtensionPoint(final ExtensionPointName<T> extensionPointName, final Class<? extends T> aClass) {
+ public static <T> void registerApplicationExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName, @NotNull Class<? extends T> aClass) {
final String name = extensionPointName.getName();
registerExtensionPoint(Extensions.getRootArea(), name, aClass);
}
+ @NotNull
public CoreLocalFileSystem getLocalFileSystem() {
return myLocalFileSystem;
}
+ @NotNull
public VirtualFileSystem getJarFileSystem() {
return myJarFileSystem;
}
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java
index 3bfae45dde59..24e12524dc97 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java
@@ -132,7 +132,11 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
public void readExternal(@NotNull Document document, @NotNull URL url) throws InvalidDataException, FileNotFoundException {
Application application = ApplicationManager.getApplication();
- document = JDOMXIncluder.resolve(document, url.toExternalForm(), application != null && application.isUnitTestMode());
+ readExternal(document, url, application != null && application.isUnitTestMode());
+ }
+
+ public void readExternal(@NotNull Document document, @NotNull URL url, boolean ignoreMissingInclude) throws InvalidDataException, FileNotFoundException {
+ document = JDOMXIncluder.resolve(document, url.toExternalForm(), ignoreMissingInclude);
Element rootElement = document.getRootElement();
internJDOMElement(rootElement);
readExternal(document.getRootElement());
@@ -342,6 +346,18 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor {
return myCategory;
}
+ @SuppressWarnings("UnusedDeclaration") // Used in Upsource
+ @Nullable
+ public MultiMap<String, Element> getExtensionsPoints() {
+ return myExtensionsPoints;
+ }
+
+ @SuppressWarnings("UnusedDeclaration") // Used in Upsource
+ @Nullable
+ public MultiMap<String, Element> getExtensions() {
+ return myExtensions;
+ }
+
@SuppressWarnings({"HardCodedStringLiteral"})
@NotNull
public List<File> getClassPath() {
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
index 65eabe217859..cf2d45ad4945 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
@@ -539,8 +539,9 @@ public class PluginManagerCore {
ArrayList<PluginId> plugins = new ArrayList<PluginId>();
for (PluginId dependentPluginId : descriptor.getDependentPluginIds()) {
// check for missing optional dependency
- if (idToDescriptorMap.containsKey(dependentPluginId)) {
- plugins.add(dependentPluginId);
+ IdeaPluginDescriptorImpl dep = idToDescriptorMap.get(dependentPluginId);
+ if (dep != null) {
+ plugins.add(dep.getPluginId());
}
}
return plugins.iterator();
diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
index dabe29e48617..3338241e705a 100644
--- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
+++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,10 +36,7 @@ import com.intellij.psi.impl.source.text.DiffLog;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.text.BlockSupport;
import com.intellij.psi.tree.*;
-import com.intellij.util.CharTable;
-import com.intellij.util.ExceptionUtil;
-import com.intellij.util.ThreeState;
-import com.intellij.util.TripleFunction;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.LimitedPool;
@@ -1345,6 +1342,13 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return Comparing.equal(e1.getErrorDescription(), getErrorMessage(newNode)) ? ThreeState.UNSURE : ThreeState.NO;
}
+ if (custom != null) {
+ ThreeState customResult = custom.fun(oldNode, newNode, myTreeStructure);
+
+ if (customResult != ThreeState.UNSURE) {
+ return customResult;
+ }
+ }
if (newNode instanceof Token) {
final IElementType type = newNode.getTokenType();
final Token token = (Token)newNode;
@@ -1378,9 +1382,6 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
: ThreeState.NO;
}
}
- if (custom != null) {
- return custom.fun(oldNode, newNode, myTreeStructure);
- }
return ThreeState.UNSURE;
}
@@ -1654,21 +1655,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
* just to make removeRange method available.
*/
private static class MyList extends ArrayList<ProductionMarker> {
- private static final Field ourElementDataField;
-
- static {
- Field f;
- try {
- f = ArrayList.class.getDeclaredField("elementData");
- f.setAccessible(true);
- }
- catch(NoSuchFieldException e) {
- // IBM J9 does not have the field
- f = null;
-
- }
- ourElementDataField = f;
- }
+ private static final Field ourElementDataField = ReflectionUtil.getDeclaredField(ArrayList.class, "elementData");
private Object[] cachedElementData;
diff --git a/platform/core-impl/src/com/intellij/mock/MockDumbService.java b/platform/core-impl/src/com/intellij/mock/MockDumbService.java
index fa922fbe21ba..1e1179cc5ee8 100644
--- a/platform/core-impl/src/com/intellij/mock/MockDumbService.java
+++ b/platform/core-impl/src/com/intellij/mock/MockDumbService.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.project.DumbModeTask;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -50,11 +51,15 @@ public class MockDumbService extends DumbService {
}
@Override
- public void queueTask(DumbModeTask task) {
+ public void queueTask(@NotNull DumbModeTask task) {
task.performInDumbMode(new EmptyProgressIndicator());
+ Disposer.dispose(task);
}
@Override
+ public void cancelTask(@NotNull DumbModeTask task) { }
+
+ @Override
public JComponent wrapGently(@NotNull JComponent dumbUnawareContent, @NotNull Disposable parentDisposable) {
throw new UnsupportedOperationException();
}
diff --git a/platform/core-impl/src/com/intellij/mock/MockFileDocumentManagerImpl.java b/platform/core-impl/src/com/intellij/mock/MockFileDocumentManagerImpl.java
index ffaba2b21b10..1d7e03624708 100644
--- a/platform/core-impl/src/com/intellij/mock/MockFileDocumentManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/mock/MockFileDocumentManagerImpl.java
@@ -24,7 +24,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
-import com.intellij.util.containers.WeakFactoryMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,26 +37,25 @@ public class MockFileDocumentManagerImpl extends FileDocumentManager {
myCachedDocumentKey = cachedDocumentKey;
}
- private final WeakFactoryMap<VirtualFile,Document> myDocuments = new WeakFactoryMap<VirtualFile, Document>() {
- @Override
- protected Document create(final VirtualFile key) {
- if (key.isDirectory() || isBinaryWithoutDecompiler(key)) return null;
+ private static final Key<Document> MOCK_DOC_KEY = Key.create("MOCK_DOC_KEY");
- CharSequence text = LoadTextUtil.loadText(key);
- final Document document = myFactory.fun(text);
- document.putUserData(MOCK_VIRTUAL_FILE_KEY, key);
- return document;
- }
-
- private boolean isBinaryWithoutDecompiler(VirtualFile file) {
- final FileType ft = file.getFileType();
- return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) == null;
- }
- };
+ private static boolean isBinaryWithoutDecompiler(VirtualFile file) {
+ final FileType ft = file.getFileType();
+ return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) == null;
+ }
@Override
public Document getDocument(@NotNull VirtualFile file) {
- return myDocuments.get(file);
+ Document document = file.getUserData(MOCK_DOC_KEY);
+ if (document == null) {
+ if (file.isDirectory() || isBinaryWithoutDecompiler(file)) return null;
+
+ CharSequence text = LoadTextUtil.loadText(file);
+ document = myFactory.fun(text);
+ document.putUserData(MOCK_VIRTUAL_FILE_KEY, file);
+ document = file.putUserDataIfAbsent(MOCK_DOC_KEY, document);
+ }
+ return document;
}
@Override
diff --git a/platform/core-impl/src/com/intellij/mock/MockReferenceProvidersRegistry.java b/platform/core-impl/src/com/intellij/mock/MockReferenceProvidersRegistry.java
deleted file mode 100644
index fb092b8bd495..000000000000
--- a/platform/core-impl/src/com/intellij/mock/MockReferenceProvidersRegistry.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.mock;
-
-import com.intellij.lang.Language;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.PsiReferenceRegistrar;
-import com.intellij.psi.PsiReferenceService;
-import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
-
-/**
- * @author yole
- */
-public class MockReferenceProvidersRegistry extends ReferenceProvidersRegistry {
- @Override
- public PsiReferenceRegistrar getRegistrar(Language language) {
- return null;
- }
-
- @Override
- protected PsiReference[] doGetReferencesFromProviders(PsiElement context, PsiReferenceService.Hints hints) {
- return PsiReference.EMPTY_ARRAY;
- }
-}
diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
index ddabe8b9458a..acb83f1fe2fd 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
@@ -44,10 +44,14 @@ public interface ApplicationEx extends Application {
@NotNull
String getName();
+ /**
+ * @return true if this thread is inside read action.
+ * @see #runReadAction(Runnable)
+ */
boolean holdsReadLock();
/**
- * @return true if the EDT performs write action now.
+ * @return true if the EDT is performing write action right now.
* @see #runWriteAction(Runnable)
*/
boolean isWriteActionInProgress();
diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java
index a64852deb33c..4282eb20ff26 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java
@@ -74,6 +74,8 @@ public abstract class ApplicationInfoEx extends ApplicationInfo {
public abstract String getPluginsDownloadUrl();
+ public abstract String getBuiltinPluginsUrl();
+
public abstract String getWebHelpUrl();
public abstract String getWhatsNewUrl();
diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
index 6c8feab54aae..78ce83cc5154 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
@@ -83,6 +83,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
private String myPluginManagerUrl;
private String myPluginsListUrl;
private String myPluginsDownloadUrl;
+ private String myBuiltinPluginsUrl;
private String myWhatsNewUrl;
private String myWinKeymapUrl;
private String myMacKeymapUrl;
@@ -153,6 +154,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
@NonNls private static final String ELEMENT_PLUGINS = "plugins";
@NonNls private static final String ATTRIBUTE_LIST_URL = "list-url";
@NonNls private static final String ATTRIBUTE_DOWNLOAD_URL = "download-url";
+ @NonNls private static final String ATTRIBUTE_BUILTIN_URL = "builtin-url";
@NonNls private static final String ATTRIBUTE_WEBHELP_URL = "webhelp-url";
@NonNls private static final String ATTRIBUTE_HAS_HELP = "has-help";
@NonNls private static final String ATTRIBUTE_HAS_CONTEXT_HELP = "has-context-help";
@@ -355,6 +357,10 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
return myPluginsDownloadUrl;
}
+ public String getBuiltinPluginsUrl() {
+ return myBuiltinPluginsUrl;
+ }
+
public String getWebHelpUrl() {
return myWebHelpUrl;
}
@@ -651,6 +657,9 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
if (downloadUrl != null) {
myPluginsDownloadUrl = downloadUrl;
}
+ if (!getBuild().isSnapshot()) {
+ myBuiltinPluginsUrl = pluginsElement.getAttributeValue(ATTRIBUTE_BUILTIN_URL);
+ }
}
else {
myPluginManagerUrl = DEFAULT_PLUGINS_HOST;
@@ -770,4 +779,12 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
return myDependentPlugin;
}
}
+
+ private static volatile boolean myInPerformanceTest;
+ public static boolean isInPerformanceTest() {
+ return myInPerformanceTest;
+ }
+ public static void setInPerformanceTest(boolean inPerformanceTest) {
+ myInPerformanceTest = inPerformanceTest;
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java b/platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java
index deba1eec5408..df22fdb8da8a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/CommandProcessorEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/command/CommandProcessorEx.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java b/platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java
index 0f257672be0c..14353098da5b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandLog.java
+++ b/platform/core-impl/src/com/intellij/openapi/command/impl/CommandLog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java b/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java
new file mode 100644
index 000000000000..d7284ee5242f
--- /dev/null
+++ b/platform/core-impl/src/com/intellij/openapi/command/impl/CoreCommandProcessor.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.command.impl;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandEvent;
+import com.intellij.openapi.command.CommandListener;
+import com.intellij.openapi.command.CommandProcessorEx;
+import com.intellij.openapi.command.UndoConfirmationPolicy;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Stack;
+
+public class CoreCommandProcessor extends CommandProcessorEx {
+ private static class CommandDescriptor {
+ public final Runnable myCommand;
+ public final Project myProject;
+ public String myName;
+ public Object myGroupId;
+ public final Document myDocument;
+ public final UndoConfirmationPolicy myUndoConfirmationPolicy;
+
+ public CommandDescriptor(Runnable command,
+ Project project,
+ String name,
+ Object groupId,
+ UndoConfirmationPolicy undoConfirmationPolicy,
+ Document document) {
+ myCommand = command;
+ myProject = project;
+ myName = name;
+ myGroupId = groupId;
+ myUndoConfirmationPolicy = undoConfirmationPolicy;
+ myDocument = document;
+ }
+
+ @Override
+ public String toString() {
+ return "'" + myName + "', group: '" + myGroupId + "'";
+ }
+ }
+
+ protected CommandDescriptor myCurrentCommand = null;
+ private final Stack<CommandDescriptor> myInterruptedCommands = new Stack<CommandDescriptor>();
+
+// private HashMap myStatisticsMap = new HashMap(); // command name --> count
+
+ // private HashMap myStatisticsMap = new HashMap(); // command name --> count
+
+ private final List<CommandListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+
+ private int myUndoTransparentCount = 0;
+
+ @Override
+ public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) {
+ executeCommand(null, runnable, name, groupId);
+ }
+
+ @Override
+ public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) {
+ executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT);
+ }
+
+ @Override
+ public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) {
+ executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document);
+ }
+
+ @Override
+ public void executeCommand(Project project,
+ @NotNull final Runnable command,
+ final String name,
+ final Object groupId,
+ @NotNull UndoConfirmationPolicy confirmationPolicy) {
+ executeCommand(project, command, name, groupId, confirmationPolicy, null);
+ }
+
+ @Override
+ public void executeCommand(Project project,
+ @NotNull final Runnable command,
+ final String name,
+ final Object groupId,
+ @NotNull UndoConfirmationPolicy confirmationPolicy,
+ Document document) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (project != null && project.isDisposed()) return;
+
+ if (CommandLog.LOG.isDebugEnabled()) {
+ CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId);
+ }
+
+ if (myCurrentCommand != null) {
+ command.run();
+ return;
+ }
+ Throwable throwable = null;
+ try {
+ myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document);
+ fireCommandStarted();
+ command.run();
+ }
+ catch (Throwable th) {
+ throwable = th;
+ }
+ finally {
+ finishCommand(project, myCurrentCommand, throwable);
+ }
+ }
+
+ @Override
+ @Nullable
+ public Object startCommand(final Project project,
+ @Nls final String name,
+ final Object groupId,
+ final UndoConfirmationPolicy undoConfirmationPolicy) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (project != null && project.isDisposed()) return null;
+
+ if (CommandLog.LOG.isDebugEnabled()) {
+ CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId);
+ }
+
+ if (myCurrentCommand != null) {
+ return null;
+ }
+
+ Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null;
+ myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document);
+ fireCommandStarted();
+ return myCurrentCommand;
+ }
+
+ @Override
+ public void finishCommand(final Project project, final Object command, final Throwable throwable) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress");
+ fireCommandFinished();
+ }
+
+ protected void fireCommandFinished() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandDescriptor currentCommand = myCurrentCommand;
+ CommandEvent event = new CommandEvent(this, currentCommand.myCommand,
+ currentCommand.myName,
+ currentCommand.myGroupId,
+ currentCommand.myProject,
+ currentCommand.myUndoConfirmationPolicy,
+ currentCommand.myDocument);
+ try {
+ for (CommandListener listener : myListeners) {
+ try {
+ listener.beforeCommandFinished(event);
+ }
+ catch (Throwable e) {
+ CommandLog.LOG.error(e);
+ }
+ }
+ }
+ finally {
+ myCurrentCommand = null;
+ for (CommandListener listener : myListeners) {
+ try {
+ listener.commandFinished(event);
+ }
+ catch (Throwable e) {
+ CommandLog.LOG.error(e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void enterModal() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandDescriptor currentCommand = myCurrentCommand;
+ myInterruptedCommands.push(currentCommand);
+ if (currentCommand != null) {
+ fireCommandFinished();
+ }
+ }
+
+ @Override
+ public void leaveModal() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand));
+
+ myCurrentCommand = myInterruptedCommands.pop();
+ if (myCurrentCommand != null) {
+ fireCommandStarted();
+ }
+ }
+
+ @Override
+ public void setCurrentCommandName(String name) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandDescriptor currentCommand = myCurrentCommand;
+ CommandLog.LOG.assertTrue(currentCommand != null);
+ currentCommand.myName = name;
+ }
+
+ @Override
+ public void setCurrentCommandGroupId(Object groupId) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandDescriptor currentCommand = myCurrentCommand;
+ CommandLog.LOG.assertTrue(currentCommand != null);
+ currentCommand.myGroupId = groupId;
+ }
+
+ @Override
+ @Nullable
+ public Runnable getCurrentCommand() {
+ CommandDescriptor currentCommand = myCurrentCommand;
+ return currentCommand != null ? currentCommand.myCommand : null;
+ }
+
+ @Override
+ @Nullable
+ public String getCurrentCommandName() {
+ CommandDescriptor currentCommand = myCurrentCommand;
+ if (currentCommand != null) return currentCommand.myName;
+ if (!myInterruptedCommands.isEmpty()) {
+ final CommandDescriptor command = myInterruptedCommands.peek();
+ return command != null ? command.myName : null;
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public Object getCurrentCommandGroupId() {
+ CommandDescriptor currentCommand = myCurrentCommand;
+ if (currentCommand != null) return currentCommand.myGroupId;
+ if (!myInterruptedCommands.isEmpty()) {
+ final CommandDescriptor command = myInterruptedCommands.peek();
+ return command != null ? command.myGroupId : null;
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public Project getCurrentCommandProject() {
+ CommandDescriptor currentCommand = myCurrentCommand;
+ return currentCommand != null ? currentCommand.myProject : null;
+ }
+
+ @Override
+ public void addCommandListener(@NotNull CommandListener listener) {
+ myListeners.add(listener);
+ }
+
+ @Override
+ public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) {
+ addCommandListener(listener);
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ removeCommandListener(listener);
+ }
+ });
+ }
+
+ @Override
+ public void removeCommandListener(@NotNull CommandListener listener) {
+ myListeners.remove(listener);
+ }
+
+ @Override
+ public void runUndoTransparentAction(@NotNull Runnable action) {
+ if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted();
+ try {
+ action.run();
+ }
+ finally {
+ if (--myUndoTransparentCount == 0) fireUndoTransparentFinished();
+ }
+ }
+
+ @Override
+ public boolean isUndoTransparentActionInProgress() {
+ return myUndoTransparentCount > 0;
+ }
+
+ @Override
+ public void markCurrentCommandAsGlobal(Project project) {
+ }
+
+
+ @Override
+ public void addAffectedDocuments(Project project, @NotNull Document... docs) {
+ }
+
+ @Override
+ public void addAffectedFiles(Project project, @NotNull VirtualFile... files) {
+ }
+
+ private void fireCommandStarted() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CommandDescriptor currentCommand = myCurrentCommand;
+ CommandEvent event = new CommandEvent(this,
+ currentCommand.myCommand,
+ currentCommand.myName,
+ currentCommand.myGroupId,
+ currentCommand.myProject,
+ currentCommand.myUndoConfirmationPolicy,
+ currentCommand.myDocument);
+ for (CommandListener listener : myListeners) {
+ try {
+ listener.commandStarted(event);
+ }
+ catch (Throwable e) {
+ CommandLog.LOG.error(e);
+ }
+ }
+ }
+
+ private void fireUndoTransparentStarted() {
+ for (CommandListener listener : myListeners) {
+ try {
+ listener.undoTransparentActionStarted();
+ }
+ catch (Throwable e) {
+ CommandLog.LOG.error(e);
+ }
+ }
+ }
+
+ private void fireUndoTransparentFinished() {
+ for (CommandListener listener : myListeners) {
+ try {
+ listener.undoTransparentActionFinished();
+ }
+ catch (Throwable e) {
+ CommandLog.LOG.error(e);
+ }
+ }
+ }
+}
diff --git a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
index 7a0e77707300..6d280a5e11af 100644
--- a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java
@@ -611,5 +611,10 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
visitor.visitComponentAdapter(this);
myDelegate.accept(visitor);
}
+
+ @Override
+ public String toString() {
+ return "ComponentConfigAdapter[" + getComponentKey() + "]: implementation=" + getComponentImplementation() + ", plugin=" + myConfig.getPluginId();
+ }
}
}
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
index 5fba46ac4ed7..1549c778a86f 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/CharArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,6 +16,8 @@
package com.intellij.openapi.editor.impl;
import com.intellij.diagnostic.Dumpable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.util.text.StringUtil;
@@ -39,6 +41,7 @@ import java.util.concurrent.locks.ReentrantLock;
* @author cdr
*/
abstract class CharArray implements CharSequenceBackedByArray, Dumpable {
+ private static final boolean CHECK_DOCUMENT_CONSISTENCY = ApplicationManager.getApplication() != null && ApplicationManager.getApplication().isUnitTestMode();
private static final Logger LOG = Logger.getInstance("#" + CharArray.class.getName());
@SuppressWarnings("UseOfArchaicSystemPropertyAccessors")
@@ -77,7 +80,7 @@ abstract class CharArray implements CharSequenceBackedByArray, Dumpable {
private final boolean myDebug = isDebug();
boolean isDebug() {
- return DEBUG_DEFERRED_PROCESSING || DocumentImpl.CHECK_DOCUMENT_CONSISTENCY;
+ return DEBUG_DEFERRED_PROCESSING || CHECK_DOCUMENT_CONSISTENCY && !ApplicationInfoImpl.isInPerformanceTest();
}
/**
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
index 8a343f7279dd..fa234e109d49 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
@@ -56,7 +56,6 @@ import java.util.List;
public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.DocumentImpl");
- public static boolean CHECK_DOCUMENT_CONSISTENCY = ApplicationManager.getApplication() != null && ApplicationManager.getApplication().isUnitTestMode();
private final Ref<DocumentListener[]> myCachedDocumentListeners = Ref.create(null);
private final List<DocumentListener> myDocumentListeners = ContainerUtil.createLockFreeCopyOnWriteList();
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
index a48ba0469c11..68e8d2500314 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java
@@ -295,14 +295,14 @@ public abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBla
}
/**
- * packing/unpacking cachedDeltaUpToRoot field parts
- * Bits layout:
- * XXXXXXXXNMMMMMMMM where
- * XXXXXXXX - 31bit int containing cached delta up to root
- * N - 1bit flag. if set then all deltas up to root are null
- * MMMMMMMM - 32bit int containing this node modification count
+ * packing/unpacking cachedDeltaUpToRoot field parts
+ * Bits layout:
+ * XXXXXXXXNMMMMMMMM where
+ * XXXXXXXX - 31bit int containing cached delta up to root
+ * N - 1bit flag. if set then all deltas up to root are null
+ * MMMMMMMM - 32bit int containing this node modification count
*/
- private static AtomicFieldUpdater<IntervalNode, Long> cachedDeltaUpdater = AtomicFieldUpdater.forLongField(IntervalNode.class);
+ private static final AtomicFieldUpdater<IntervalNode, Long> cachedDeltaUpdater = AtomicFieldUpdater.forLongFieldIn(IntervalNode.class);
private void setCachedValues(int deltaUpToRoot, boolean allDeltaUpToRootAreNull, int modCount) {
cachedDeltaUpToRoot = packValues(deltaUpToRoot, allDeltaUpToRootAreNull, modCount);
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
index 2e7ebadc3892..975add0847a9 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.editor.impl;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -98,7 +99,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
marker.setValid(true);
RMNode<T> node = (RMNode)super.addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
- if (DEBUG && node.intervals.size() > DUPLICATE_LIMIT) {
+ if (DEBUG && !ApplicationInfoImpl.isInPerformanceTest() && node.intervals.size() > DUPLICATE_LIMIT) {
l.readLock().lock();
try {
String msg = errMsg(node);
diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/TooManyUsagesStatus.java b/platform/core-impl/src/com/intellij/openapi/progress/util/TooManyUsagesStatus.java
index 74d7bf36b911..f44d497edefa 100644
--- a/platform/core-impl/src/com/intellij/openapi/progress/util/TooManyUsagesStatus.java
+++ b/platform/core-impl/src/com/intellij/openapi/progress/util/TooManyUsagesStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -27,17 +27,14 @@ import java.util.concurrent.atomic.AtomicReference;
public class TooManyUsagesStatus {
private static final Key<TooManyUsagesStatus> KEY = Key.create("TooManyUsagesStatus");
- private static final Null NULL = new Null();
+ private static final NullStatus NULL_STATUS = new NullStatus();
@NotNull
public static TooManyUsagesStatus getFrom(@Nullable ProgressIndicator indicator) {
- TooManyUsagesStatus data = null;
- if (indicator instanceof UserDataHolder) {
- data = ((UserDataHolder)indicator).getUserData(KEY);
- }
- if (data == null) data = NULL;
- return data;
+ TooManyUsagesStatus data = indicator instanceof UserDataHolder ? ((UserDataHolder)indicator).getUserData(KEY) : null;
+ return data == null ? NULL_STATUS : data;
}
+
public static TooManyUsagesStatus createFor(@NotNull ProgressIndicator indicator) {
TooManyUsagesStatus data = null;
if (indicator instanceof UserDataHolder) {
@@ -76,7 +73,7 @@ public class TooManyUsagesStatus {
}
}
- private static class Null extends TooManyUsagesStatus {
+ private static class NullStatus extends TooManyUsagesStatus {
@Override
public boolean switchTooManyUsagesStatus() {
return false;
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/CoreVirtualFilePointerManager.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/CoreVirtualFilePointerManager.java
index 5fb335394e54..da6c265a4937 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/CoreVirtualFilePointerManager.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/CoreVirtualFilePointerManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -65,9 +65,4 @@ public class CoreVirtualFilePointerManager extends VirtualFilePointerManager {
@Override
public void dispose() {
}
-
- @Override
- public long getModificationCount() {
- return 0;
- }
}
diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java
index 65dc79bac298..cf243d08bce0 100644
--- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.vfs.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.TraceableDisposable;
@@ -56,7 +57,7 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
@NotNull Disposable parentDisposable,
@Nullable VirtualFilePointerListener listener) {
//noinspection HardCodedStringLiteral
- super(TRACE_CREATION
+ super(TRACE_CREATION && !ApplicationInfoImpl.isInPerformanceTest()
? new Throwable("parent = '" + parentDisposable + "' (" + parentDisposable.getClass() + "); listener=" + listener)
: null);
myVirtualFilePointerManager = manager;
diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
index 5a3247452d57..ba5858c52993 100644
--- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
+++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
@@ -212,7 +212,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
final ListIterator<Pair<PomModelAspect, PomTransaction>> blocksIterator = myBlockedAspects.listIterator(myBlockedAspects.size());
while (blocksIterator.hasPrevious()) {
final Pair<PomModelAspect, PomTransaction> pair = blocksIterator.previous();
- if (pomModelAspect == pair.getFirst() && // aspect dependance
+ if (pomModelAspect == pair.getFirst() && // aspect dependence
PsiTreeUtil.isAncestor(pair.getSecond().getChangeScope(), transaction.getChangeScope(), false) &&
// target scope contain current
getContainingFileByTree(pair.getSecond().getChangeScope()) != null // target scope physical
@@ -234,7 +234,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
final int oldLength = containingFileByTree.getTextLength();
boolean success = synchronizer.commitTransaction(document);
if (success) {
- BlockSupportImpl.sendAfterChildrenChangedEvent((PsiManagerImpl)PsiManager.getInstance(myProject), (PsiFileImpl)containingFileByTree, oldLength, true);
+ BlockSupportImpl.sendAfterChildrenChangedEvent((PsiManagerImpl)PsiManager.getInstance(myProject), containingFileByTree, oldLength, true);
}
}
if (containingFileByTree != null) {
@@ -271,6 +271,8 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
PsiToDocumentSynchronizer synchronizer =((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject)).getSynchronizer();
TextRange changedPsiRange = DocumentCommitProcessor.getChangedPsiRange(file, oldText, newText);
+ if (changedPsiRange == null) return;
+
final DiffLog log = BlockSupport.getInstance(myProject).reparseRange(file, changedPsiRange, newText, new EmptyProgressIndicator());
synchronizer.setIgnorePsiEvents(true);
try {
diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
index 7358dffd9e69..454c81a7f320 100644
--- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
+++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
@@ -32,6 +32,7 @@ import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
+import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NonNls;
@@ -103,7 +104,7 @@ public abstract class PsiAnchor {
public static StubIndexReference createStubReference(@NotNull PsiElement element, @NotNull PsiFile containingFile) {
if (element instanceof StubBasedPsiElement &&
element.isPhysical() &&
- (element instanceof PsiCompiledElement || ((PsiFileImpl)containingFile).getContentElementType() instanceof IStubFileElementType)) {
+ (element instanceof PsiCompiledElement || canHaveStub(containingFile))) {
final StubBasedPsiElement elt = (StubBasedPsiElement)element;
final IStubElementType elementType = elt.getElementType();
if (elt.getStub() != null || elementType.shouldCreateStub(element.getNode())) {
@@ -116,6 +117,14 @@ public abstract class PsiAnchor {
return null;
}
+ private static boolean canHaveStub(PsiFile file) {
+ if (!(file instanceof PsiFileImpl)) return false;
+
+ VirtualFile vFile = file.getVirtualFile();
+ IElementType elementType = ((PsiFileImpl)file).getContentElementType();
+ return elementType instanceof IStubFileElementType && vFile != null && ((IStubFileElementType)elementType).shouldBuildStubFor(vFile);
+ }
+
public static int calcStubIndex(StubBasedPsiElement psi) {
if (psi instanceof PsiFile) {
return 0;
@@ -360,7 +369,7 @@ public abstract class PsiAnchor {
PsiDirectoryReference reference = (PsiDirectoryReference)o;
if (!myFile.equals(reference.myFile)) return false;
- if (myProject != null ? !myProject.equals(reference.myProject) : reference.myProject != null) return false;
+ if (!myProject.equals(reference.myProject)) return false;
return true;
}
diff --git a/platform/core-impl/src/com/intellij/psi/PsiReferenceServiceImpl.java b/platform/core-impl/src/com/intellij/psi/PsiReferenceServiceImpl.java
index 3283e3abbdf1..d77eb0a9f794 100644
--- a/platform/core-impl/src/com/intellij/psi/PsiReferenceServiceImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/PsiReferenceServiceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +25,7 @@ import java.util.List;
* @author Gregory.Shrago
*/
public class PsiReferenceServiceImpl extends PsiReferenceService {
+ @NotNull
@Override
public List<PsiReference> getReferences(@NotNull PsiElement element, @NotNull Hints hints) {
if (element instanceof ContributedReferenceHost) {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java
index a7a38fc749e5..81524ba31402 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java
index 40da8f1f28bc..a42d7a1944f0 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java
@@ -105,13 +105,17 @@ public abstract class DocumentCommitProcessor {
final long startDocModificationTimeStamp = document.getModificationStamp();
final FileElement myTreeElementBeingReparsedSoItWontBeCollected = ((PsiFileImpl)file).calcTreeElement();
final CharSequence chars = document.getImmutableCharSequence();
+ final CharSequence oldPsiText = myTreeElementBeingReparsedSoItWontBeCollected.getChars();
+ final TextRange changedPsiRange = getChangedPsiRange(file, oldPsiText, chars);
+ if (changedPsiRange == null) {
+ return null;
+ }
+
final Boolean data = document.getUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY);
if (data != null) {
document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, null);
file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, data);
}
- final CharSequence oldPsiText = myTreeElementBeingReparsedSoItWontBeCollected.getChars();
- final TextRange changedPsiRange = getChangedPsiRange(file, oldPsiText, chars);
BlockSupport blockSupport = BlockSupport.getInstance(file.getProject());
final DiffLog diffLog = blockSupport.reparseRange(file, changedPsiRange, chars, task.indicator);
@@ -135,6 +139,7 @@ public abstract class DocumentCommitProcessor {
};
}
+ @Nullable
public static TextRange getChangedPsiRange(@NotNull PsiFile file, @NotNull CharSequence oldPsiText, @NotNull CharSequence newDocumentText) {
if (!file.getViewProvider().supportsIncrementalReparse(file.getLanguage())) {
return new TextRange(0, newDocumentText.length());
@@ -142,7 +147,7 @@ public abstract class DocumentCommitProcessor {
int commonPrefixLength = StringUtil.commonPrefixLength(oldPsiText, newDocumentText);
if (commonPrefixLength == newDocumentText.length() && newDocumentText.length() == oldPsiText.length()) {
- return new TextRange(0, newDocumentText.length());
+ return null;
}
int commonSuffixLength = StringUtil.commonSuffixLength(oldPsiText, newDocumentText);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
index 26e07974b6fa..3583af212528 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
@@ -20,6 +20,7 @@ import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -85,6 +86,16 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
mySmartPointerManager = (SmartPointerManagerImpl)smartPointerManager;
mySynchronizer = new PsiToDocumentSynchronizer(this, bus);
myPsiManager.addPsiTreeChangeListener(mySynchronizer);
+ bus.connect().subscribe(PsiDocumentTransactionListener.TOPIC, new PsiDocumentTransactionListener() {
+ @Override
+ public void transactionStarted(@NotNull Document document, @NotNull PsiFile file) {
+ myUncommittedDocuments.remove(document);
+ }
+
+ @Override
+ public void transactionCompleted(@NotNull Document document, @NotNull PsiFile file) {
+ }
+ });
}
@Override
@@ -158,7 +169,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
document = FileDocumentManager.getInstance().getDocument(viewProvider.getVirtualFile());
if (document != null) {
if (document.getTextLength() != file.getTextLength()) {
- String message = "Modified PSI with no document: " + file + "; physical=" + viewProvider.isPhysical();
+ String message = "Document/PSI mismatch: " + file + " (" + file.getClass() + "); physical=" + viewProvider.isPhysical();
if (document.getTextLength() + file.getTextLength() < 8096) {
message += "\n=== document ===\n" + document.getText() + "\n=== PSI ===\n" + file.getText();
}
@@ -280,7 +291,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
// run after commit actions outside write action
runAfterCommitActions(document);
- if (DebugUtil.DO_EXPENSIVE_CHECKS) {
+ if (DebugUtil.DO_EXPENSIVE_CHECKS && !ApplicationInfoImpl.isInPerformanceTest()) {
checkAllElementsValid(document, reason);
}
}
@@ -384,8 +395,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
runnable.run();
}
else {
- LOG.assertTrue(!ApplicationManager.getApplication().isReadAccessAllowed(),
- "Don't call commitAndRunReadAction inside ReadAction, it will cause a deadlock otherwise.");
+ if (ApplicationManager.getApplication().isReadAccessAllowed()) {
+ LOG.error("Don't call commitAndRunReadAction inside ReadAction, it will cause a deadlock otherwise. "+Thread.currentThread());
+ }
final Semaphore s1 = new Semaphore();
final Semaphore s2 = new Semaphore();
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java
index f77adc5796a0..a6d07ee62769 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java
@@ -251,7 +251,10 @@ public abstract class PsiElementBase extends ElementBase implements NavigatableP
@Override
public boolean isValid() {
- final PsiElement parent = getParent();
+ PsiElement parent = getParent();
+ while (parent != null && parent.getClass() == this.getClass()) {
+ parent = parent.getParent();
+ }
return parent != null && parent.isValid();
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiFileFactoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiFileFactoryImpl.java
index a24a942bcfea..1933626770dc 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiFileFactoryImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiFileFactoryImpl.java
@@ -114,6 +114,9 @@ public class PsiFileFactoryImpl extends PsiFileFactory {
final PsiFile psiFile = viewProvider.getPsi(language);
if (psiFile != null) {
if (markAsCopy) {
+ if (psiFile.getNode() == null) {
+ throw new AssertionError("No node for file " + psiFile + "; language=" + language);
+ }
markGenerated(psiFile);
}
return psiFile;
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
index 3e8c237cd458..f4d79f7370fd 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiModificationTrackerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,6 +18,7 @@ package com.intellij.psi.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.messages.MessageBus;
@@ -93,8 +94,33 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr
return myOutOfCodeBlockModificationCount.get();
}
+ private final ModificationTracker myOutOfCodeBlockModificationTracker = new ModificationTracker() {
+ @Override
+ public long getModificationCount() {
+ return getOutOfCodeBlockModificationCount();
+ }
+ };
+
+ @NotNull
+ @Override
+ public ModificationTracker getOutOfCodeBlockModificationTracker() {
+ return myOutOfCodeBlockModificationTracker;
+ }
+
@Override
public long getJavaStructureModificationCount() {
return myJavaStructureModificationCount.get();
}
+
+ private final ModificationTracker myJavaStructureModificationTracker = new ModificationTracker() {
+ @Override
+ public long getModificationCount() {
+ return getJavaStructureModificationCount();
+ }
+ };
+ @NotNull
+ @Override
+ public ModificationTracker getJavaStructureModificationTracker() {
+ return myJavaStructureModificationTracker;
+ }
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java
index 92bb374969a2..33b2593a4a52 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java
@@ -39,7 +39,7 @@ public abstract class ResolveScopeManager {
}
@NotNull
- public static GlobalSearchScope getElementUseScope(PsiElement element) {
+ public static GlobalSearchScope getElementUseScope(@NotNull PsiElement element) {
return getInstance(element.getProject()).getUseScope(element);
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java
index 386a0c2dfb3a..e847b542cee1 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/NamedObjectProviderBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,10 +47,10 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
final Map<String, List<ProviderInfo<Provider, ElementPattern>>> map = caseSensitive ? myNamesToProvidersMap : myNamesToProvidersMapInsensitive;
for (final String attributeName : names) {
- List<ProviderInfo<Provider, ElementPattern>> psiReferenceProviders = map.get(attributeName);
+ String key = caseSensitive ? attributeName : attributeName.toLowerCase();
+ List<ProviderInfo<Provider, ElementPattern>> psiReferenceProviders = map.get(key);
if (psiReferenceProviders == null) {
- String key = caseSensitive ? attributeName : attributeName.toLowerCase();
map.put(key, psiReferenceProviders = new SmartList<ProviderInfo<Provider, ElementPattern>>());
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java
index c3e852fdba3b..aa0446257495 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ProviderBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java
index d472a53a3682..5c2ea08ecda6 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceContributorEP.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java
index 8d7b62023f72..bcea41fd6ceb 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/PsiReferenceRegistrarImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java
index 214d2b3ae298..39b584f6a1ef 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -44,21 +44,25 @@ public abstract class ReferenceProvidersRegistry {
return ServiceManager.getService(ReferenceProvidersRegistry.class);
}
- public abstract PsiReferenceRegistrar getRegistrar(Language language);
+ @NotNull
+ public abstract PsiReferenceRegistrar getRegistrar(@NotNull Language language);
/**
* @see #getReferencesFromProviders(com.intellij.psi.PsiElement)
*/
@Deprecated
- public static PsiReference[] getReferencesFromProviders(PsiElement context, @NotNull Class clazz) {
+ @NotNull
+ public static PsiReference[] getReferencesFromProviders(@NotNull PsiElement context, @NotNull Class clazz) {
return getReferencesFromProviders(context, PsiReferenceService.Hints.NO_HINTS);
}
- public static PsiReference[] getReferencesFromProviders(PsiElement context) {
+ @NotNull
+ public static PsiReference[] getReferencesFromProviders(@NotNull PsiElement context) {
return getReferencesFromProviders(context, PsiReferenceService.Hints.NO_HINTS);
}
- public static PsiReference[] getReferencesFromProviders(PsiElement context, @NotNull PsiReferenceService.Hints hints) {
+ @NotNull
+ public static PsiReference[] getReferencesFromProviders(@NotNull PsiElement context, @NotNull PsiReferenceService.Hints hints) {
ProgressIndicatorProvider.checkCanceled();
PsiUtilCore.ensureValid(context);
@@ -66,5 +70,6 @@ public abstract class ReferenceProvidersRegistry {
return registry.doGetReferencesFromProviders(context, hints);
}
- protected abstract PsiReference[] doGetReferencesFromProviders(PsiElement context, PsiReferenceService.Hints hints);
+ @NotNull
+ protected abstract PsiReference[] doGetReferencesFromProviders(@NotNull PsiElement context, @NotNull PsiReferenceService.Hints hints);
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java
index 80e794d19e14..6d913a0ba816 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/ReferenceProvidersRegistryImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -80,14 +80,16 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
}
};
+ @NotNull
@Override
- public synchronized PsiReferenceRegistrarImpl getRegistrar(Language language) {
+ public synchronized PsiReferenceRegistrarImpl getRegistrar(@NotNull Language language) {
return myRegistrars.get(language);
}
+ @NotNull
@Override
- protected PsiReference[] doGetReferencesFromProviders(PsiElement context,
- PsiReferenceService.Hints hints) {
+ protected PsiReference[] doGetReferencesFromProviders(@NotNull PsiElement context,
+ @NotNull PsiReferenceService.Hints hints) {
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> providersForContextLanguage =
getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java
index 69ea3dc5dc9d..2394c04dd912 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/reference/SimpleProviderBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
index e9d2badbdb83..80d62f72d72b 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -76,7 +76,7 @@ public class BlockSupportImpl extends BlockSupport {
@Override
@NotNull
public DiffLog reparseRange(@NotNull final PsiFile file,
- TextRange changedPsiRange,
+ @NotNull TextRange changedPsiRange,
@NotNull final CharSequence newFileText,
@NotNull final ProgressIndicator indicator) {
final PsiFileImpl fileImpl = (PsiFileImpl)file;
@@ -315,7 +315,8 @@ public class BlockSupportImpl extends BlockSupport {
PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(manager);
event.setParent(scope);
event.setFile(scope.getContainingFile());
- event.setOffset(scope.getTextRange().getStartOffset());
+ TextRange range = scope.getTextRange();
+ event.setOffset(range == null ? 0 : range.getStartOffset());
event.setOldLength(scope.getTextLength());
// the "generic" event is being sent on every PSI change. It does not carry any specific info except the fact that "something has changed"
event.setGenericChange(isGenericChange);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/RecursiveTreeElementWalkingVisitor.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/RecursiveTreeElementWalkingVisitor.java
index bfc81688d8df..82d9e3998dcd 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/RecursiveTreeElementWalkingVisitor.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/RecursiveTreeElementWalkingVisitor.java
@@ -58,6 +58,7 @@ public abstract class RecursiveTreeElementWalkingVisitor extends TreeElementVisi
private final WalkingState<ASTNode> myWalkingState = new WalkingState<ASTNode>(ASTTreeGuide.instance) {
@Override
public void elementFinished(@NotNull ASTNode element) {
+ RecursiveTreeElementWalkingVisitor.this.elementFinished(element);
}
@Override
@@ -66,6 +67,9 @@ public abstract class RecursiveTreeElementWalkingVisitor extends TreeElementVisi
}
};
+ protected void elementFinished(@NotNull ASTNode element) {
+ }
+
@Override
public void visitLeaf(LeafElement leaf) {
visitNode(leaf);
diff --git a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
index c99e5d227bb2..115b91a050fd 100644
--- a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -55,6 +55,7 @@ public class ProjectScopeImpl extends GlobalSearchScope {
return false;
}
+ @NotNull
@Override
public String getDisplayName() {
return PsiBundle.message("psi.search.scope.project");
diff --git a/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java b/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java
new file mode 100644
index 000000000000..0d22e819579f
--- /dev/null
+++ b/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.stubs;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeRegistry;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.IStubFileElementType;
+
+public class CumulativeStubVersion {
+ private static final int VERSION = 27;
+
+ public static int getCumulativeVersion() {
+ int version = VERSION;
+ for (final FileType fileType : FileTypeRegistry.getInstance().getRegisteredFileTypes()) {
+ if (fileType instanceof LanguageFileType) {
+ Language l = ((LanguageFileType)fileType).getLanguage();
+ ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
+ if (parserDefinition != null) {
+ final IFileElementType type = parserDefinition.getFileNodeType();
+ if (type instanceof IStubFileElementType) {
+ version += ((IStubFileElementType)type).getStubVersion();
+ }
+ }
+ }
+
+ BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
+ if (builder != null) {
+ version += builder.getStubVersion();
+ }
+ }
+ return version;
+ }
+}
diff --git a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java
index d69e62cff2ce..284704cf3962 100644
--- a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java
+++ b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java
@@ -17,16 +17,14 @@ package com.intellij.psi.stubs;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.Key;
-import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.util.indexing.FileContent;
+import com.intellij.util.indexing.FileContentImpl;
import com.intellij.util.indexing.IndexingDataKeys;
import com.intellij.util.indexing.SubstitutedFileType;
import org.jetbrains.annotations.Nullable;
@@ -57,21 +55,8 @@ public class StubTreeBuilder {
Language l = languageFileType.getLanguage();
final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType();
- PsiFile psi = null;
CharSequence contentAsText = inputData.getContentAsText();
- Document document = FileDocumentManager.getInstance().getCachedDocument(inputData.getFile());
- if (document != null) {
- PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(inputData.getProject());
- if (psiDocumentManager.isUncommited(document)) {
- PsiFile existingPsi = psiDocumentManager.getPsiFile(document);
- if(existingPsi != null) {
- psi = existingPsi;
- }
- }
- }
- if (psi == null) {
- psi = inputData.getPsiFile();
- }
+ PsiFile psi = ((FileContentImpl)inputData).getPsiFileAccountingForUnsavedDocument();
psi = psi.getViewProvider().getStubBindingRoot();
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText);
diff --git a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
index 6cbacf0886b8..c94921b7eaeb 100644
--- a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
+++ b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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 abstract class BlockSupport {
@NotNull
public abstract DiffLog reparseRange(@NotNull PsiFile file,
- TextRange changedPsiRange,
+ @NotNull TextRange changedPsiRange,
@NotNull CharSequence newText,
@NotNull ProgressIndicator progressIndicator) throws IncorrectOperationException;
diff --git a/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java b/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java
index c90b8ad9084a..b440a43b0613 100644
--- a/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java
+++ b/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java
@@ -16,6 +16,8 @@
package com.intellij.util.indexing;
import com.intellij.lang.Language;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
@@ -25,6 +27,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.LanguageSubstitutors;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import org.jetbrains.annotations.NotNull;
@@ -129,14 +132,8 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon
}
@NotNull
- private FileType substituteFileType(VirtualFile file, FileType fileType) {
- Project project = getProject();
- return SubstitutedFileType.substituteFileType(file, fileType, project);
- }
-
- @NotNull
public FileType getSubstitutedFileType() {
- return substituteFileType(myFile, myFileType);
+ return SubstitutedFileType.substituteFileType(myFile, myFileType, getProject());
}
@TestOnly
@@ -221,4 +218,23 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon
public byte[] getHash() {
return myHash;
}
+
+ public PsiFile getPsiFileAccountingForUnsavedDocument() {
+ Document document = FileDocumentManager.getInstance().getCachedDocument(getFile());
+ PsiFile psi = null;
+ if (document != null) {
+ PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(getProject());
+ if (psiDocumentManager.isUncommited(document)) {
+ PsiFile existingPsi = psiDocumentManager.getPsiFile(document);
+ if(existingPsi != null) {
+ psi = existingPsi;
+ }
+ }
+ }
+ if (psi == null) {
+ psi = getPsiFile();
+ }
+ return psi;
+ }
+
}
diff --git a/platform/duplicates-analysis/duplicates-analysis.iml b/platform/duplicates-analysis/duplicates-analysis.iml
new file mode 100644
index 000000000000..9c2e9b7a6602
--- /dev/null
+++ b/platform/duplicates-analysis/duplicates-analysis.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="analysis-impl" exported="" />
+ <orderEntry type="module" module-name="annotations" exported="" />
+ <orderEntry type="module" module-name="extensions" exported="" />
+ <orderEntry type="module" module-name="util" exported="" />
+ <orderEntry type="module" module-name="indexing-api" exported="" />
+ <orderEntry type="module" module-name="projectModel-api" exported="" />
+ <orderEntry type="module" module-name="projectModel-impl" exported="" />
+ </component>
+</module>
+
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/AbstractMatchingVisitor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/AbstractMatchingVisitor.java
new file mode 100644
index 000000000000..0b6bd6519edd
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/AbstractMatchingVisitor.java
@@ -0,0 +1,119 @@
+package com.intellij.dupLocator;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class AbstractMatchingVisitor {
+
+ public abstract boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2);
+
+ public abstract boolean match(PsiElement element1, PsiElement element2);
+
+ protected abstract boolean doMatchInAnyOrder(NodeIterator elements, NodeIterator elements2);
+
+ public boolean matchSequentially(@NotNull PsiElement[] elements1, @NotNull PsiElement[] element2) {
+ return matchSequentially(new FilteringNodeIterator(new ArrayBackedNodeIterator(elements1), getNodeFilter()),
+ new FilteringNodeIterator(new ArrayBackedNodeIterator(element2), getNodeFilter()));
+ }
+
+ @NotNull
+ protected abstract NodeFilter getNodeFilter();
+
+ public boolean matchOptionally(@Nullable PsiElement element1, @Nullable PsiElement element2) {
+ return element1 == null && isLeftLooseMatching() ||
+ element2 == null && isRightLooseMatching() ||
+ match(element1, element2);
+ }
+
+ public boolean matchSons(final PsiElement el1, final PsiElement el2) {
+ if (el1 == null || el2 == null) return el1 == el2;
+ return matchSequentially(el1.getFirstChild(), el2.getFirstChild());
+ }
+
+ public boolean matchSonsOptionally(final PsiElement element, final PsiElement element2) {
+ if (element == null && isLeftLooseMatching()) {
+ return true;
+ }
+ if (element2 == null && isRightLooseMatching()) {
+ return true;
+ }
+ if (element == null || element2 == null) {
+ return element == element2;
+ }
+ return matchSequentiallyOptionally(element.getFirstChild(), element2.getFirstChild());
+ }
+
+ public final boolean matchSonsInAnyOrder(PsiElement element1, PsiElement element2) {
+ if (element1 == null && isLeftLooseMatching()) {
+ return true;
+ }
+ if (element2 == null && isRightLooseMatching()) {
+ return true;
+ }
+ if (element1 == null || element2 == null) {
+ return element1 == element2;
+ }
+ PsiElement e = element1.getFirstChild();
+ PsiElement e2 = element2.getFirstChild();
+ return (e == null && isLeftLooseMatching()) ||
+ (e2 == null && isRightLooseMatching()) ||
+ matchInAnyOrder(new FilteringNodeIterator(new SiblingNodeIterator(e), getNodeFilter()),
+ new FilteringNodeIterator(new SiblingNodeIterator(e2), getNodeFilter()));
+ }
+
+ public boolean matchOptionally(@NotNull PsiElement[] elements1, @NotNull PsiElement[] elements2) {
+ return (elements1.length == 0 && isLeftLooseMatching()) ||
+ (elements2.length == 0 && isRightLooseMatching()) ||
+ matchSequentially(elements1, elements2);
+ }
+
+ public final boolean matchInAnyOrder(final PsiElement[] elements, final PsiElement[] elements2) {
+ if (elements == elements2) return true;
+
+ return matchInAnyOrder(
+ new ArrayBackedNodeIterator(elements),
+ new ArrayBackedNodeIterator(elements2)
+ );
+ }
+
+ protected boolean isLeftLooseMatching() {
+ return true;
+ }
+
+ protected boolean isRightLooseMatching() {
+ return true;
+ }
+
+ public boolean matchSequentially(PsiElement el1, PsiElement el2) {
+ //if (el1==null || el2==null) return el1 == el2;
+ return matchSequentially(new FilteringNodeIterator(new SiblingNodeIterator(el1), getNodeFilter()),
+ new FilteringNodeIterator(new SiblingNodeIterator(el2), getNodeFilter()));
+ }
+
+ public boolean matchSequentiallyOptionally(PsiElement el1, PsiElement el2) {
+ return (el1 == null && isLeftLooseMatching()) ||
+ (el2 == null && isRightLooseMatching()) ||
+ matchSequentially(new FilteringNodeIterator(new SiblingNodeIterator(el1), getNodeFilter()),
+ new FilteringNodeIterator(new SiblingNodeIterator(el2), getNodeFilter()));
+ }
+
+ public final boolean matchInAnyOrder(final NodeIterator elements, final NodeIterator elements2) {
+ if ((!elements.hasNext() && isLeftLooseMatching()) ||
+ (!elements2.hasNext() && isRightLooseMatching()) ||
+ (!elements.hasNext() && !elements2.hasNext())
+ ) {
+ return true;
+ }
+
+ return doMatchInAnyOrder(elements, elements2);
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DefaultDuplocatorState.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DefaultDuplocatorState.java
new file mode 100644
index 000000000000..5468d1fbd0b3
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DefaultDuplocatorState.java
@@ -0,0 +1,65 @@
+package com.intellij.dupLocator;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.xmlb.XmlSerializer;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class DefaultDuplocatorState implements ExternalizableDuplocatorState {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.DefaultDuplocatorState");
+
+ public boolean DISTINGUISH_VARIABLES = false;
+ public boolean DISTINGUISH_FUNCTIONS = true;
+ public boolean DISTINGUISH_LITERALS = true;
+ public int LOWER_BOUND = 10;
+ public int DISCARD_COST = 0;
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ XmlSerializer.deserializeInto(this, element);
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ XmlSerializer.serializeInto(this, element);
+ }
+
+ @Override
+ public boolean distinguishRole(@NotNull PsiElementRole role) {
+ switch (role) {
+ case VARIABLE_NAME:
+ return DISTINGUISH_VARIABLES;
+
+ case FIELD_NAME:
+ return DISTINGUISH_VARIABLES;
+
+ case FUNCTION_NAME:
+ return DISTINGUISH_FUNCTIONS;
+
+ default:
+ LOG.error("Unknown role " + role);
+ return true;
+ }
+ }
+
+ @Override
+ public boolean distinguishLiterals() {
+ return DISTINGUISH_LITERALS;
+ }
+
+ @Override
+ public int getLowerBound() {
+ return LOWER_BOUND;
+ }
+
+ @Override
+ public int getDiscardCost() {
+ return DISCARD_COST;
+ }
+
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DupInfo.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DupInfo.java
new file mode 100644
index 000000000000..8828a74c3cbf
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DupInfo.java
@@ -0,0 +1,27 @@
+package com.intellij.dupLocator;
+
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.usageView.UsageInfo;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 29, 2004
+ * Time: 5:10:31 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface DupInfo {
+ int getPatterns();
+ int getPatternCost(int number);
+ int getPatternDensity(int number);
+ PsiFragment[] getFragmentOccurences(int pattern);
+ UsageInfo[] getUsageOccurences(int pattern);
+ int getFileCount(final int pattern);
+ @Nullable
+ String getTitle(int pattern);
+ @Nullable
+ String getComment(int pattern);
+
+ int getHash(final int i);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DupLocatorBundle.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DupLocatorBundle.java
new file mode 100644
index 000000000000..560995a559a5
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DupLocatorBundle.java
@@ -0,0 +1,32 @@
+package com.intellij.dupLocator;
+
+import com.intellij.CommonBundle;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+public class DupLocatorBundle {
+
+ public static String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, @NotNull Object... params) {
+ return CommonBundle.message(getBundle(), key, params);
+ }
+
+ private static Reference<ResourceBundle> ourBundle;
+ @NonNls private static final String BUNDLE = "messages.DupLocatorBundle";
+
+ private DupLocatorBundle() {
+ }
+
+ private static ResourceBundle getBundle() {
+ ResourceBundle bundle = com.intellij.reference.SoftReference.dereference(ourBundle);
+ if (bundle == null) {
+ bundle = ResourceBundle.getBundle(BUNDLE);
+ ourBundle = new SoftReference<ResourceBundle>(bundle);
+ }
+ return bundle;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfile.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfile.java
new file mode 100644
index 000000000000..56387b07bc85
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfile.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.dupLocator;
+
+import com.intellij.dupLocator.treeHash.FragmentsCollector;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.lang.Language;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Eugene.Kudelevsky
+ * Date: 15.05.2009
+ * Time: 14:53:00
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class DuplicatesProfile {
+ public static final ExtensionPointName<DuplicatesProfile> EP_NAME = ExtensionPointName.create("com.intellij.duplicates.profile");
+
+ @NotNull
+ public abstract DuplocateVisitor createVisitor(@NotNull FragmentsCollector collector);
+
+ @NotNull
+ public DuplocateVisitor createVisitor(@NotNull FragmentsCollector collector, boolean forIndexing) {
+ return createVisitor(collector);
+ }
+
+ public abstract boolean isMyLanguage(@NotNull Language language);
+
+ @NotNull
+ public abstract DuplocatorState getDuplocatorState(@NotNull Language language);
+
+ @Nullable
+ public String getComment(@NotNull DupInfo info, int index) {
+ return null;
+ }
+
+ public abstract boolean isMyDuplicate(@NotNull DupInfo info, int index);
+
+ public boolean supportIndex() {
+ return true;
+ }
+
+ private static final int FACTOR = 2;
+ private static final int MAX_COST = 7000;
+
+ public boolean shouldPutInIndex(PsiFragment fragment, int cost, DuplocatorState state) {
+ final int lowerBound = state.getLowerBound();
+ if (cost < FACTOR*lowerBound || cost > MAX_COST) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Nullable
+ public static DuplicatesProfile findProfileForLanguage(@NotNull Language language) {
+ return findProfileForLanguage(EP_NAME.getExtensions(), language);
+ }
+
+ @NotNull
+ public static DuplicatesProfile[] getAllProfiles() {
+ return Extensions.getExtensions(EP_NAME);
+ }
+
+ @Nullable
+ public static DuplicatesProfile findProfileForLanguage(DuplicatesProfile[] profiles, @NotNull Language language) {
+ for (DuplicatesProfile profile : profiles) {
+ if (profile.isMyLanguage(language)) {
+ return profile;
+ }
+ }
+
+ return null;
+ }
+
+ @NotNull
+ public Language getLanguage(@NotNull PsiElement element) {
+ return element.getLanguage();
+ }
+
+ @Nullable
+ public PsiElementRole getRole(@NotNull PsiElement element) {
+ return null;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfileCache.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfileCache.java
new file mode 100644
index 000000000000..db9ff875e9bf
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplicatesProfileCache.java
@@ -0,0 +1,76 @@
+package com.intellij.dupLocator;
+
+import com.intellij.dupLocator.treeHash.FragmentsCollector;
+import com.intellij.lang.Language;
+import com.intellij.openapi.extensions.Extensions;
+import gnu.trove.TIntObjectHashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Eugene.Kudelevsky
+ * Date: May 18, 2009
+ * Time: 7:39:35 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class DuplicatesProfileCache {
+ private static final Map<DupInfo, TIntObjectHashMap<DuplicatesProfile>> ourProfileCache = new HashMap<DupInfo, TIntObjectHashMap<DuplicatesProfile>>();
+
+ private DuplicatesProfileCache() {
+ }
+
+ public static void clear(@NotNull DupInfo info) {
+ ourProfileCache.remove(info);
+ }
+
+ @Nullable
+ public static DuplicatesProfile getProfile(@NotNull DupInfo dupInfo, int index) {
+ TIntObjectHashMap<DuplicatesProfile> patternCache = ourProfileCache.get(dupInfo);
+ if (patternCache == null) {
+ patternCache = new TIntObjectHashMap<DuplicatesProfile>();
+ ourProfileCache.put(dupInfo, patternCache);
+ }
+ DuplicatesProfile result = patternCache.get(index);
+ if (result == null) {
+ DuplicatesProfile[] profiles = Extensions.getExtensions(DuplicatesProfile.EP_NAME);
+ DuplicatesProfile theProfile = null;
+ for (DuplicatesProfile profile : profiles) {
+ if (profile.isMyDuplicate(dupInfo, index)) {
+ theProfile = profile;
+ break;
+ }
+ }
+ result = theProfile == null ? NULL_PROFILE : theProfile;
+ patternCache.put(index, result);
+ }
+ return result == NULL_PROFILE ? null : result;
+ }
+
+ private static final DuplicatesProfile NULL_PROFILE = new DuplicatesProfile() {
+ @NotNull
+ @Override
+ public DuplocateVisitor createVisitor(@NotNull FragmentsCollector collector) {
+ return null;
+ }
+
+ @Override
+ public boolean isMyLanguage(@NotNull Language language) {
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public DuplocatorState getDuplocatorState(@NotNull Language language) {
+ return null;
+ }
+
+ @Override
+ public boolean isMyDuplicate(@NotNull DupInfo info, int index) {
+ return false;
+ }
+ };
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocateVisitor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocateVisitor.java
new file mode 100644
index 000000000000..b603bc2a650c
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocateVisitor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.dupLocator;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+* Created by IntelliJ IDEA.
+* User: Eugene.Kudelevsky
+* Date: 15.05.2009
+* Time: 15:09:22
+* To change this template use File | Settings | File Templates.
+*/
+public interface DuplocateVisitor {
+ void visitNode(@NotNull PsiElement node);
+
+ /**
+ * Is not invoked when index is used
+ * @see com.intellij.dupLocator.DuplicatesProfile#supportIndex()
+ */
+ void hashingFinished();
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorSettings.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorSettings.java
new file mode 100644
index 000000000000..66983d376eb6
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorSettings.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.dupLocator;
+
+import com.intellij.openapi.components.*;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Apr 8, 2004
+ * Time: 2:47:43 PM
+ * To change this template use File | Settings | File Templates.
+ */
+@State(
+ name="DuplocatorSettings",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.APP_CONFIG + "/other.xml"
+ )}
+)
+public class DuplocatorSettings implements PersistentStateComponent<DuplocatorSettings> {
+ public boolean DISTINGUISH_VARIABLES = false;
+ public boolean DISTINGUISH_FIELDS = false;
+ public boolean DISTINGUISH_METHODS = true;
+ public boolean DISTINGUISH_TYPES = true;
+ public boolean DISTINGUISH_LITERALS = true;
+ public boolean CHECK_VALIDITY = true;
+ public int LOWER_BOUND = 10;
+ public int DISCARD_COST = 0;
+ public Set<String> SELECTED_PROFILES = new HashSet<String>();
+ public String LAST_SELECTED_LANGUAGE = null;
+
+ public static DuplocatorSettings getInstance() {
+ return ServiceManager.getService(DuplocatorSettings.class);
+ }
+
+ @Override
+ public DuplocatorSettings getState() {
+ return this;
+ }
+
+ @Override
+ public void loadState(DuplocatorSettings object) {
+ XmlSerializerUtil.copyBean(object, this);
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorState.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorState.java
new file mode 100644
index 000000000000..9ef1dc19ce98
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/DuplocatorState.java
@@ -0,0 +1,12 @@
+package com.intellij.dupLocator;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface DuplocatorState {
+
+ int getLowerBound();
+
+ int getDiscardCost();
+
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/ExternalizableDuplocatorState.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/ExternalizableDuplocatorState.java
new file mode 100644
index 000000000000..703f0b8515e0
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/ExternalizableDuplocatorState.java
@@ -0,0 +1,14 @@
+package com.intellij.dupLocator;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface ExternalizableDuplocatorState extends DuplocatorState, JDOMExternalizable {
+
+ boolean distinguishRole(@NotNull PsiElementRole role);
+
+ boolean distinguishLiterals();
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java
new file mode 100644
index 000000000000..92fc5b3b3175
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java
@@ -0,0 +1,90 @@
+package com.intellij.dupLocator;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.containers.HashMap;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+@State(
+ name = "MultiLanguageDuplocatorSettings",
+ storages = {
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/duplocatorSettings.xml")
+ }
+)
+public class MultilanguageDuplocatorSettings implements PersistentStateComponent<Element> {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.MultiLanguageDuplocatorSettings");
+
+ private final Map<String, ExternalizableDuplocatorState> mySettingsMap = new HashMap<String, ExternalizableDuplocatorState>();
+
+ public static MultilanguageDuplocatorSettings getInstance() {
+ return ServiceManager.getService(MultilanguageDuplocatorSettings.class);
+ }
+
+ public void registerState(@NotNull Language language, @NotNull ExternalizableDuplocatorState state) {
+ synchronized (mySettingsMap) {
+ mySettingsMap.put(language.getDisplayName(), state);
+ }
+ }
+
+ public ExternalizableDuplocatorState getState(@NotNull Language language) {
+ synchronized (mySettingsMap) {
+ return mySettingsMap.get(language.getDisplayName());
+ }
+ }
+
+ @Override
+ public Element getState() {
+ synchronized (mySettingsMap) {
+ final Element element = new Element("state");
+ for (String name : mySettingsMap.keySet()) {
+ final Element child = element.addContent("object");
+ element.setAttribute("language", name);
+ final JDOMExternalizable settingsObject = mySettingsMap.get(name);
+ try {
+ settingsObject.writeExternal(child);
+ }
+ catch (WriteExternalException e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+ return element;
+ }
+ }
+
+ @Override
+ public void loadState(Element state) {
+ synchronized (mySettingsMap) {
+ if (state == null) {
+ return;
+ }
+
+ for (Object o : state.getChildren("object")) {
+ final Element objectElement = (Element)o;
+ final String language = objectElement.getAttributeValue("language");
+
+ if (language != null) {
+ final JDOMExternalizable stateObject = mySettingsMap.get(language);
+ if (stateObject != null) {
+ try {
+ stateObject.readExternal(objectElement);
+ }
+ catch (InvalidDataException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/NodeSpecificHasher.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/NodeSpecificHasher.java
new file mode 100644
index 000000000000..687c2ec41269
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/NodeSpecificHasher.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 24-Jan-2007
+ */
+package com.intellij.dupLocator;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public abstract class NodeSpecificHasher implements DuplocateVisitor {
+ /**
+ * getNodeHash is called on each node, which was returned by getNodeChildren method
+ */
+ public abstract int getNodeHash(PsiElement node);
+
+ /**
+ * Used in TreeComparator and TreeHashers
+ * @return -1 if you want to ignore this node.
+ * Note: only nodes with equal values can be considered as equal (areNodesEqual will be called further)
+ * This cost will be used when calculating compound nodes. See DuplocatorSettings#LOWER_BOUND
+ */
+ public abstract int getNodeCost(PsiElement node);
+
+ /**
+ * List all of the nodes to process within TreeComparator
+ */
+ public abstract List<PsiElement> getNodeChildren(PsiElement node);
+
+ /**
+ * This is dual function to getNodeCost, checks whether 2 nodes with same costs are really equal
+ */
+ public abstract boolean areNodesEqual(@NotNull PsiElement node1, @NotNull PsiElement node2);
+
+ public boolean areTreesEqual(@NotNull PsiElement root1, @NotNull PsiElement root2, int discardCost) {
+ return TreeComparator.areEqual(root1, root2, this, discardCost);
+ }
+
+ public abstract boolean checkDeep(PsiElement node1, PsiElement node2);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/PsiElementRole.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/PsiElementRole.java
new file mode 100644
index 000000000000..09f043c9b6e2
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/PsiElementRole.java
@@ -0,0 +1,5 @@
+package com.intellij.dupLocator;
+
+public enum PsiElementRole {
+ VARIABLE_NAME, FIELD_NAME, FUNCTION_NAME
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeComparator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeComparator.java
new file mode 100644
index 000000000000..c18199dcab37
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeComparator.java
@@ -0,0 +1,45 @@
+package com.intellij.dupLocator;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 26, 2004
+ * Time: 3:48:37 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TreeComparator {
+ private TreeComparator() {
+ }
+
+ public static boolean areEqual(@NotNull PsiElement x, @NotNull PsiElement y, NodeSpecificHasher hasher, int discardCost) {
+ final int costX = hasher.getNodeCost(x);
+ final int costY = hasher.getNodeCost(y);
+ if (costX == -1 || costY == -1) return false;
+ if (costX < discardCost || costY < discardCost) {
+ return true;
+ }
+
+ if (hasher.areNodesEqual(x, y)) {
+ if (!hasher.checkDeep(x, y)) return true;
+ List<PsiElement> xSons = hasher.getNodeChildren(x);
+ List<PsiElement> ySons = hasher.getNodeChildren(y);
+
+ if (xSons.size() == ySons.size()) {
+ for (int i = 0; i < ySons.size(); i++) {
+ if (!areEqual(xSons.get(i), ySons.get(i), hasher, discardCost)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeHasher.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeHasher.java
new file mode 100644
index 000000000000..2d07de9737ab
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/TreeHasher.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 07-Mar-2007
+ */
+package com.intellij.dupLocator;
+
+import com.intellij.psi.PsiElement;
+
+public interface TreeHasher {
+ void hash(PsiElement root, NodeSpecificHasher hasher);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/_DupInfo.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/_DupInfo.java
new file mode 100644
index 000000000000..1980a6667609
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/_DupInfo.java
@@ -0,0 +1,25 @@
+package com.intellij.dupLocator;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.util.containers.HashSet;
+
+import java.util.TreeSet;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 18, 2004
+ * Time: 8:48:33 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface _DupInfo {
+ TreeSet<Integer> getPatterns();
+
+ int getHeight(Integer pattern);
+
+ int getDensity(Integer pattern);
+
+ HashSet<PsiElement> getOccurencies(Integer pattern);
+
+ String toString(Integer pattern);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptor.java
new file mode 100644
index 000000000000..91286f10f63d
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptor.java
@@ -0,0 +1,18 @@
+package com.intellij.dupLocator.equivalence;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface EquivalenceDescriptor {
+ List<PsiElement[]> getCodeBlocks();
+
+ List<SingleChildDescriptor> getSingleChildDescriptors();
+
+ List<MultiChildDescriptor> getMultiChildDescriptors();
+
+ List<Object> getConstants();
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorBuilder.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorBuilder.java
new file mode 100644
index 000000000000..cf7ab456d29a
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorBuilder.java
@@ -0,0 +1,111 @@
+package com.intellij.dupLocator.equivalence;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class EquivalenceDescriptorBuilder implements EquivalenceDescriptor {
+ private final List<SingleChildDescriptor> mySingleChildDescriptors = new ArrayList<SingleChildDescriptor>();
+ private final List<MultiChildDescriptor> myMultiChildDescriptors = new ArrayList<MultiChildDescriptor>();
+ private final List<Object> myConstants = new ArrayList<Object>();
+ private final List<PsiElement[]> myCodeBlocks = new ArrayList<PsiElement[]>();
+
+ public EquivalenceDescriptorBuilder() {
+ }
+
+ public List<SingleChildDescriptor> getSingleChildDescriptors() {
+ return mySingleChildDescriptors;
+ }
+
+ public List<MultiChildDescriptor> getMultiChildDescriptors() {
+ return myMultiChildDescriptors;
+ }
+
+ public List<Object> getConstants() {
+ return myConstants;
+ }
+
+ @NotNull
+ public List<PsiElement[]> getCodeBlocks() {
+ return myCodeBlocks;
+ }
+
+ public EquivalenceDescriptorBuilder codeBlock(@Nullable PsiElement[] block) {
+ myCodeBlocks.add(block);
+ return this;
+ }
+
+ public EquivalenceDescriptorBuilder element(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.DEFAULT, element);
+ }
+
+ public EquivalenceDescriptorBuilder elements(@Nullable PsiElement[] elements) {
+ return add(MultiChildDescriptor.MyType.DEFAULT, elements);
+ }
+
+ public EquivalenceDescriptorBuilder children(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.CHILDREN, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder optionally(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.OPTIONALLY, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder optionallyInPattern(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.OPTIONALLY_IN_PATTERN, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder optionally(@Nullable PsiElement[] elements) {
+ return add(MultiChildDescriptor.MyType.OPTIONALLY, elements);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder optionallyInPattern(@Nullable PsiElement[] elements) {
+ return add(MultiChildDescriptor.MyType.OPTIONALLY_IN_PATTERN, elements);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder childrenOptionally(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.CHILDREN_OPTIONALLY, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder childrenOptionallyInPattern(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.CHILDREN_OPTIONALLY_IN_PATTERN, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder inAnyOrder(PsiElement[] elements) {
+ return add(MultiChildDescriptor.MyType.IN_ANY_ORDER, elements);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder childrenInAnyOrder(@Nullable PsiElement element) {
+ return add(SingleChildDescriptor.MyType.CHILDREN_IN_ANY_ORDER, element);
+ }
+
+ @NotNull
+ public EquivalenceDescriptorBuilder constant(@Nullable Object constant) {
+ myConstants.add(constant);
+ return this;
+ }
+
+ private EquivalenceDescriptorBuilder add(MultiChildDescriptor.MyType type, PsiElement[] elements) {
+ myMultiChildDescriptors.add(new MultiChildDescriptor(type, elements));
+ return this;
+ }
+
+ private EquivalenceDescriptorBuilder add(SingleChildDescriptor.MyType type, PsiElement element) {
+ mySingleChildDescriptors.add(new SingleChildDescriptor(type, element));
+ return this;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorProvider.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorProvider.java
new file mode 100644
index 000000000000..275281237a02
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/EquivalenceDescriptorProvider.java
@@ -0,0 +1,42 @@
+package com.intellij.dupLocator.equivalence;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class EquivalenceDescriptorProvider {
+ public static final ExtensionPointName<EquivalenceDescriptorProvider> EP_NAME =
+ ExtensionPointName.create("com.intellij.equivalenceDescriptorProvider");
+
+ // for using in tests only !!!
+ public static boolean ourUseDefaultEquivalence = false;
+
+ public abstract boolean isMyContext(@NotNull PsiElement context);
+
+ @Nullable
+ public abstract EquivalenceDescriptor buildDescriptor(@NotNull PsiElement element);
+
+ // by default only PsiWhitespace ignored
+ public TokenSet getIgnoredTokens() {
+ return TokenSet.EMPTY;
+ }
+
+ @Nullable
+ public static EquivalenceDescriptorProvider getInstance(@NotNull PsiElement context) {
+ if (ourUseDefaultEquivalence) {
+ return null;
+ }
+
+ for (EquivalenceDescriptorProvider descriptorProvider : EP_NAME.getExtensions()) {
+ if (descriptorProvider.isMyContext(context)) {
+ return descriptorProvider;
+ }
+ }
+ return null;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/MultiChildDescriptor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/MultiChildDescriptor.java
new file mode 100644
index 000000000000..0043bad9fc94
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/MultiChildDescriptor.java
@@ -0,0 +1,35 @@
+package com.intellij.dupLocator.equivalence;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class MultiChildDescriptor {
+ private final MyType myType;
+ private final PsiElement[] myElements;
+
+ public MultiChildDescriptor(@NotNull MyType type, @Nullable PsiElement[] elements) {
+ myType = type;
+ myElements = elements;
+ }
+
+ @NotNull
+ public MyType getType() {
+ return myType;
+ }
+
+ @Nullable
+ public PsiElement[] getElements() {
+ return myElements;
+ }
+
+ public static enum MyType {
+ DEFAULT,
+ OPTIONALLY,
+ OPTIONALLY_IN_PATTERN,
+ IN_ANY_ORDER
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/SingleChildDescriptor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/SingleChildDescriptor.java
new file mode 100644
index 000000000000..0692cd49e05b
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/equivalence/SingleChildDescriptor.java
@@ -0,0 +1,38 @@
+package com.intellij.dupLocator.equivalence;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class SingleChildDescriptor {
+ private final MyType myType;
+ private final PsiElement myElement;
+
+ public SingleChildDescriptor(@NotNull MyType type, @Nullable PsiElement element) {
+ myType = type;
+ myElement = element;
+ }
+
+ @NotNull
+ public MyType getType() {
+ return myType;
+ }
+
+ @Nullable
+ public PsiElement getElement() {
+ return myElement;
+ }
+
+ public static enum MyType {
+ DEFAULT,
+ OPTIONALLY,
+ OPTIONALLY_IN_PATTERN,
+ CHILDREN,
+ CHILDREN_OPTIONALLY,
+ CHILDREN_OPTIONALLY_IN_PATTERN,
+ CHILDREN_IN_ANY_ORDER
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java
new file mode 100644
index 000000000000..cacbcf89aca0
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.dupLocator.index;
+
+import com.intellij.dupLocator.DuplicatesProfile;
+import com.intellij.dupLocator.DuplocateVisitor;
+import com.intellij.dupLocator.DuplocatorState;
+import com.intellij.dupLocator.treeHash.FragmentsCollector;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.lang.Language;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.SystemProperties;
+import com.intellij.util.indexing.*;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.DataInputOutputUtil;
+import com.intellij.util.io.EnumeratorIntegerDescriptor;
+import com.intellij.util.io.KeyDescriptor;
+import gnu.trove.THashMap;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @by Maxim.Mossienko on 12/11/13.
+ */
+public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayList> implements PsiDependentIndex {
+ static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.duplicates.online.calculation",
+ isEnabledByDefault());
+
+ private static boolean isEnabledByDefault() {
+ Application application = ApplicationManager.getApplication();
+ return application.isInternal() && !application.isUnitTestMode();
+ }
+
+ @NonNls public static final ID<Integer, TIntArrayList> NAME = ID.create("DuplicatesIndex");
+ private static final int myBaseVersion = 9;
+
+ private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
+ @Override
+ public boolean acceptInput(@NotNull final VirtualFile file) {
+ return ourEnabled && findDuplicatesProfile(file.getFileType()) != null;
+ }
+ };
+
+ private final DataExternalizer<TIntArrayList> myValueExternalizer = new DataExternalizer<TIntArrayList>() {
+ @Override
+ public void save(@NotNull DataOutput out, TIntArrayList list) throws IOException {
+ if (list.size() == 1) DataInputOutputUtil.writeINT(out, list.getQuick(0));
+ else {
+ DataInputOutputUtil.writeINT(out, -list.size());
+ int prev = 0;
+ for (int i = 0, len = list.size(); i < len; ++i) {
+ int value = list.getQuick(i);
+ DataInputOutputUtil.writeINT(out, value - prev);
+ prev = value;
+ }
+ }
+ }
+
+ @Override
+ public TIntArrayList read(@NotNull DataInput in) throws IOException {
+ int capacityOrValue = DataInputOutputUtil.readINT(in);
+ if (capacityOrValue >= 0) {
+ TIntArrayList list = new TIntArrayList(1);
+ list.add(capacityOrValue);
+ return list;
+ }
+ capacityOrValue = -capacityOrValue;
+ TIntArrayList list = new TIntArrayList(capacityOrValue);
+ int prev = 0;
+ while(capacityOrValue-- > 0) {
+ int value = DataInputOutputUtil.readINT(in) + prev;
+ list.add(value);
+ prev = value;
+ }
+ return list;
+ }
+ };
+
+ private final DataIndexer<Integer, TIntArrayList, FileContent> myIndexer = new DataIndexer<Integer, TIntArrayList, FileContent>() {
+ @Override
+ @NotNull
+ public Map<Integer, TIntArrayList> map(@NotNull final FileContent inputData) {
+ FileType type = inputData.getFileType();
+
+ DuplicatesProfile profile = findDuplicatesProfile(type);
+ if (profile == null) return Collections.emptyMap();
+
+ MyFragmentsCollector collector = new MyFragmentsCollector(profile, ((LanguageFileType)type).getLanguage());
+ DuplocateVisitor visitor = profile.createVisitor(collector, true);
+ visitor.visitNode(((FileContentImpl)inputData).getPsiFileAccountingForUnsavedDocument());
+
+ return collector.getMap();
+ }
+ };
+
+ @Nullable
+ public static DuplicatesProfile findDuplicatesProfile(FileType fileType) {
+ if (!(fileType instanceof LanguageFileType)) return null;
+ Language language = ((LanguageFileType)fileType).getLanguage();
+ DuplicatesProfile profile = DuplicatesProfile.findProfileForLanguage(language);
+ return profile != null && profile.supportIndex() ? profile : null;
+ }
+
+ @Override
+ public int getVersion() {
+ return myBaseVersion + (ourEnabled ? 0xFF : 0);
+ }
+
+ @Override
+ public boolean dependsOnFileContent() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public ID<Integer,TIntArrayList> getName() {
+ return NAME;
+ }
+
+ @NotNull
+ @Override
+ public DataIndexer<Integer, TIntArrayList, FileContent> getIndexer() {
+ return myIndexer;
+ }
+
+ @NotNull
+ @Override
+ public DataExternalizer<TIntArrayList> getValueExternalizer() {
+ return myValueExternalizer;
+ }
+
+ @NotNull
+ @Override
+ public KeyDescriptor<Integer> getKeyDescriptor() {
+ return EnumeratorIntegerDescriptor.INSTANCE;
+ }
+
+ @NotNull
+ @Override
+ public FileBasedIndex.InputFilter getInputFilter() {
+ return myInputFilter;
+ }
+
+ //private static final TracingData myTracingData = new TracingData();
+ private static final TracingData myTracingData = null;
+
+ private static class MyFragmentsCollector implements FragmentsCollector {
+ private final THashMap<Integer, TIntArrayList> myMap = new THashMap<Integer, TIntArrayList>();
+ private final DuplicatesProfile myProfile;
+ private final DuplocatorState myDuplocatorState;
+
+ public MyFragmentsCollector(DuplicatesProfile profile, Language language) {
+ myProfile = profile;
+ myDuplocatorState = profile.getDuplocatorState(language);
+ }
+
+ @Override
+ public void add(int hash, int cost, @Nullable PsiFragment frag) {
+ if (!isIndexedFragment(frag, cost, myProfile, myDuplocatorState)) {
+ return;
+ }
+
+ if (myTracingData != null) myTracingData.record(hash, cost, frag);
+
+ TIntArrayList list = myMap.get(hash);
+ if (list == null) { myMap.put(hash, list = new TIntArrayList()); }
+ list.add(frag.getStartOffset());
+ }
+
+ public THashMap<Integer,TIntArrayList> getMap() {
+ return myMap;
+ }
+ }
+
+ static boolean isIndexedFragment(@Nullable PsiFragment frag, int cost, DuplicatesProfile profile, DuplocatorState duplocatorState) {
+ if(frag == null) return false;
+ return profile.shouldPutInIndex(frag, cost, duplocatorState);
+ }
+
+ @TestOnly
+ public static boolean setEnabled(boolean value) {
+ boolean old = ourEnabled;
+ ourEnabled = value;
+ return old;
+ }
+
+ @Override
+ public boolean hasSnapshotMapping() {
+ return true;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java
new file mode 100644
index 000000000000..f015fe21213b
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java
@@ -0,0 +1,134 @@
+package com.intellij.dupLocator.index;
+
+import com.intellij.codeInspection.*;
+import com.intellij.dupLocator.DuplicatesProfile;
+import com.intellij.dupLocator.DuplocatorState;
+import com.intellij.dupLocator.treeHash.FragmentsCollector;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileWithId;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.SmartList;
+import com.intellij.util.indexing.FileBasedIndex;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntIntHashMap;
+import gnu.trove.TIntObjectHashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class DuplicatesInspectionBase extends LocalInspectionTool {
+ @Nullable
+ @Override
+ public ProblemDescriptor[] checkFile(@NotNull final PsiFile psiFile, @NotNull final InspectionManager manager, final boolean isOnTheFly) {
+ final VirtualFile virtualFile = psiFile.getVirtualFile();
+ if (!(virtualFile instanceof VirtualFileWithId) || /*!isOnTheFly || */!DuplicatesIndex.ourEnabled) return ProblemDescriptor.EMPTY_ARRAY;
+ final DuplicatesProfile profile = DuplicatesIndex.findDuplicatesProfile(psiFile.getFileType());
+ if (profile == null) return ProblemDescriptor.EMPTY_ARRAY;
+
+ final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage());
+ final SmartList<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>();
+
+ final TreeMap<Integer, TextRange> reportedRanges = new TreeMap<Integer, TextRange>();
+ final TIntObjectHashMap<VirtualFile> reportedFiles = new TIntObjectHashMap<VirtualFile>();
+ final TIntObjectHashMap<PsiElement> reportedPsi = new TIntObjectHashMap<PsiElement>();
+ final TIntIntHashMap reportedOffsetInOtherFiles = new TIntIntHashMap();
+ final TIntIntHashMap fragmentSize = new TIntIntHashMap();
+
+ profile.createVisitor(new FragmentsCollector() {
+ @Override
+ public void add(int hash, final int cost, @Nullable final PsiFragment frag) {
+ if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) {
+ return;
+ }
+
+ ProgressManager.checkCanceled();
+ FileBasedIndex.getInstance().processValues(DuplicatesIndex.NAME, hash, null, new FileBasedIndex.ValueProcessor<TIntArrayList>() {
+ final ProjectFileIndex myProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(psiFile.getProject());
+ @Override
+ public boolean process(final VirtualFile file, final TIntArrayList list) {
+ for(int i = 0, len = list.size(); i < len; ++i) {
+ ProgressManager.checkCanceled();
+
+ int value = list.getQuick(i);
+
+ if (myProjectFileIndex.isInSource(virtualFile) && !myProjectFileIndex.isInSource(file)) return true;
+ if (!myProjectFileIndex.isInSource(virtualFile) && myProjectFileIndex.isInSource(file)) return true;
+ final int startOffset = frag.getStartOffset();
+ final int endOffset = frag.getEndOffset();
+ if (file.equals(virtualFile) && value >= startOffset && value < endOffset) continue;
+
+ PsiElement[] elements = frag.getElements();
+ PsiElement target = elements[0];
+ TextRange rangeInElement = null;
+ if (elements.length > 1) {
+ PsiElement firstElement = elements[0];
+ target = firstElement.getParent();
+ PsiElement lastElement = elements[elements.length - 1];
+ rangeInElement = new TextRange(
+ elements[0].getStartOffsetInParent(),
+ lastElement.getStartOffsetInParent() + lastElement.getTextLength()
+ );
+ }
+
+ Integer fragmentStartOffsetInteger = startOffset;
+ SortedMap<Integer,TextRange> map = reportedRanges.subMap(fragmentStartOffsetInteger, endOffset);
+ int newFragmentSize = !map.isEmpty() ? 0:1;
+
+ Iterator<Integer> iterator = map.keySet().iterator();
+ while(iterator.hasNext()) {
+ Integer next = iterator.next();
+ iterator.remove();
+ reportedFiles.remove(next);
+ reportedOffsetInOtherFiles.remove(next);
+ reportedPsi.remove(next);
+ newFragmentSize += fragmentSize.remove(next);
+ }
+
+ reportedRanges.put(fragmentStartOffsetInteger, rangeInElement);
+ reportedFiles.put(fragmentStartOffsetInteger, file);
+ reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value);
+ reportedPsi.put(fragmentStartOffsetInteger, target);
+ fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize);
+
+ return false;
+ }
+ return true;
+ }
+ }, GlobalSearchScope.projectScope(psiFile.getProject()));
+ }
+ }, true).visitNode(psiFile);
+
+ for(Map.Entry<Integer, TextRange> entry:reportedRanges.entrySet()) {
+ final Integer offset = entry.getKey();
+ // todo 3 statements constant
+ if (fragmentSize.get(offset) < 3) continue;
+ final VirtualFile file = reportedFiles.get(offset);
+ String message = "Found duplicated code in " + file.getPath();
+
+ PsiElement targetElement = reportedPsi.get(offset);
+ TextRange rangeInElement = entry.getValue();
+ final int offsetInOtherFile = reportedOffsetInOtherFiles.get(offset);
+
+ LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile);
+ ProblemDescriptor descriptor = manager
+ .createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.WEAK_WARNING, isOnTheFly, fix);
+ descriptors.add(descriptor);
+ }
+
+ return descriptors.isEmpty() ? null : descriptors.toArray(new ProblemDescriptor[descriptors.size()]);
+ }
+
+ protected LocalQuickFix createNavigateToDupeFix(@NotNull VirtualFile file, int offsetInOtherFile) {
+ return null;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/TracingData.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/TracingData.java
new file mode 100644
index 000000000000..758e747b38c1
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/TracingData.java
@@ -0,0 +1,103 @@
+package com.intellij.dupLocator.index;
+
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.openapi.util.ShutDownTracker;
+import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.io.EnumeratorIntegerDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import gnu.trove.TIntIntHashMap;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+* Created by Maxim.Mossienko on 3/19/2014.
+*/
+public class TracingData {
+ private static final String tracingDataLocation = "E:\\ultimate\\system\\occurrences";
+ private final PersistentHashMap<Integer, Integer> keys;
+ private final ScheduledThreadPoolExecutor pool = ConcurrencyUtil.newSingleScheduledThreadExecutor("My flushing thread");
+
+ private final AtomicInteger maxHash = new AtomicInteger();
+ private final AtomicInteger maxValue = new AtomicInteger();
+ private ScheduledFuture<?> flushingFuture;
+
+ TracingData() {
+ PersistentHashMap<Integer, Integer> lkeys = null;
+ try {
+ lkeys = createOrOpenMap();
+ flushingFuture = pool.scheduleWithFixedDelay(new Runnable() {
+ @Override
+ public void run() {
+ if (keys.isDirty() && !keys.isClosed()) {
+ keys.force();
+ }
+ }
+ }, 5, 5, TimeUnit.SECONDS);
+ ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
+ @Override
+ public void run() {
+ flushingFuture.cancel(false);
+ }
+ });
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ keys = lkeys;
+ }
+
+ private static PersistentHashMap<Integer, Integer> createOrOpenMap() throws IOException {
+ return new PersistentHashMap<Integer, Integer>(new File(tracingDataLocation), EnumeratorIntegerDescriptor.INSTANCE, EnumeratorIntegerDescriptor.INSTANCE);
+ }
+
+ public void record(int hash, int cost, PsiFragment frag) {
+ //System.out.println(frag.getElements()[0].getText());
+
+ if (keys != null) {
+ try {
+ Integer integer = keys.get(hash);
+ int value = integer != null ? integer + 1 : 1;
+ keys.put(hash, value);
+ int currentMaxValue = maxValue.get();
+ while (value > currentMaxValue) {
+ if (maxValue.compareAndSet(currentMaxValue, value)) {
+ maxHash.set(hash);
+ System.out.println(maxValue + "," + maxHash + ","+frag.getElements()[0].getText());
+ break;
+ }
+ currentMaxValue = maxValue.get();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ PersistentHashMap<Integer, Integer> lkeys = createOrOpenMap();
+ List<Integer> mapping = (List<Integer>)lkeys.getAllKeysWithExistingMapping();
+ System.out.println(mapping.size());
+ final TIntIntHashMap map = new TIntIntHashMap(mapping.size());
+ for(Integer i:mapping) map.put(i, lkeys.get(i));
+
+ Collections.sort(mapping, new Comparator<Integer>() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return map.get(o2) - map.get(o1);
+ }
+ });
+
+ for(int i = 0; i < 500; ++i) {
+ //System.out.println(mapping.get(i) + ",");
+ System.out.println(mapping.get(i) + ":" + map.get(mapping.get(i)));
+ }
+ lkeys.close();
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/ArrayBackedNodeIterator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/ArrayBackedNodeIterator.java
new file mode 100644
index 000000000000..fa54077afec4
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/ArrayBackedNodeIterator.java
@@ -0,0 +1,43 @@
+package com.intellij.dupLocator.iterators;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Node iterator over array
+ */
+public final class ArrayBackedNodeIterator extends NodeIterator {
+ private final PsiElement[] nodes;
+ private int index;
+
+ public ArrayBackedNodeIterator(final PsiElement[] _nodes) {
+ nodes = _nodes;
+ index = 0;
+ }
+
+ public boolean hasNext() {
+ return index < nodes.length;
+ }
+
+ public void rewind(int number) {
+ index -= number;
+ }
+
+ public PsiElement current() {
+ if (index < nodes.length)
+ return nodes[index];
+
+ return null;
+ }
+
+ public void advance() {
+ ++index;
+ }
+
+ public void rewind() {
+ --index;
+ }
+
+ public void reset() {
+ index = 0;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/CountingNodeIterator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/CountingNodeIterator.java
new file mode 100644
index 000000000000..3b0736eb4e1a
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/CountingNodeIterator.java
@@ -0,0 +1,44 @@
+package com.intellij.dupLocator.iterators;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Iterator that limits processing of specified number of nodes
+ */
+public final class CountingNodeIterator extends NodeIterator {
+ private int index;
+ private final int max;
+ private final NodeIterator delegate;
+
+ public CountingNodeIterator(int _max, NodeIterator _iterator) {
+ max = _max;
+ delegate = _iterator;
+ }
+
+ public boolean hasNext() {
+ return index < max && delegate.hasNext();
+ }
+
+ public PsiElement current() {
+ if (index < max)
+ return delegate.current();
+ return null;
+ }
+
+ public void advance() {
+ ++index;
+ delegate.advance();
+ }
+
+ public void rewind() {
+ if (index >0) {
+ -- index;
+ delegate.rewind();
+ }
+ }
+
+ public void reset() {
+ index = 0;
+ delegate.reset();
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/FilteringNodeIterator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/FilteringNodeIterator.java
new file mode 100644
index 000000000000..a06c65fa1563
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/FilteringNodeIterator.java
@@ -0,0 +1,61 @@
+package com.intellij.dupLocator.iterators;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+
+/**
+ * Iterator over important nodes
+ */
+public class FilteringNodeIterator extends NodeIterator {
+ private final NodeIterator delegate;
+ private final NodeFilter filter;
+
+ private void advanceToNext() {
+ while (delegate.hasNext() && filter.accepts(delegate.current())) {
+ delegate.advance();
+ }
+ }
+
+ private void rewindToPrevious() {
+ while (filter.accepts(delegate.current())) {
+ delegate.rewind();
+ }
+ }
+
+ public FilteringNodeIterator(NodeIterator iterator, NodeFilter filter) {
+ delegate = iterator;
+ this.filter = filter;
+ advanceToNext();
+ }
+
+ public boolean hasNext() {
+ return delegate.hasNext() && !filter.accepts(delegate.current());
+ }
+
+ public void rewind(int number) {
+ while(number > 0) {
+ delegate.rewind();
+ rewindToPrevious();
+ --number;
+ }
+ }
+
+ public PsiElement current() {
+ return delegate.current();
+ }
+
+ public void advance() {
+ delegate.advance();
+ advanceToNext();
+ }
+
+ public void rewind() {
+ delegate.rewind();
+ rewindToPrevious();
+ }
+
+ public void reset() {
+ delegate.reset();
+ advanceToNext();
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/NodeIterator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/NodeIterator.java
new file mode 100644
index 000000000000..acd9d9f43574
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/NodeIterator.java
@@ -0,0 +1,30 @@
+package com.intellij.dupLocator.iterators;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Node iterator interface
+ */
+public abstract class NodeIterator implements Cloneable {
+ public abstract boolean hasNext();
+ public abstract PsiElement current();
+ public abstract void advance();
+ public abstract void rewind();
+ public abstract void reset();
+
+ public void rewind(int number) {
+ while(number > 0) {
+ --number;
+ rewind();
+ }
+ }
+
+ public NodeIterator clone() {
+ try {
+ return (NodeIterator) super.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/SiblingNodeIterator.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/SiblingNodeIterator.java
new file mode 100644
index 000000000000..f28e4078b961
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/iterators/SiblingNodeIterator.java
@@ -0,0 +1,38 @@
+package com.intellij.dupLocator.iterators;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Iterates over siblings
+ */
+public final class SiblingNodeIterator extends NodeIterator {
+ private final PsiElement start;
+ private PsiElement current;
+ private PsiElement previous;
+
+ public SiblingNodeIterator(final PsiElement element) {
+ previous = current = start = element;
+ }
+
+ public boolean hasNext() {
+ return current!=null;
+ }
+
+ public PsiElement current() {
+ return current;
+ }
+
+ public void advance() {
+ previous = current;
+ current = current != null ? current.getNextSibling():null;
+ }
+
+ public void rewind() {
+ current = previous;
+ previous = current != null ? current.getPrevSibling():null;
+ }
+
+ public void reset() {
+ previous = current = start;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/AbstractTreeHasher.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/AbstractTreeHasher.java
new file mode 100644
index 000000000000..d020651f055d
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/AbstractTreeHasher.java
@@ -0,0 +1,209 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.NodeSpecificHasher;
+import com.intellij.dupLocator.TreeHasher;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.lang.Language;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.psi.PsiAnchor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db, oleg
+ * Date: Mar 26, 2004
+ * Time: 4:44:13 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class AbstractTreeHasher implements TreeHasher {
+ protected final boolean myForIndexing;
+ protected final FragmentsCollector myCallBack;
+
+ public AbstractTreeHasher(FragmentsCollector cb, boolean forIndexing) {
+ myCallBack = cb;
+ myForIndexing = forIndexing;
+ }
+
+ public final void hash(@NotNull final PsiElement root, @NotNull final NodeSpecificHasher hasher) {
+ hash(root, null, hasher);
+ }
+
+ protected abstract TreeHashResult hash(@NotNull PsiElement root, PsiFragment upper, @NotNull NodeSpecificHasher hasher);
+
+ /**
+ * Computes element hash using children hashes.
+ * Creates only single PsiFragment.
+ */
+ protected TreeHashResult computeElementHash(@NotNull final PsiElement root, final PsiFragment upper, final NodeSpecificHasher hasher) {
+ if (myForIndexing) {
+ return TreeHashingUtils.computeElementHashForIndexing(this, myCallBack, root, upper, hasher);
+ }
+ ProgressManager.checkCanceled();
+ final List<PsiElement> children = hasher.getNodeChildren(root);
+ final int size = children.size();
+ final int[] childHashes = new int[size];
+ final int[] childCosts = new int[size];
+
+ final PsiFragment fragment = buildFragment(hasher, root, getCost(root));
+
+ if (upper != null) {
+ fragment.setParent(upper);
+ }
+
+ if (size == 0 && !(root instanceof LeafElement)) {
+ return new TreeHashResult(hasher.getNodeHash(root), hasher.getNodeCost(root), fragment);
+ }
+
+ for (int i = 0; i < size; i++) {
+ final TreeHashResult res = hash(children.get(i), fragment, hasher);
+ childHashes[i] = res.getHash();
+ childCosts[i] = res.getCost();
+ }
+
+ final int c = hasher.getNodeCost(root) + vector(childCosts);
+ final int h1 = hasher.getNodeHash(root);
+
+ final int discardCost = getDiscardCost(root);
+
+ for (int i = 0; i < size; i++) {
+ if (childCosts[i] <= discardCost && ignoreChildHash(children.get(i))) {
+ childHashes[i] = 0;
+ }
+ }
+ final int h = h1 + vector(childHashes);
+
+ if (myCallBack != null) {
+ myCallBack.add(h, c, fragment);
+ }
+
+ return new TreeHashResult(h, c, fragment);
+ }
+
+ protected TreePsiFragment buildFragment(NodeSpecificHasher hasher, PsiElement root,int cost) {
+ if (myForIndexing) {
+ return new TreePsiFragment(hasher, root, cost) {
+ @Override
+ protected PsiAnchor createAnchor(PsiElement element) {
+ return new PsiAnchor.HardReference(element);
+ }
+
+ @Override
+ protected Language calcLanguage(PsiElement element) {
+ return null; // for performance
+ }
+ };
+ }
+ return new TreePsiFragment(hasher, root, cost);
+ }
+
+ protected TreePsiFragment buildFragment(NodeSpecificHasher hasher, List<? extends PsiElement> elements, int from, int to) {
+ if (myForIndexing) {
+ return new TreePsiFragment(hasher, elements, from, to) {
+ @Override
+ protected PsiAnchor createAnchor(PsiElement element) {
+ return new PsiAnchor.HardReference(element);
+ }
+
+ @Override
+ protected Language calcLanguage(PsiElement element) {
+ return null; // for performance
+ }
+ };
+ }
+ return new TreePsiFragment(hasher, elements, from, to);
+ }
+
+ protected abstract int getDiscardCost(PsiElement root);
+
+ protected boolean ignoreChildHash(PsiElement element) {
+ return false;
+ }
+
+ protected TreeHashResult hashCodeBlock(final List<? extends PsiElement> statements,
+ final PsiFragment upper,
+ final NodeSpecificHasher hasher) {
+ return hashCodeBlock(statements, upper, hasher, false);
+ }
+
+ /**
+ * Creates PsiFragments using given statements with their hashes
+ */
+ protected TreeHashResult hashCodeBlock(final List<? extends PsiElement> statements,
+ final PsiFragment upper,
+ final NodeSpecificHasher hasher,
+ boolean forceHash) {
+ final int statementsSize = statements.size();
+ if (statementsSize == 1) {
+ return hash(statements.get(0), upper, hasher);
+ }
+ if (statementsSize > 0) {
+ // Here we compute all the possible code fragments using statements
+ if (statementsSize < 20 || forceHash) { //todo should be configurable
+ final PsiFragment[] frags = new PsiFragment[statementsSize];
+
+ final PsiFragment fragment = buildFragment(hasher, statements, 0, statementsSize - 1);
+ fragment.setParent(upper);
+
+ // Fill all the statements costs and hashes
+ final int[] hashes = new int[statementsSize];
+ final int[] costs = new int[statementsSize];
+ for (int i = 0; i < statementsSize; i++) {
+ final TreeHashResult res = hash(statements.get(i), null, hasher);
+ hashes[i] = res.getHash();
+ costs[i] = res.getCost();
+ frags[i] = res.getFragment();
+ }
+
+ if (myCallBack != null) {
+ final PsiFragment[] parents = new PsiFragment[statementsSize]; //parent(end) = [beg, end]
+ for (int beg = 0; beg < statementsSize; beg++) {
+ int hash = 0;
+ int cost = 0;
+ for (int end = beg; end < statementsSize && end - beg < 20; end++) {
+ hash = 31 * hash + hashes[end];
+ cost += costs[end];
+ final PsiFragment curr =
+ beg == end
+ ? frags[beg]
+ : beg == 0 && end == statementsSize - 1 ? fragment : buildFragment(hasher, statements, beg, end);
+ if (beg > 0) {
+ curr.setParent(parents[end]); //[beg, end].setParent([beg - 1, end])
+ }
+ parents[end] = curr;
+ if (end > beg) {
+ parents[end - 1].setParent(curr);//[beg, end - 1].setParent([beg, end])
+ }
+ myCallBack.add(hash, cost, curr);
+ }
+ }
+ }
+ return new TreeHashResult(vector(hashes, 31), vector(costs), fragment);
+ }
+ }
+ return new TreeHashResult(1, 0, buildFragment(hasher, statements, 0, statementsSize - 1));
+ }
+
+ protected int getCost(final PsiElement root){
+ return 0;
+ }
+
+ public static int vector(int[] args) {
+ return vector(args, 1);
+ }
+
+ public static int vector(int[] args, int mult) {
+ int sum = 0;
+ for (int arg : args) {
+ sum = mult * sum + arg;
+ }
+ return sum;
+ }
+
+ public boolean shouldAnonymize(PsiElement root, NodeSpecificHasher hasher) {
+ return false;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesMatchingVisitor.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesMatchingVisitor.java
new file mode 100644
index 000000000000..5df14b3abcc6
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesMatchingVisitor.java
@@ -0,0 +1,228 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.*;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.containers.HashMap;
+import gnu.trove.TIntObjectHashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class DuplicatesMatchingVisitor extends AbstractMatchingVisitor {
+ private final NodeSpecificHasherBase myNodeSpecificHasher;
+ private final NodeFilter myNodeFilter;
+ private final int myDiscardCost;
+ private final TreeHasherBase myTreeHasher;
+ private final Map<PsiElement, TreeHashResult> myPsiElement2HashAndCost = new HashMap<PsiElement, TreeHashResult>();
+
+ public DuplicatesMatchingVisitor(NodeSpecificHasherBase nodeSpecificHasher,
+ @NotNull NodeFilter nodeFilter,
+ int discardCost) {
+ myNodeSpecificHasher = nodeSpecificHasher;
+ myNodeFilter = nodeFilter;
+ myDiscardCost = discardCost;
+ myTreeHasher = new TreeHasherBase(null, myNodeSpecificHasher.getDuplicatesProfile(), discardCost, false) {
+ @Override
+ protected TreeHashResult hash(@NotNull PsiElement root, PsiFragment upper, @NotNull NodeSpecificHasher hasher) {
+ TreeHashResult result = myPsiElement2HashAndCost.get(root);
+ if (result == null) {
+ result = super.hash(root, upper, hasher);
+ myPsiElement2HashAndCost.put(root, result);
+ }
+ return result;
+ }
+ };
+ }
+
+ @Override
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2) {
+ while (true) {
+ if (!nodes.hasNext() || !nodes2.hasNext()) {
+ return !nodes.hasNext() && !nodes2.hasNext();
+ }
+
+ skipIfNeccessary(nodes, nodes2);
+ skipIfNeccessary(nodes2, nodes);
+
+ if (!nodes.hasNext() || !nodes2.hasNext()) {
+ return !nodes.hasNext() && !nodes2.hasNext();
+ }
+
+ if (!match(nodes.current(), nodes2.current())) {
+ return false;
+ }
+
+ nodes.advance();
+ nodes2.advance();
+ }
+ }
+
+ private static void skipIfNeccessary(NodeIterator nodes, NodeIterator nodes2) {
+ while (DuplocatorUtil.shouldSkip(nodes2.current(), nodes.current())) {
+ nodes2.advance();
+ }
+ }
+
+ @Override
+ public boolean match(PsiElement element1, PsiElement element2) {
+ if (element1 == null || element2 == null) {
+ return element1 == element2;
+ }
+
+ if (myDiscardCost > 0) {
+ final int cost1 = myTreeHasher.hash(element1, null, myNodeSpecificHasher).getCost();
+ final int cost2 = myTreeHasher.hash(element2, null, myNodeSpecificHasher).getCost();
+
+ if (cost1 < myDiscardCost || cost2 < myDiscardCost) {
+ return true;
+ }
+ }
+
+ final DuplicatesProfileBase duplicatesProfile = myNodeSpecificHasher.getDuplicatesProfile();
+
+ final PsiElementRole role1 = duplicatesProfile.getRole(element1);
+ final PsiElementRole role2 = duplicatesProfile.getRole(element2);
+
+ final Set<PsiElementRole> skippedRoles = EnumSet.noneOf(PsiElementRole.class);
+ final ExternalizableDuplocatorState duplocatorState =
+ duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element1));
+
+ for (PsiElementRole role : PsiElementRole.values()) {
+ if (!duplocatorState.distinguishRole(role)) {
+ skippedRoles.add(role);
+ }
+ }
+
+ if (role1 == role2 && skippedRoles.contains(role1)) {
+ return true;
+ }
+
+ final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element1);
+ EquivalenceDescriptor descriptor1 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element1) : null;
+ EquivalenceDescriptor descriptor2 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element2) : null;
+
+ PsiElement newElement1 = DuplocatorUtil.skipNodeIfNeccessary(element1, descriptor1, myNodeFilter);
+ PsiElement newElement2 = DuplocatorUtil.skipNodeIfNeccessary(element2, descriptor2, myNodeFilter);
+
+ if (newElement1 != element1 || newElement2 != element2) {
+ return match(newElement1, newElement2);
+ }
+
+ if (!element1.getClass().equals(element2.getClass())) {
+ return false;
+ }
+
+ if (descriptor1 != null && descriptor2 != null) {
+ return DuplocatorUtil.match(descriptor1, descriptor2, this, skippedRoles, duplicatesProfile);
+ }
+
+ if (element1 instanceof LeafElement) {
+ IElementType elementType1 = ((LeafElement)element1).getElementType();
+ IElementType elementType2 = ((LeafElement)element2).getElementType();
+
+ if (!duplocatorState.distinguishLiterals() &&
+ duplicatesProfile.getLiterals().contains(elementType1) &&
+ duplicatesProfile.getLiterals().contains(elementType2)) {
+ return true;
+ }
+ return element1.getText().equals(element2.getText());
+ }
+
+ if (element1.getFirstChild() == null && element1.getTextLength() == 0) {
+ return element2.getFirstChild() == null && element2.getTextLength() == 0;
+ }
+
+ return matchSequentially(new FilteringNodeIterator(new SiblingNodeIterator(element1.getFirstChild()), getNodeFilter()),
+ new FilteringNodeIterator(new SiblingNodeIterator(element2.getFirstChild()), getNodeFilter()));
+ }
+
+ @Override
+ protected boolean doMatchInAnyOrder(NodeIterator it1, NodeIterator it2) {
+ final List<PsiElement> elements1 = new ArrayList<PsiElement>();
+ final List<PsiElement> elements2 = new ArrayList<PsiElement>();
+
+ while (it1.hasNext()) {
+ final PsiElement element = it1.current();
+ if (element != null) {
+ elements1.add(element);
+ }
+ it1.advance();
+ }
+
+ while (it2.hasNext()) {
+ final PsiElement element = it2.current();
+ if (element != null) {
+ elements2.add(element);
+ }
+ it2.advance();
+ }
+
+ if (elements1.size() != elements2.size()) {
+ return false;
+ }
+
+ final TIntObjectHashMap<List<PsiElement>> hash2element = new TIntObjectHashMap<List<PsiElement>>(elements1.size());
+
+ for (PsiElement element : elements1) {
+ final TreeHashResult result = myTreeHasher.hash(element, null, myNodeSpecificHasher);
+ if (result != null) {
+ final int hash = result.getHash();
+
+ List<PsiElement> list = hash2element.get(hash);
+ if (list == null) {
+ list = new ArrayList<PsiElement>();
+ hash2element.put(hash, list);
+ }
+ list.add(element);
+ }
+ }
+
+ for (PsiElement element : elements2) {
+ final TreeHashResult result = myTreeHasher.hash(element, null, myNodeSpecificHasher);
+ if (result != null) {
+ final int hash = result.getHash();
+ final List<PsiElement> list = hash2element.get(hash);
+ if (list == null) {
+ return false;
+ }
+
+ boolean found = false;
+ for (Iterator<PsiElement> it = list.iterator(); it.hasNext();) {
+ if (match(element, it.next())) {
+ it.remove();
+ found = true;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+
+ if (list.size() == 0) {
+ hash2element.remove(hash);
+ }
+ }
+ }
+
+ return hash2element.size() == 0;
+ }
+
+ @NotNull
+ @Override
+ protected NodeFilter getNodeFilter() {
+ return myNodeFilter;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesProfileBase.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesProfileBase.java
new file mode 100644
index 000000000000..d416f29b0646
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplicatesProfileBase.java
@@ -0,0 +1,55 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.*;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.lang.Language;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class DuplicatesProfileBase extends DuplicatesProfile {
+ @NotNull
+ @Override
+ public DuplocateVisitor createVisitor(@NotNull FragmentsCollector collector) {
+ return new NodeSpecificHasherBase(DuplocatorSettings.getInstance(), collector, this);
+ }
+
+ public abstract int getNodeCost(@NotNull PsiElement element);
+
+ public TokenSet getLiterals() {
+ return TokenSet.EMPTY;
+ }
+
+ @Override
+ @NotNull
+ public ExternalizableDuplocatorState getDuplocatorState(@NotNull Language language) {
+ return DuplocatorUtil.registerAndGetState(language);
+ }
+
+ @Override
+ public boolean isMyDuplicate(@NotNull DupInfo info, int index) {
+ PsiFragment[] fragments = info.getFragmentOccurences(index);
+ if (fragments.length > 0) {
+ PsiElement[] elements = fragments[0].getElements();
+ if (elements.length > 0) {
+ final PsiElement first = elements[0];
+ if (first != null) {
+ Language language = first.getLanguage();
+ return isMyLanguage(language);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Nullable
+ public PsiElementRole getRole(@NotNull PsiElement element) {
+ return null;
+ }
+
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java
new file mode 100644
index 000000000000..03685d181afc
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java
@@ -0,0 +1,383 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.*;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.openapi.components.PathMacroManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.usageView.UsageInfo;
+import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
+import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TIntObjectProcedure;
+import gnu.trove.TObjectIntHashMap;
+import gnu.trove.TObjectIntIterator;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 26, 2004
+ * Time: 7:11:30 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class DuplocatorHashCallback implements FragmentsCollector {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.treeHash.DuplocatorHashCallback");
+
+ private TIntObjectHashMap<List<List<PsiFragment>>> myDuplicates;
+ private final int myBound;
+ private boolean myReadOnly = false;
+ private final int myDiscardCost;
+
+ public DuplocatorHashCallback(int bound, int discardCost) {
+ myDuplicates = new TIntObjectHashMap<List<List<PsiFragment>>>();
+ myBound = bound;
+ myDiscardCost = discardCost;
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public DuplocatorHashCallback(final int bound, final int discardCost, final boolean readOnly) {
+ this(bound, discardCost);
+ myReadOnly = readOnly;
+ }
+
+ public DuplocatorHashCallback(int lowerBound) {
+ this(lowerBound, 0);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void setReadOnly(final boolean readOnly) {
+ myReadOnly = readOnly;
+ }
+
+ // used in TeamCity
+ @SuppressWarnings("UnusedParameters")
+ public void add(int hash, int cost, PsiFragment frag, NodeSpecificHasher visitor) {
+ forceAdd(hash, cost, frag);
+ }
+
+ private void forceAdd(int hash, int cost, PsiFragment frag) {
+ if (frag == null) { //fake fragment
+ myDuplicates.put(hash, new ArrayList<List<PsiFragment>>());
+ return;
+ }
+
+ frag.setCost(cost);
+
+ List<List<PsiFragment>> fragments = myDuplicates.get(hash);
+
+ if (fragments == null) {
+ if (!myReadOnly) { //do not add new hashcodes
+ List<List<PsiFragment>> list = new ArrayList<List<PsiFragment>>();
+ List<PsiFragment> listf = new ArrayList<PsiFragment>();
+
+ listf.add(frag);
+ list.add(listf);
+
+ myDuplicates.put(hash, list);
+ }
+
+ return;
+ }
+
+ boolean found = false;
+
+ final PsiElement[] elements = frag.getElements();
+
+ int discardCost = 0;
+
+ if (myDiscardCost >= 0) {
+ discardCost = myDiscardCost;
+ }
+ else {
+ final DuplocatorState state = DuplocatorUtil.getDuplocatorState(frag);
+ if (state != null) {
+ discardCost = state.getDiscardCost();
+ }
+ }
+
+ for (Iterator<List<PsiFragment>> i = fragments.iterator(); i.hasNext() && !found; ) {
+ List<PsiFragment> fi = i.next();
+ PsiFragment aFrag = fi.get(0);
+
+ if (aFrag.isEqual(elements, discardCost)) {
+ boolean skip = false;
+
+ for (Iterator<PsiFragment> frags = fi.iterator(); frags.hasNext() && !skip; ) {
+ skip = frag.intersectsWith(frags.next());
+ if (skip) {
+ frags.remove();
+ }
+ }
+
+ fi.add(frag);
+
+ found = true;
+ }
+ }
+
+ if (!found) {
+ List<PsiFragment> newFrags = new ArrayList<PsiFragment>();
+ newFrags.add(frag);
+
+ fragments.add(newFrags);
+ }
+ }
+
+ @Override
+ public void add(int hash, int cost, PsiFragment frag) {
+ int bound;
+
+ if (myBound >= 0) {
+ bound = myBound;
+ }
+ else {
+ final DuplocatorState duplocatorState = DuplocatorUtil.getDuplocatorState(frag);
+ if (duplocatorState == null) {
+ return;
+ }
+ bound = duplocatorState.getLowerBound();
+ }
+
+ if (cost >= bound) {
+ forceAdd(hash, cost, frag);
+ }
+ }
+
+ public DupInfo getInfo() {
+ final TObjectIntHashMap<PsiFragment[]> duplicateList = new TObjectIntHashMap<PsiFragment[]>();
+
+ myDuplicates.forEachEntry(new TIntObjectProcedure<List<List<PsiFragment>>>() {
+ public boolean execute(final int hash, final List<List<PsiFragment>> listList) {
+ for (List<PsiFragment> list : listList) {
+ final int len = list.size();
+ if (len > 1) {
+ PsiFragment[] filtered = new PsiFragment[len];
+ int idx = 0;
+ for (final PsiFragment fragment : list) {
+ fragment.markDuplicate();
+ filtered[idx++] = fragment;
+ }
+ duplicateList.put(filtered, hash);
+ }
+ }
+
+ return true;
+ }
+ });
+
+ myDuplicates = null;
+
+ for (TObjectIntIterator<PsiFragment[]> dups = duplicateList.iterator(); dups.hasNext(); ) {
+ dups.advance();
+ PsiFragment[] fragments = dups.key();
+ LOG.assertTrue(fragments.length > 1);
+ boolean nested = false;
+ for (PsiFragment fragment : fragments) {
+ if (fragment.isNested()) {
+ nested = true;
+ break;
+ }
+ }
+
+ if (nested) {
+ dups.remove();
+ }
+ }
+
+ final Object[] duplicates = duplicateList.keys();
+
+ Arrays.sort(duplicates, new Comparator<Object>() {
+ public int compare(Object x, Object y) {
+ return ((PsiFragment[])y)[0].getCost() - ((PsiFragment[])x)[0].getCost();
+ }
+ });
+
+ return new DupInfo() {
+ private final TIntObjectHashMap<GroupNodeDescription> myPattern2Description = new TIntObjectHashMap<GroupNodeDescription>();
+
+ public int getPatterns() {
+ return duplicates.length;
+ }
+
+ public int getPatternCost(int number) {
+ return ((PsiFragment[])duplicates[number])[0].getCost();
+ }
+
+ public int getPatternDensity(int number) {
+ return ((PsiFragment[])duplicates[number]).length;
+ }
+
+ public PsiFragment[] getFragmentOccurences(int pattern) {
+ return (PsiFragment[])duplicates[pattern];
+ }
+
+ public UsageInfo[] getUsageOccurences(int pattern) {
+ PsiFragment[] occs = getFragmentOccurences(pattern);
+ UsageInfo[] infos = new UsageInfo[occs.length];
+
+ for (int i = 0; i < infos.length; i++) {
+ infos[i] = occs[i].getUsageInfo();
+ }
+
+ return infos;
+ }
+
+ public int getFileCount(final int pattern) {
+ if (myPattern2Description.containsKey(pattern)) {
+ return myPattern2Description.get(pattern).getFilesCount();
+ }
+ return cacheGroupNodeDescription(pattern).getFilesCount();
+ }
+
+ private GroupNodeDescription cacheGroupNodeDescription(final int pattern) {
+ final Set<PsiFile> files = new HashSet<PsiFile>();
+ final PsiFragment[] occurencies = getFragmentOccurences(pattern);
+ for (PsiFragment occurency : occurencies) {
+ final PsiFile file = occurency.getFile();
+ if (file != null) {
+ files.add(file);
+ }
+ }
+ final int fileCount = files.size();
+ final PsiFile psiFile = occurencies[0].getFile();
+ DuplicatesProfile profile = DuplicatesProfileCache.getProfile(this, pattern);
+ String comment = profile != null ? profile.getComment(this, pattern) : "";
+ final GroupNodeDescription description = new GroupNodeDescription(fileCount, psiFile != null ? psiFile.getName() : "unknown", comment);
+ myPattern2Description.put(pattern, description);
+ return description;
+ }
+
+ @Nullable
+ public String getTitle(int pattern) {
+ if (getFileCount(pattern) == 1) {
+ if (myPattern2Description.containsKey(pattern)) {
+ return myPattern2Description.get(pattern).getTitle();
+ }
+ return cacheGroupNodeDescription(pattern).getTitle();
+ }
+ return null;
+ }
+
+
+ @Nullable
+ public String getComment(int pattern) {
+ if (getFileCount(pattern) == 1) {
+ if (myPattern2Description.containsKey(pattern)) {
+ return myPattern2Description.get(pattern).getComment();
+ }
+ return cacheGroupNodeDescription(pattern).getComment();
+ }
+ return null;
+ }
+
+ public int getHash(final int i) {
+ return duplicateList.get((PsiFragment[])duplicates[i]);
+ }
+ };
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ public void report(String path, final Project project) throws IOException {
+ int[] hashCodes = myDuplicates.keys();
+ FileWriter fileWriter = null;
+ //fragments
+ try {
+ fileWriter = new FileWriter(path + File.separator + "fragments.xml");
+ PrettyPrintWriter writer = new PrettyPrintWriter(fileWriter);
+ writer.startNode("root");
+ for (int hash : hashCodes) {
+ List<List<PsiFragment>> dupList = myDuplicates.get(hash);
+ writer.startNode("hash");
+ writer.addAttribute("val", String.valueOf(hash));
+ for (final List<PsiFragment> psiFragments : dupList) {
+ writeFragments(psiFragments, writer, project, false);
+ }
+ writer.endNode();
+ }
+ writer.endNode(); //root node
+ writer.flush();
+ }
+ finally {
+ if (fileWriter != null) {
+ fileWriter.close();
+ }
+ }
+
+ fileWriter = null;
+ //duplicates
+ try {
+ fileWriter = new FileWriter(path + File.separator + "duplicates.xml");
+ PrettyPrintWriter writer = new PrettyPrintWriter(fileWriter);
+ writer.startNode("root");
+ final DupInfo info = getInfo();
+ final int patterns = info.getPatterns();
+ for (int i = 0; i < patterns; i++) {
+ writer.startNode("duplicate");
+ writer.addAttribute("cost", String.valueOf(info.getPatternCost(i)));
+ writer.addAttribute("hash", String.valueOf(info.getHash(i)));
+ writeFragments(Arrays.asList(info.getFragmentOccurences(i)), writer, project, true);
+ writer.endNode();
+ }
+ writer.endNode(); //root node
+ writer.flush();
+ }
+ finally {
+ if (fileWriter != null) {
+ fileWriter.close();
+ }
+ }
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ private static void writeFragments(final List<PsiFragment> psiFragments,
+ final PrettyPrintWriter writer,
+ Project project,
+ final boolean shouldWriteOffsets) {
+ final PathMacroManager macroManager = PathMacroManager.getInstance(project);
+ final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
+
+ for (PsiFragment fragment : psiFragments) {
+ final PsiFile psiFile = fragment.getFile();
+ final VirtualFile virtualFile = psiFile != null ? psiFile.getVirtualFile() : null;
+ if (virtualFile != null) {
+ writer.startNode("fragment");
+ writer.addAttribute("file", macroManager.collapsePath(virtualFile.getUrl()));
+ if (shouldWriteOffsets) {
+ final Document document = documentManager.getDocument(psiFile);
+ LOG.assertTrue(document != null);
+ int startOffset = fragment.getStartOffset();
+ final int line = document.getLineNumber(startOffset);
+ writer.addAttribute("line", String.valueOf(line));
+ final int lineStartOffset = document.getLineStartOffset(line);
+ if (StringUtil.isEmptyOrSpaces(document.getText().substring(lineStartOffset, startOffset))) {
+ startOffset = lineStartOffset;
+ }
+ writer.addAttribute("start", String.valueOf(startOffset));
+ writer.addAttribute("end", String.valueOf(fragment.getEndOffset()));
+ if (fragment.containsMultipleFragments()) {
+ final int[][] offsets = fragment.getOffsets();
+ for (int[] offset : offsets) {
+ writer.startNode("offset");
+ writer.addAttribute("start", String.valueOf(offset[0]));
+ writer.addAttribute("end", String.valueOf(offset[1]));
+ writer.endNode();
+ }
+ }
+ }
+ writer.endNode();
+ }
+ }
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/FragmentsCollector.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/FragmentsCollector.java
new file mode 100644
index 000000000000..f6b25a4020b8
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/FragmentsCollector.java
@@ -0,0 +1,11 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.util.PsiFragment;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface FragmentsCollector {
+ void add(int hash, int cost, @Nullable PsiFragment frag);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/GroupNodeDescription.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/GroupNodeDescription.java
new file mode 100644
index 000000000000..ddaa6928b6e9
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/GroupNodeDescription.java
@@ -0,0 +1,34 @@
+package com.intellij.dupLocator.treeHash;
+
+/**
+* Created by IntelliJ IDEA.
+* User: Eugene.Kudelevsky
+* Date: 15.05.2009
+* Time: 16:24:08
+* To change this template use File | Settings | File Templates.
+*/
+public class GroupNodeDescription {
+ private final int myFilesCount;
+ private final String myTitle;
+ private final String myComment;
+
+
+ public GroupNodeDescription(final int filesCount, final String title, final String comment) {
+ myFilesCount = filesCount;
+ myTitle = title;
+ myComment = comment;
+ }
+
+
+ public int getFilesCount() {
+ return myFilesCount;
+ }
+
+ public String getTitle() {
+ return myTitle;
+ }
+
+ public String getComment() {
+ return myComment;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/NodeSpecificHasherBase.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/NodeSpecificHasherBase.java
new file mode 100644
index 000000000000..ef2e92fad8be
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/NodeSpecificHasherBase.java
@@ -0,0 +1,145 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.DuplocatorSettings;
+import com.intellij.dupLocator.NodeSpecificHasher;
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.lang.Language;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiErrorElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class NodeSpecificHasherBase extends NodeSpecificHasher {
+ private final TreeHasherBase myTreeHasher;
+ private final DuplocatorSettings mySettings;
+ private final DuplicatesProfileBase myDuplicatesProfile;
+
+ private final NodeFilter myNodeFilter = new NodeFilter() {
+ @Override
+ public boolean accepts(PsiElement element) {
+ return DuplocatorUtil.isIgnoredNode(element) || isToSkipAsLiteral(element);
+ }
+ };
+ protected final boolean myForIndexing;
+
+ private boolean isToSkipAsLiteral(PsiElement element) {
+ return isLiteral(element) &&
+ !myDuplicatesProfile.getDuplocatorState(myDuplicatesProfile.getLanguage(element)).distinguishLiterals();
+ }
+
+ public NodeSpecificHasherBase(@NotNull final DuplocatorSettings settings,
+ @NotNull FragmentsCollector callback,
+ @NotNull DuplicatesProfileBase duplicatesProfile) {
+ this(settings, callback, duplicatesProfile, false);
+ }
+
+ public NodeSpecificHasherBase(@NotNull final DuplocatorSettings settings,
+ @NotNull FragmentsCollector callback,
+ @NotNull DuplicatesProfileBase duplicatesProfile,
+ boolean forIndexing) {
+ myTreeHasher = new TreeHasherBase(callback, duplicatesProfile, forIndexing ? 0:-1, forIndexing);
+ mySettings = settings;
+ myDuplicatesProfile = duplicatesProfile;
+ myForIndexing = forIndexing;
+ }
+
+ @NotNull
+ public NodeFilter getNodeFilter() {
+ return myNodeFilter;
+ }
+
+ @Override
+ public int getNodeHash(PsiElement node) {
+ if (node == null) {
+ return 0;
+ }
+ if (node instanceof PsiWhiteSpace || node instanceof PsiErrorElement) {
+ return 0;
+ }
+ else if (node instanceof LeafElement) {
+ if (isToSkipAsLiteral(node)) {
+ return 0;
+ }
+ return node.getText().hashCode();
+
+ }
+ return node.getClass().getName().hashCode();
+ }
+
+ private boolean isLiteral(PsiElement node) {
+ if (node instanceof LeafElement) {
+ final IElementType elementType = ((LeafElement)node).getElementType();
+ if (myDuplicatesProfile.getLiterals().contains(elementType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int getNodeCost(PsiElement node) {
+ return node != null ? myDuplicatesProfile.getNodeCost(node) : 0;
+ }
+
+ @Override
+ public List<PsiElement> getNodeChildren(PsiElement node) {
+ final List<PsiElement> result = new ArrayList<PsiElement>();
+
+ final FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(node.getFirstChild()), myNodeFilter);
+ while (it.hasNext()) {
+ result.add(it.current());
+ it.advance();
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean areNodesEqual(@NotNull PsiElement node1, @NotNull PsiElement node2) {
+ return false;
+ }
+
+ @Override
+ public boolean areTreesEqual(@NotNull PsiElement root1, @NotNull PsiElement root2, int discardCost) {
+ if (root1 == root2) {
+ return true;
+ }
+ return new DuplicatesMatchingVisitor(this, myNodeFilter, discardCost).match(root1, root2);
+ }
+
+ @NotNull
+ public DuplicatesProfileBase getDuplicatesProfile() {
+ return myDuplicatesProfile;
+ }
+
+ @Override
+ public boolean checkDeep(PsiElement node1, PsiElement node2) {
+ // todo: try to optimize this
+ return true;
+ }
+
+ @Override
+ public void visitNode(@NotNull PsiElement node) {
+ final Language language = node.getLanguage();
+ if ((myForIndexing || mySettings.SELECTED_PROFILES.contains(language.getDisplayName())) &&
+ myDuplicatesProfile.isMyLanguage(language)) {
+
+ myTreeHasher.hash(node, this);
+ }
+ }
+
+ @Override
+ public void hashingFinished() {
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashResult.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashResult.java
new file mode 100644
index 000000000000..a8994e9f8c39
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashResult.java
@@ -0,0 +1,30 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.util.PsiFragment;
+
+/**
+* @author oleg
+*/
+public class TreeHashResult {
+ int myHash;
+ int myCost;
+ PsiFragment myFragment;
+
+ public TreeHashResult(final int hash, final int cost, final PsiFragment fragment) {
+ myHash = hash;
+ myCost = cost;
+ myFragment = fragment;
+ }
+
+ public int getHash() {
+ return myHash;
+ }
+
+ public int getCost() {
+ return myCost;
+ }
+
+ public PsiFragment getFragment() {
+ return myFragment;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHasherBase.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHasherBase.java
new file mode 100644
index 000000000000..75faa9894701
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHasherBase.java
@@ -0,0 +1,378 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.DuplicatesProfile;
+import com.intellij.dupLocator.ExternalizableDuplocatorState;
+import com.intellij.dupLocator.NodeSpecificHasher;
+import com.intellij.dupLocator.PsiElementRole;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
+import com.intellij.dupLocator.equivalence.MultiChildDescriptor;
+import com.intellij.dupLocator.equivalence.SingleChildDescriptor;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.openapi.util.Couple;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+class TreeHasherBase extends AbstractTreeHasher {
+ private final FragmentsCollector myCallback;
+ private final int myDiscardCost;
+ private final DuplicatesProfile myProfile;
+
+ TreeHasherBase(@Nullable FragmentsCollector callback,
+ @NotNull DuplicatesProfile profile,
+ int discardCost, boolean forIndexing) {
+ super(callback, forIndexing);
+ myCallback = callback;
+ myDiscardCost = discardCost;
+ myProfile = profile;
+ }
+
+ @Override
+ protected int getDiscardCost(PsiElement root) {
+ if (myDiscardCost >= 0) {
+ return myDiscardCost;
+ }
+ return myProfile.getDuplocatorState(myProfile.getLanguage(root)).getDiscardCost();
+ }
+
+ @Override
+ protected TreeHashResult hash(@NotNull PsiElement root, PsiFragment upper, @NotNull NodeSpecificHasher hasher) {
+ final TreeHashResult result = computeHash(root, upper, hasher);
+
+ // todo: try to optimize (ex. compute cost and hash separately)
+ final int discardCost = getDiscardCost(root);
+ if (result.getCost() < discardCost) {
+ return new TreeHashResult(0, result.getCost(), result.getFragment());
+ }
+
+ return result;
+ }
+
+ private TreeHashResult computeHash(PsiElement root, PsiFragment upper, NodeSpecificHasher hasher) {
+ final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(root);
+
+ if (descriptorProvider != null) {
+ final EquivalenceDescriptor descriptor = descriptorProvider.buildDescriptor(root);
+
+ if (descriptor != null) {
+ return computeHash(root, upper, descriptor, hasher);
+ }
+ }
+
+ if (root instanceof PsiFile) {
+ final List<PsiElement> children = hasher.getNodeChildren(root);
+ if (children.size() <= 20) {
+ return hashCodeBlock(children, upper, hasher, true);
+ }
+ }
+
+ final NodeSpecificHasherBase ssrNodeSpecificHasher = (NodeSpecificHasherBase)hasher;
+
+ if (shouldBeAnonymized(root, ssrNodeSpecificHasher)) {
+ return computeElementHash(root, upper, hasher);
+ }
+
+ if (myForIndexing) {
+ return computeElementHash(root, upper, hasher);
+ }
+
+ final PsiElement element = DuplocatorUtil.getOnlyChild(root, ssrNodeSpecificHasher.getNodeFilter());
+ if (element != root) {
+ final TreeHashResult result = hash(element, upper, hasher);
+ final int cost = hasher.getNodeCost(root);
+ return new TreeHashResult(result.getHash(), result.getCost() + cost, result.getFragment());
+ }
+
+ return computeElementHash(element, upper, hasher);
+ }
+
+ @Override
+ public boolean shouldAnonymize(PsiElement root, NodeSpecificHasher hasher) {
+ return shouldBeAnonymized(root, (NodeSpecificHasherBase)hasher);
+ }
+
+ @Override
+ protected TreeHashResult computeElementHash(@NotNull PsiElement root, PsiFragment upper, NodeSpecificHasher hasher) {
+ if (myForIndexing) {
+ return TreeHashingUtils.computeElementHashForIndexing(this, myCallBack, root, upper, hasher);
+ }
+
+ final List<PsiElement> children = hasher.getNodeChildren(root);
+ final int size = children.size();
+ final int[] childHashes = new int[size];
+ final int[] childCosts = new int[size];
+
+ final PsiFragment fragment = buildFragment(hasher, root, getCost(root));
+
+ if (upper != null) {
+ fragment.setParent(upper);
+ }
+
+ if (size == 0 && !(root instanceof LeafElement)) {
+ // contains only whitespaces and other unmeaning children
+ return new TreeHashResult(0, hasher.getNodeCost(root), fragment);
+ }
+
+ for (int i = 0; i < size; i++) {
+ final TreeHashResult res = this.hash(children.get(i), fragment, hasher);
+ childHashes[i] = res.getHash();
+ childCosts[i] = res.getCost();
+ }
+
+ final int c = hasher.getNodeCost(root) + AbstractTreeHasher.vector(childCosts);
+ final int h1 = hasher.getNodeHash(root);
+
+ final int discardCost = getDiscardCost(root);
+
+ for (int i = 0; i < size; i++) {
+ if (childCosts[i] <= discardCost && ignoreChildHash(children.get(i))) {
+ childHashes[i] = 0;
+ }
+ }
+
+ int h = h1 + AbstractTreeHasher.vector(childHashes);
+
+ if (shouldBeAnonymized(root, (NodeSpecificHasherBase)hasher)) {
+ h = 0;
+ }
+
+ if (myCallBack != null) {
+ myCallBack.add(h, c, fragment);
+ }
+
+ return new TreeHashResult(h, c, fragment);
+ }
+
+ @Override
+ protected TreeHashResult hashCodeBlock(List<? extends PsiElement> statements,
+ PsiFragment upper,
+ NodeSpecificHasher hasher,
+ boolean forceHash) {
+ if (!myForIndexing) return super.hashCodeBlock(statements, upper, hasher, forceHash);
+
+ return TreeHashingUtils.hashCodeBlockForIndexing(this, myCallBack, statements, upper, hasher);
+ }
+
+ private TreeHashResult computeHash(PsiElement element,
+ PsiFragment parent,
+ EquivalenceDescriptor descriptor,
+ NodeSpecificHasher hasher) {
+ final NodeSpecificHasherBase ssrHasher = (NodeSpecificHasherBase)hasher;
+ final PsiElement element2 = DuplocatorUtil.skipNodeIfNeccessary(element, descriptor, ssrHasher.getNodeFilter());
+ final boolean canSkip = element2 != element;
+
+ final PsiFragment fragment = buildFragment(hasher, element, 0);
+
+ if (parent != null) {
+ fragment.setParent(parent);
+ }
+
+ int hash = canSkip ? 0 : hasher.getNodeHash(element);
+ int cost = hasher.getNodeCost(element);
+
+ for (SingleChildDescriptor childDescriptor : descriptor.getSingleChildDescriptors()) {
+ final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
+ hash = hash * 31 + childHashResult.first;
+ cost += childHashResult.second;
+ }
+
+ for (MultiChildDescriptor childDescriptor : descriptor.getMultiChildDescriptors()) {
+ final Couple<Integer> childHashResult = computeHash(childDescriptor, fragment, hasher);
+ hash = hash * 31 + childHashResult.first;
+ cost += childHashResult.second;
+ }
+
+ for (Object constant : descriptor.getConstants()) {
+ final int constantHash = constant != null ? constant.hashCode() : 0;
+ hash = hash * 31 + constantHash;
+ }
+
+ for (PsiElement[] codeBlock : descriptor.getCodeBlocks()) {
+ final List<PsiElement> filteredBlock = filter(codeBlock, ssrHasher);
+ final TreeHashResult childHashResult = hashCodeBlock(filteredBlock, fragment, hasher);
+ hash = hash * 31 + childHashResult.getHash();
+ cost += childHashResult.getCost();
+ }
+
+ if (myCallback != null) {
+ myCallback.add(hash, cost, fragment);
+ }
+ return new TreeHashResult(hash, cost, fragment);
+ }
+
+ public static List<PsiElement> filter(PsiElement[] elements, NodeSpecificHasherBase hasher) {
+ List<PsiElement> filteredElements = new ArrayList<PsiElement>();
+ for (PsiElement element : elements) {
+ if (!hasher.getNodeFilter().accepts(element)) {
+ filteredElements.add(element);
+ }
+ }
+ return filteredElements;
+ }
+
+ @NotNull
+ private Couple<Integer> computeHash(SingleChildDescriptor childDescriptor,
+ PsiFragment parentFragment,
+ NodeSpecificHasher nodeSpecificHasher) {
+
+ final PsiElement element = childDescriptor.getElement();
+ if (element == null) {
+ return Couple.of(0, 0);
+ }
+ final Couple<Integer> result = doComputeHash(childDescriptor, parentFragment, nodeSpecificHasher);
+
+ final DuplicatesProfileBase duplicatesProfile = ((NodeSpecificHasherBase)nodeSpecificHasher).getDuplicatesProfile();
+ final PsiElementRole role = duplicatesProfile.getRole(element);
+ if (role != null) {
+ final ExternalizableDuplocatorState state =
+ duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element));
+ if (!state.distinguishRole(role)) {
+ return Couple.of(0, result.second);
+ }
+ }
+ return result;
+ }
+
+ private static boolean shouldBeAnonymized(PsiElement element, NodeSpecificHasherBase nodeSpecificHasher) {
+ final DuplicatesProfileBase duplicatesProfile = nodeSpecificHasher.getDuplicatesProfile();
+ final PsiElementRole role = duplicatesProfile.getRole(element);
+ if (role != null) {
+ final ExternalizableDuplocatorState state =
+ duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element));
+ return !state.distinguishRole(role);
+ }
+ return false;
+ }
+
+ @NotNull
+ private Couple<Integer> doComputeHash(SingleChildDescriptor childDescriptor,
+ PsiFragment parentFragment,
+ NodeSpecificHasher nodeSpecificHasher) {
+ final PsiElement element = childDescriptor.getElement();
+
+ switch (childDescriptor.getType()) {
+ case OPTIONALLY_IN_PATTERN:
+ case DEFAULT:
+ final TreeHashResult result = hash(element, parentFragment, nodeSpecificHasher);
+ return Couple.of(result.getHash(), result.getCost());
+
+ case CHILDREN_OPTIONALLY_IN_PATTERN:
+ case CHILDREN:
+ TreeHashResult[] childResults = computeHashesForChildren(element, parentFragment, nodeSpecificHasher);
+ int[] hashes = getHashes(childResults);
+ int[] costs = getCosts(childResults);
+
+ int hash = AbstractTreeHasher.vector(hashes, 31);
+ int cost = AbstractTreeHasher.vector(costs);
+
+ return Couple.of(hash, cost);
+
+ case CHILDREN_IN_ANY_ORDER:
+ childResults = computeHashesForChildren(element, parentFragment, nodeSpecificHasher);
+ hashes = getHashes(childResults);
+ costs = getCosts(childResults);
+
+ hash = AbstractTreeHasher.vector(hashes);
+ cost = AbstractTreeHasher.vector(costs);
+
+ return Couple.of(hash, cost);
+
+ default:
+ return Couple.of(0, 0);
+ }
+ }
+
+ @NotNull
+ private Couple<Integer> computeHash(MultiChildDescriptor childDescriptor,
+ PsiFragment parentFragment,
+ NodeSpecificHasher nodeSpecificHasher) {
+ final PsiElement[] elements = childDescriptor.getElements();
+
+ if (elements == null) {
+ return Couple.of(0, 0);
+ }
+
+ switch (childDescriptor.getType()) {
+
+ case OPTIONALLY_IN_PATTERN:
+ case DEFAULT:
+ TreeHashResult[] childResults = computeHashes(elements, parentFragment, nodeSpecificHasher);
+ int[] hashes = getHashes(childResults);
+ int[] costs = getCosts(childResults);
+
+ int hash = AbstractTreeHasher.vector(hashes, 31);
+ int cost = AbstractTreeHasher.vector(costs);
+
+ return Couple.of(hash, cost);
+
+ case IN_ANY_ORDER:
+ childResults = computeHashes(elements, parentFragment, nodeSpecificHasher);
+ hashes = getHashes(childResults);
+ costs = getCosts(childResults);
+
+ hash = AbstractTreeHasher.vector(hashes);
+ cost = AbstractTreeHasher.vector(costs);
+
+ return Couple.of(hash, cost);
+
+ default:
+ return Couple.of(0, 0);
+ }
+ }
+
+ @NotNull
+ private TreeHashResult[] computeHashesForChildren(PsiElement element,
+ PsiFragment parentFragment,
+ NodeSpecificHasher nodeSpecificHasher) {
+ final List<TreeHashResult> result = new ArrayList<TreeHashResult>();
+
+ for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
+ final TreeHashResult childResult = hash(element, parentFragment, nodeSpecificHasher);
+ result.add(childResult);
+ }
+ return result.toArray(new TreeHashResult[result.size()]);
+ }
+
+ @NotNull
+ private TreeHashResult[] computeHashes(PsiElement[] elements,
+ PsiFragment parentFragment,
+ NodeSpecificHasher nodeSpecificHasher) {
+ TreeHashResult[] result = new TreeHashResult[elements.length];
+
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = hash(elements[i], parentFragment, nodeSpecificHasher);
+ }
+
+ return result;
+ }
+
+ private static int[] getHashes(TreeHashResult[] results) {
+ int[] hashes = new int[results.length];
+
+ for (int i = 0; i < results.length; i++) {
+ hashes[i] = results[i].getHash();
+ }
+
+ return hashes;
+ }
+
+ private static int[] getCosts(TreeHashResult[] results) {
+ int[] costs = new int[results.length];
+
+ for (int i = 0; i < results.length; i++) {
+ costs[i] = results[i].getCost();
+ }
+
+ return costs;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashingUtils.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashingUtils.java
new file mode 100644
index 000000000000..115a3cf5b566
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreeHashingUtils.java
@@ -0,0 +1,80 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.NodeSpecificHasher;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.tree.LeafElement;
+
+import java.util.List;
+
+/**
+ * Created by Maxim.Mossienko on 2/17/14.
+ */
+public class TreeHashingUtils {
+ protected static TreeHashResult hashCodeBlockForIndexing(AbstractTreeHasher treeHasher, FragmentsCollector callBack,
+ List<? extends PsiElement> statements,
+ PsiFragment upper,
+ NodeSpecificHasher hasher) {
+ final int statementsSize = statements.size();
+
+ if (statementsSize > 0) {
+ final PsiFragment fragment = treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1);
+ fragment.setParent(upper);
+ int cost = 0;
+ int hash = 0;
+ for (PsiElement statement : statements) {
+ final TreeHashResult res = treeHasher.hash(statement, null, hasher);
+ hash = hash* 31 + res.getHash();
+ cost += res.getCost();
+ }
+
+ TreeHashResult result = new TreeHashResult(hash, cost, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1));
+ if (callBack != null && statementsSize > 1) callBack.add(hash, cost, fragment);
+ return result;
+ }
+ return new TreeHashResult(1, 0, treeHasher.buildFragment(hasher, statements, 0, statementsSize - 1));
+ }
+ static TreeHashResult computeElementHashForIndexing(AbstractTreeHasher base,
+ FragmentsCollector callBack,
+ PsiElement root,
+ PsiFragment upper,
+ NodeSpecificHasher hasher
+ ) {
+ final List<PsiElement> children = hasher.getNodeChildren(root);
+ final PsiFragment fragment = base.buildFragment(hasher, root, base.getCost(root));
+
+ if (upper != null) {
+ fragment.setParent(upper);
+ }
+
+ final int size = children.size();
+ if (size == 0 && !(root instanceof LeafElement)) {
+ // contains only whitespaces and other unmeaning children
+ return new TreeHashResult(0, hasher.getNodeCost(root), fragment);
+ }
+
+ final int discardCost = base.getDiscardCost(root);
+ int c = hasher.getNodeCost(root);
+ int h = hasher.getNodeHash(root);
+
+ for (int i = 0; i < size; i++) {
+ PsiElement child = children.get(i);
+ final TreeHashResult res = base.hash(child, fragment, hasher);
+ int childCost = res.getCost();
+ c += childCost;
+ if (childCost > discardCost || !base.ignoreChildHash(child)) {
+ h += res.getHash();
+ }
+ }
+
+ if (base.shouldAnonymize(root, hasher)) {
+ h = 0;
+ }
+
+ if (callBack != null) {
+ callBack.add(h, c, fragment);
+ }
+
+ return new TreeHashResult(h, c, fragment);
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreePsiFragment.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreePsiFragment.java
new file mode 100644
index 000000000000..8429e4763afc
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/TreePsiFragment.java
@@ -0,0 +1,41 @@
+package com.intellij.dupLocator.treeHash;
+
+import com.intellij.dupLocator.NodeSpecificHasher;
+import com.intellij.dupLocator.util.PsiFragment;
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+* @author oleg
+*/
+public class TreePsiFragment extends PsiFragment {
+ private final NodeSpecificHasher myHasher;
+
+ public TreePsiFragment(final NodeSpecificHasher hasher, final PsiElement root, final int cost) {
+ super(root, cost);
+ myHasher = hasher;
+ }
+
+ public TreePsiFragment(final NodeSpecificHasher hasher, final List<? extends PsiElement> element, final int from, final int to) {
+ super(element, from, to);
+ myHasher = hasher;
+ }
+
+ public boolean isEqual(PsiElement[] elements, int discardCost) {
+ if (elements.length != myElementAnchors.length) {
+ return false;
+ }
+
+ for (int i = 0; i < myElementAnchors.length; i++) {
+ PsiElement one = myElementAnchors[i].retrieve();
+ PsiElement two = elements[i];
+
+ if (one == null || two == null || !myHasher.areTreesEqual(one, two, discardCost)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeView/NodeMatcher.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeView/NodeMatcher.java
new file mode 100644
index 000000000000..3ac62bb83af0
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeView/NodeMatcher.java
@@ -0,0 +1,14 @@
+package com.intellij.dupLocator.treeView;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 20, 2004
+ * Time: 12:31:53 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface NodeMatcher {
+ boolean match(PsiElement node);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/util/DuplocatorUtil.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/DuplocatorUtil.java
new file mode 100644
index 000000000000..bf0ef80ab793
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/DuplocatorUtil.java
@@ -0,0 +1,317 @@
+package com.intellij.dupLocator.util;
+
+import com.intellij.dupLocator.*;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
+import com.intellij.dupLocator.equivalence.MultiChildDescriptor;
+import com.intellij.dupLocator.equivalence.SingleChildDescriptor;
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.lang.Language;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiErrorElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class DuplocatorUtil {
+ private DuplocatorUtil() {
+ }
+
+ public static boolean isIgnoredNode(PsiElement element) {
+ // ex. "var i = 0" in AS: empty JSAttributeList should be skipped
+ /*if (element.getText().length() == 0) {
+ return true;
+ }*/
+
+ if (element instanceof PsiWhiteSpace || element instanceof PsiErrorElement || element instanceof PsiComment) {
+ return true;
+ }
+
+ if (!(element instanceof LeafElement)) {
+ return false;
+ }
+
+ if (CharArrayUtil.containsOnlyWhiteSpaces(element.getText())) {
+ return true;
+ }
+
+ EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element);
+ if (descriptorProvider == null) {
+ return false;
+ }
+
+ final IElementType elementType = ((LeafElement)element).getElementType();
+ return descriptorProvider.getIgnoredTokens().contains(elementType);
+ }
+
+ public static PsiElement getOnlyChild(PsiElement element, @NotNull NodeFilter filter) {
+ FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(element.getFirstChild()), filter);
+ PsiElement child = it.current();
+ if (child != null) {
+ it.advance();
+ if (!it.hasNext()) {
+ return child;
+ }
+ }
+ return element;
+ }
+
+ public static boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
+ if (element == null || elementToMatchWith == null) {
+ return false;
+ }
+
+ if (element.getClass() == elementToMatchWith.getClass()) {
+ return false;
+ }
+
+ if (element.getFirstChild() == null && element.getTextLength() == 0 && !(element instanceof LeafElement)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Nullable
+ public static PsiElement skipNodeIfNeccessary(PsiElement element, EquivalenceDescriptor descriptor, NodeFilter filter) {
+ if (element == null) {
+ return null;
+ }
+
+ /*if (!canSkip(element) && getOnlyNonWhitespaceChild(element) == null) {
+ return element;
+ }*/
+
+ // todo optimize! (this method is often invokated for the same node)
+
+ if (descriptor == null) {
+ final EquivalenceDescriptorProvider provider = EquivalenceDescriptorProvider.getInstance(element);
+ if (provider != null) {
+ descriptor = provider.buildDescriptor(element);
+ }
+ }
+
+ if (descriptor != null) {
+ final PsiElement onlyChild = getOnlyChildFromDescriptor(descriptor, filter);
+ return onlyChild != null ? onlyChild : element;
+ }
+ return getOnlyChild(element, filter);
+ }
+
+ @Nullable
+ private static PsiElement getOnlyChildFromDescriptor(EquivalenceDescriptor equivalenceDescriptor, NodeFilter filter) {
+ if (!equivalenceDescriptor.getConstants().isEmpty()) {
+ return null;
+ }
+
+ final List<SingleChildDescriptor> singleChildren = equivalenceDescriptor.getSingleChildDescriptors();
+ final List<MultiChildDescriptor> multiChildren = equivalenceDescriptor.getMultiChildDescriptors();
+ final List<PsiElement[]> codeBlocks = equivalenceDescriptor.getCodeBlocks();
+
+ if (singleChildren.size() + multiChildren.size() + codeBlocks.size() != 1) {
+ return null;
+ }
+
+ if (!singleChildren.isEmpty()) {
+ final SingleChildDescriptor descriptor = singleChildren.get(0);
+ final PsiElement child = descriptor.getElement();
+
+ if (child != null) {
+ final SingleChildDescriptor.MyType type = descriptor.getType();
+
+ if (type == SingleChildDescriptor.MyType.DEFAULT) {
+ return child;
+ }
+ else if (type == SingleChildDescriptor.MyType.CHILDREN ||
+ type == SingleChildDescriptor.MyType.CHILDREN_IN_ANY_ORDER) {
+ return getOnlyChild(child, filter);
+ }
+ }
+ }
+ else if (!multiChildren.isEmpty()) {
+ final MultiChildDescriptor descriptor = multiChildren.get(0);
+ final PsiElement[] children = descriptor.getElements();
+
+ if (children != null && children.length == 1 && descriptor.getType() != MultiChildDescriptor.MyType.OPTIONALLY) {
+ return children[0];
+ }
+ }
+ else if (!codeBlocks.isEmpty()) {
+ final PsiElement[] codeBlock = codeBlocks.get(0);
+ if (codeBlock != null && codeBlock.length == 1) {
+ return codeBlock[0];
+ }
+ }
+ return null;
+ }
+
+ public static boolean match(@NotNull EquivalenceDescriptor descriptor1,
+ @NotNull EquivalenceDescriptor descriptor2,
+ @NotNull AbstractMatchingVisitor g,
+ @NotNull Set<PsiElementRole> skippedRoles,
+ @Nullable DuplicatesProfile profile) {
+
+ if (descriptor1.getSingleChildDescriptors().size() != descriptor2.getSingleChildDescriptors().size()) {
+ return false;
+ }
+
+ if (descriptor1.getMultiChildDescriptors().size() != descriptor2.getMultiChildDescriptors().size()) {
+ return false;
+ }
+
+ if (descriptor1.getCodeBlocks().size() != descriptor2.getCodeBlocks().size()) {
+ return false;
+ }
+
+ if (descriptor1.getConstants().size() != descriptor2.getConstants().size()) {
+ return false;
+ }
+
+ for (int i = 0, n = descriptor1.getConstants().size(); i < n; i++) {
+ Object childDescriptor1 = descriptor1.getConstants().get(i);
+ Object childDescriptor2 = descriptor2.getConstants().get(i);
+
+ if (!Comparing.equal(childDescriptor1, childDescriptor2)) {
+ return false;
+ }
+ }
+
+ for (int i = 0, n = descriptor1.getSingleChildDescriptors().size(); i < n; i++) {
+ SingleChildDescriptor childDescriptor1 = descriptor1.getSingleChildDescriptors().get(i);
+ SingleChildDescriptor childDescriptor2 = descriptor2.getSingleChildDescriptors().get(i);
+
+ if (!match(childDescriptor1, childDescriptor2, g, skippedRoles, profile)) {
+ return false;
+ }
+ }
+
+ for (int i = 0, n = descriptor1.getMultiChildDescriptors().size(); i < n; i++) {
+ MultiChildDescriptor childDescriptor1 = descriptor1.getMultiChildDescriptors().get(i);
+ MultiChildDescriptor childDescriptor2 = descriptor2.getMultiChildDescriptors().get(i);
+
+ if (!match(childDescriptor1, childDescriptor2, g)) {
+ return false;
+ }
+ }
+
+ for (int i = 0, n = descriptor1.getCodeBlocks().size(); i < n; i++) {
+ final PsiElement[] codeBlock1 = descriptor1.getCodeBlocks().get(i);
+ final PsiElement[] codeBlock2 = descriptor2.getCodeBlocks().get(i);
+
+ if (!g.matchSequentially(codeBlock1, codeBlock2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean match(@NotNull SingleChildDescriptor childDescriptor1,
+ @NotNull SingleChildDescriptor childDescriptor2,
+ @NotNull AbstractMatchingVisitor g,
+ @NotNull Set<PsiElementRole> skippedRoles,
+ @Nullable DuplicatesProfile duplicatesProfile) {
+ if (childDescriptor1.getType() != childDescriptor2.getType()) {
+ return false;
+ }
+
+ final PsiElement element1 = childDescriptor1.getElement();
+ final PsiElement element2 = childDescriptor2.getElement();
+
+ if (duplicatesProfile != null) {
+ final PsiElementRole role1 = element1 != null ? duplicatesProfile.getRole(element1) : null;
+ final PsiElementRole role2 = element2 != null ? duplicatesProfile.getRole(element2) : null;
+
+ if (role1 == role2 && skippedRoles.contains(role1)) {
+ return true;
+ }
+ }
+
+ switch (childDescriptor1.getType()) {
+
+ case DEFAULT:
+ return g.match(element1, element2);
+
+ case OPTIONALLY_IN_PATTERN:
+ case OPTIONALLY:
+ return g.matchOptionally(element1, element2);
+
+ case CHILDREN:
+ return g.matchSons(element1, element2);
+
+ case CHILDREN_OPTIONALLY_IN_PATTERN:
+ case CHILDREN_OPTIONALLY:
+ return g.matchSonsOptionally(element1, element2);
+
+ case CHILDREN_IN_ANY_ORDER:
+ return g.matchSonsInAnyOrder(element1, element2);
+
+ default:
+ return false;
+ }
+ }
+
+ private static boolean match(@NotNull MultiChildDescriptor childDescriptor1,
+ @NotNull MultiChildDescriptor childDescriptor2,
+ @NotNull AbstractMatchingVisitor g) {
+
+ if (childDescriptor1.getType() != childDescriptor2.getType()) {
+ return false;
+ }
+
+ final PsiElement[] elements1 = childDescriptor1.getElements();
+ final PsiElement[] elements2 = childDescriptor2.getElements();
+
+ switch (childDescriptor1.getType()) {
+
+ case DEFAULT:
+ return g.matchSequentially(elements1, elements2);
+
+ case OPTIONALLY_IN_PATTERN:
+ case OPTIONALLY:
+ return g.matchOptionally(elements1, elements2);
+
+ case IN_ANY_ORDER:
+ return g.matchInAnyOrder(elements1, elements2);
+
+ default:
+ return false;
+ }
+ }
+
+ @Nullable
+ public static DuplocatorState getDuplocatorState(PsiFragment frag) {
+ final Language language = frag.getLanguage();
+ if (language == null) {
+ return null;
+ }
+
+ final DuplicatesProfile profile = DuplicatesProfile.findProfileForLanguage(language);
+ return profile != null
+ ? profile.getDuplocatorState(language)
+ : null;
+ }
+
+ @NotNull
+ public static ExternalizableDuplocatorState registerAndGetState(Language language) {
+ final MultilanguageDuplocatorSettings settings = MultilanguageDuplocatorSettings.getInstance();
+ ExternalizableDuplocatorState state = settings.getState(language);
+ if (state == null) {
+ state = new DefaultDuplocatorState();
+ settings.registerState(language, state);
+ }
+ return state;
+ }
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/util/NodeFilter.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/NodeFilter.java
new file mode 100644
index 000000000000..5741279b4175
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/NodeFilter.java
@@ -0,0 +1,10 @@
+package com.intellij.dupLocator.util;
+
+import com.intellij.psi.PsiElement;
+
+/**
+ * Base class for tree filtering
+ */
+public interface NodeFilter {
+ boolean accepts(PsiElement element);
+}
diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java
new file mode 100644
index 000000000000..5bf5b3e137e7
--- /dev/null
+++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java
@@ -0,0 +1,253 @@
+package com.intellij.dupLocator.util;
+
+import com.intellij.dupLocator.DuplicatesProfile;
+import com.intellij.lang.Language;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.PsiAnchor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.usageView.UsageInfo;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Mar 26, 2004
+ * Time: 4:58:00 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class PsiFragment {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.PsiFragment");
+
+ protected final PsiAnchor[] myElementAnchors;
+ private final Language myLanguage;
+ private PsiFragment[] myParents;
+ private boolean myDuplicate;
+ private boolean myChecked;
+ private boolean myNested;
+ private int myCost;
+
+ public PsiFragment(PsiElement element) {
+ this(element, 0);
+ }
+
+ public PsiFragment(PsiElement element, int cost) {
+ myElementAnchors = new PsiAnchor[]{createAnchor(element)};
+ myDuplicate = false;
+ myChecked = false;
+ myNested = false;
+ myParents = null;
+ myCost = cost;
+ myLanguage = calcLanguage(element);
+ }
+
+ protected Language calcLanguage(PsiElement element) {
+ return doGetLanguageForElement(element);
+ }
+
+ protected PsiAnchor createAnchor(final PsiElement element) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<PsiAnchor>() {
+ public PsiAnchor compute() {
+ return PsiAnchor.create(element);
+ }
+ });
+ }
+
+ public PsiFragment(List<? extends PsiElement> elements) {
+ this(elements, 0, elements.size() - 1);
+ }
+
+ public PsiFragment(List<? extends PsiElement> elements, int from, int to) {
+ myElementAnchors = new PsiAnchor[to - from + 1];
+
+ for (int i = from; i <= to; i++) {
+ myElementAnchors[i - from] = createAnchor(elements.get(i));
+ }
+
+ myDuplicate = false;
+ myChecked = false;
+ myNested = false;
+ myParents = null;
+ myLanguage = to >= from && from < elements.size()
+ ? calcLanguage(elements.get(from))
+ : null;
+ }
+
+ @NotNull
+ private static Language doGetLanguageForElement(@NotNull PsiElement element) {
+ final DuplicatesProfile profile = DuplicatesProfile.findProfileForLanguage(element.getLanguage());
+ if (profile == null) {
+ return element.getLanguage();
+ }
+ return profile.getLanguage(element);
+ }
+
+ public void setCost(int c) {
+ if (myCost != -1) {
+ myCost = c;
+ }
+ }
+
+ public void markDuplicate() {
+ myDuplicate = true;
+ }
+
+ public boolean isNested() {
+ if (myChecked) {
+ return myNested;
+ }
+
+ myChecked = true;
+
+ if (myParents != null) {
+ PsiFragment parent1 = myParents[0];
+ PsiFragment parent2 = myParents[1];
+
+ if (parent1 != null) {
+ myNested |= parent1.myDuplicate || parent1.isNested();
+ if (parent2 != null) {
+ myNested |= parent2.myDuplicate || parent2.isNested();
+ }
+ }
+ }
+
+ return myNested;
+ }
+
+ public void setParent(PsiFragment f) {
+ if (f == null) return;
+ if (myParents == null) {
+ myParents = new PsiFragment[]{f, null};
+ }
+ else {
+ if (myParents[0] == f || myParents[1] == f) return;
+ if (myParents[1] != null) {
+ LOG.error("Third parent set.");
+ }
+
+ myParents[1] = f;
+ }
+ }
+
+ public PsiElement[] getElements() {
+ PsiElement[] elements = new PsiElement[myElementAnchors.length];
+
+ for (int i = 0; i < elements.length; i++) {
+ elements[i] = myElementAnchors[i].retrieve();
+ }
+
+ return elements;
+ }
+
+ @Nullable
+ public PsiFile getFile() {
+ return myElementAnchors.length > 0 ? myElementAnchors[0].getFile() : null;
+ }
+
+ public int getStartOffset() {
+ return myElementAnchors.length > 0 ? myElementAnchors[0].getStartOffset() : -1;
+ }
+
+ public int getEndOffset() {
+ return myElementAnchors.length > 0 ? myElementAnchors[myElementAnchors.length - 1].getEndOffset() : -1;
+ }
+
+ public boolean intersectsWith(PsiFragment f) {
+ final int start = getStartOffset();
+ final int end = getEndOffset();
+ final int fStart = f.getStartOffset();
+ final int fEnd = f.getEndOffset();
+
+ return
+ Comparing.equal(f.getFile(), getFile()) && ((start <= fStart && fStart <= end) || (start <= fEnd && fEnd <= end));
+ }
+
+ public abstract boolean isEqual(PsiElement[] elements, int discardCost);
+
+ @Nullable
+ public UsageInfo getUsageInfo() {
+ if (myElementAnchors.length == 1) {
+ final PsiElement element = myElementAnchors[0].retrieve();
+ if (element == null || !element.isValid()) return null;
+ return new UsageInfo(element);
+ }
+
+ PsiElement parent = PsiTreeUtil.findCommonParent(getElements());
+ if (parent == null) return null;
+ int offs = parent.getTextRange().getStartOffset();
+
+ final int startOffsetInParent = getStartOffset() - offs;
+ final int endOffsetInParent = getEndOffset() - offs;
+ if (startOffsetInParent < 0) return null;
+ if (endOffsetInParent < startOffsetInParent) return null;
+ return new UsageInfo(parent, startOffsetInParent, endOffsetInParent);
+ }
+
+ //debug only
+ public String toString() {
+ StringBuilder buffer = new StringBuilder();
+
+ for (PsiAnchor psiAnchor : myElementAnchors) {
+ final PsiElement element = psiAnchor.retrieve();
+ if (element != null) {
+ buffer.append(element.getText());
+ buffer.append("\n");
+ }
+ }
+
+ return buffer.toString();
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof PsiFragment)) return false;
+
+ PsiFragment other = ((PsiFragment)o);
+
+ return other.getStartOffset() == getStartOffset() &&
+ other.getEndOffset() == getEndOffset() &&
+ Comparing.equal(other.getFile(), getFile());
+ }
+
+ public int hashCode() {
+ int result = getStartOffset();
+ result += 31 * result + getEndOffset();
+ final PsiFile file = getFile();
+ if (file != null) {
+ result += 31 * result + file.getName().hashCode();
+ }
+ return result;
+ }
+
+ public int getCost() {
+ return myCost;
+ }
+
+ public int[][] getOffsets() {
+ final int[][] result = new int[myElementAnchors.length][2];
+ int idx = 0;
+ for (PsiAnchor anchor : myElementAnchors) {
+ result[idx][0] = anchor.getStartOffset();
+ result[idx++][1] = anchor.getEndOffset();
+ }
+ return result;
+ }
+
+ public boolean containsMultipleFragments() {
+ return myElementAnchors.length > 1;
+ }
+
+ @Nullable
+ public Language getLanguage() {
+ return myLanguage;
+ }
+}
+
+
diff --git a/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacade.java b/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacade.java
index 22e5b7a6c610..91adfa23dd92 100644
--- a/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacade.java
+++ b/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacade.java
@@ -92,9 +92,6 @@ public interface DvcsPlatformFacade {
void saveAllDocuments();
- @Nullable
- VirtualFile getVirtualFileByPath(@NotNull String path);
-
@NotNull
ProjectManagerEx getProjectManager();
diff --git a/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacadeImpl.java b/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacadeImpl.java
index 273c13c31dc6..9f10311f68d3 100644
--- a/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacadeImpl.java
+++ b/platform/dvcs/src/com/intellij/dvcs/DvcsPlatformFacadeImpl.java
@@ -36,7 +36,6 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
-import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -125,12 +124,6 @@ public abstract class DvcsPlatformFacadeImpl implements DvcsPlatformFacade {
});
}
- @Nullable
- @Override
- public VirtualFile getVirtualFileByPath(@NotNull String path) {
- return VcsUtil.getVirtualFile(path);
- }
-
@NotNull
@Override
public ProjectManagerEx getProjectManager() {
diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java b/platform/dvcs/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java
index f39591e556cc..3b935745a212 100644
--- a/platform/dvcs/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java
+++ b/platform/dvcs/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java
@@ -40,7 +40,7 @@ import java.awt.*;
public class BranchActionGroupPopup extends PopupFactoryImpl.ActionGroupPopup {
public BranchActionGroupPopup(@NotNull String title, @NotNull Project project,
@NotNull Condition<AnAction> preselectActionCondition, @NotNull ActionGroup actions) {
- super(title, actions, SimpleDataContext.getProjectContext(project), false, false, false, true, null, -1,
+ super(title, actions, SimpleDataContext.getProjectContext(project), false, false, false, false, null, -1,
preselectActionCondition, null);
}
diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/RootAction.java b/platform/dvcs/src/com/intellij/dvcs/ui/RootAction.java
index a8790481290d..93e49042648c 100644
--- a/platform/dvcs/src/com/intellij/dvcs/ui/RootAction.java
+++ b/platform/dvcs/src/com/intellij/dvcs/ui/RootAction.java
@@ -43,13 +43,14 @@ public class RootAction<T extends Repository> extends ActionGroup {
* @param branchText
*/
public RootAction(@NotNull T repository, @Nullable T currentRepository, @NotNull ActionGroup actionsGroup, @NotNull String branchText) {
- super(DvcsUtil.getShortRepositoryName(repository), true);
+ super("", true);
myRepository = repository;
myGroup = actionsGroup;
myBranchText = branchText;
if (repository.equals(currentRepository)) {
getTemplatePresentation().setIcon(PlatformIcons.CHECK_ICON);
}
+ getTemplatePresentation().setText(DvcsUtil.getShortRepositoryName(repository), false);
}
@NotNull
diff --git a/platform/dvcs/testFramework/com/intellij/dvcs/test/DvcsTestPlatformFacade.java b/platform/dvcs/testFramework/com/intellij/dvcs/test/DvcsTestPlatformFacade.java
deleted file mode 100644
index f2a6ecf4a725..000000000000
--- a/platform/dvcs/testFramework/com/intellij/dvcs/test/DvcsTestPlatformFacade.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.dvcs.test;
-
-import com.intellij.dvcs.DvcsPlatformFacade;
-import com.intellij.ide.SaveAndSyncHandler;
-import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.mock.MockLocalFileSystem;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ex.ProjectManagerEx;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vcs.AbstractVcsHelper;
-import com.intellij.openapi.vcs.changes.ChangeListManagerEx;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.testFramework.vcs.MockChangeListManager;
-import org.easymock.classextension.EasyMock;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- *
- * @author Kirill Likhodedov
- */
-public abstract class DvcsTestPlatformFacade implements DvcsPlatformFacade {
-
- private MockProjectRootManager myProjectRootManager;
- private ChangeListManagerEx myChangeListManager;
- private MockVcsHelper myVcsHelper;
-
- public DvcsTestPlatformFacade() {
- myProjectRootManager = new MockProjectRootManager();
- myChangeListManager = new MockChangeListManager();
- }
-
- @NotNull
- @Override
- public ProjectRootManager getProjectRootManager(@NotNull Project project) {
- return myProjectRootManager;
- }
-
- @Override
- public <T> T runReadAction(@NotNull Computable<T> computable) {
- return computable.compute();
- }
-
- @Override
- public void runReadAction(@NotNull Runnable runnable) {
- runnable.run();
- }
-
- @Override
- public void runWriteAction(@NotNull Runnable runnable) {
- runnable.run();
- }
-
- @Override
- public void invokeAndWait(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
- runnable.run();
- }
-
- @Override
- public void executeOnPooledThread(@NotNull Runnable runnable) {
- new Thread(runnable).start();
- }
-
- @Override
- public ChangeListManagerEx getChangeListManager(@NotNull Project project) {
- return myChangeListManager;
- }
-
- @Override
- public LocalFileSystem getLocalFileSystem() {
- return new MockLocalFileSystem();
- }
-
- @NotNull
- @Override
- public AbstractVcsHelper getVcsHelper(@NotNull Project project) {
- if (myVcsHelper == null) {
- myVcsHelper = new MockVcsHelper(project);
- }
- return myVcsHelper;
- }
-
- @Nullable
- @Override
- public IdeaPluginDescriptor getPluginByClassName(@NotNull String name) {
- return null;
- }
-
- @NotNull
- @Override
- public String getLineSeparator(@NotNull VirtualFile file, boolean detect) {
- try {
- return FileUtil.loadFile(new File(file.getPath())).contains("\r\n") ? "\r\n" : "\n";
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void saveAllDocuments() {
- }
-
- @Nullable
- @Override
- public VirtualFile getVirtualFileByPath(@NotNull String path) {
- return new MockVirtualFile(path);
- }
-
- @NotNull
- @Override
- public ProjectManagerEx getProjectManager() {
- return EasyMock.createMock(ProjectManagerEx.class);
- }
-
- @NotNull
- @Override
- public SaveAndSyncHandler getSaveAndSyncHandler() {
- return EasyMock.createMock(SaveAndSyncHandler.class);
- }
-
- @Override
- public void hardRefresh(@NotNull VirtualFile root) {
- }
-}
diff --git a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
index 726a7124b9e5..d89b92878f54 100644
--- a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
+++ b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,8 +34,7 @@ import java.util.Set;
* @author Kirill Likhodedov
*/
public class MockProjectRootManager extends ProjectRootManager {
-
- List<VirtualFile> myContentRoots = new ArrayList<VirtualFile>();
+ private final List<VirtualFile> myContentRoots = new ArrayList<VirtualFile>();
@NotNull
@Override
@@ -107,9 +106,4 @@ public class MockProjectRootManager extends ProjectRootManager {
public void setProjectSdkName(String name) {
throw new UnsupportedOperationException();
}
-
- @Override
- public long getModificationCount() {
- throw new UnsupportedOperationException();
- }
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
index 02a849a19eb7..df247d5be401 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
@@ -244,12 +244,20 @@ public interface CaretModel {
List<CaretState> getCaretsAndSelections();
/**
- * Executes the given task for each existing caret. Carets are iterated in their position order. Set of carets to iterate over is
+ * Same as {@link #runForEachCaret(CaretAction, boolean)} with <code>reverseOrder</code> set to <code>false</code>
+ */
+ void runForEachCaret(@NotNull CaretAction action);
+
+ /**
+ * Executes the given task for each existing caret. Set of carets to iterate over is
* determined in the beginning and is not affected by the potential carets addition or removal by the task being executed.
* At the end, merging of carets and selections is performed, so that no two carets will occur at the same logical position and
* no two selection will overlap after this method is finished.
+ * <p>
+ * Carets are iterated in position order (top-to-bottom) if <code>reverseOrder</code> is <code>false</code>, and in reverse order
+ * if it's <code>true</code>.
*/
- void runForEachCaret(@NotNull CaretAction action);
+ void runForEachCaret(@NotNull CaretAction action, boolean reverseOrder);
/**
* Executes the given task, performing caret merging afterwards. Caret merging will not happen until the operation is finished.
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java
index fe3242e47b44..29cb27933d7c 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java
@@ -48,7 +48,7 @@ public interface EditorColors {
TextAttributesKey FOLDED_TEXT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("FOLDED_TEXT_ATTRIBUTES");
TextAttributesKey DELETED_TEXT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("DELETED_TEXT_ATTRIBUTES");
- ColorKey GUTTER_BACKGROUND = ColorKey.createColorKey("GUTTER_BACKGROUND");
+ ColorKey GUTTER_BACKGROUND = ColorKey.createColorKey("GUTTER_BACKGROUND", new JBColor(0xf0f0f0, 0x313335));
@Deprecated ColorKey LEFT_GUTTER_BACKGROUND = GUTTER_BACKGROUND;
ColorKey NOTIFICATION_BACKGROUND = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsUtil.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsUtil.java
new file mode 100644
index 000000000000..14265bc65fcb
--- /dev/null
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColorsUtil.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.colors;
+
+import com.intellij.ui.ColorUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author gregsh
+ */
+public class EditorColorsUtil {
+ private EditorColorsUtil() {
+ }
+
+ /**
+ * @return the appropriate color scheme for UI other than text editor (QuickDoc, UsagesView, etc.)
+ * depending on the current LAF and current editor color scheme.
+ */
+ @NotNull
+ public static EditorColorsScheme getGlobalOrDefaultColorScheme() {
+ return getColorSchemeForBackground(null);
+ }
+
+ /**
+ * @return the appropriate color scheme for UI other than text editor (QuickDoc, UsagesView, etc.)
+ * depending on the current LAF, current editor color scheme and the component background.
+ */
+ @NotNull
+ public static EditorColorsScheme getColorSchemeForComponent(@Nullable JComponent component) {
+ return getColorSchemeForBackground(component != null ? component.getBackground() : null);
+ }
+
+ /**
+ * @return the appropriate color scheme for UI other than text editor (QuickDoc, UsagesView, etc.)
+ * depending on the current LAF, current editor color scheme and background color.
+ */
+ public static EditorColorsScheme getColorSchemeForBackground(@Nullable Color background) {
+ EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
+ boolean dark1 = background == null ? UIUtil.isUnderDarcula() : ColorUtil.isDark(background);
+ boolean dark2 = ColorUtil.isDark(globalScheme.getDefaultBackground());
+ if (dark1 != dark2) {
+ EditorColorsScheme scheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME);
+ if (scheme != null) {
+ return scheme;
+ }
+ }
+ return globalScheme;
+ }
+}
diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
index e0d91f62eadc..e90693927d34 100644
--- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
+++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/highlighter/EditorHighlighterFactoryImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.LanguageSubstitutors;
@@ -77,6 +78,9 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
try {
return FileTypeEditorHighlighterProviders.INSTANCE.forFileType(fileType).getEditorHighlighter(project, fileType, vFile, settings);
}
+ catch (ProcessCanceledException e) {
+ throw e;
+ }
catch (Exception e) {
LOG.error(e);
}
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java b/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java
index 209a29b74011..9e1a199bcd69 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/ExtensionPointName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +39,7 @@ public class ExtensionPointName<T> {
}
+ @Override
public String toString() {
return myName;
}
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
index d172a30ff285..f992e45bc9fc 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/impl/ExtensionComponentAdapter.java
@@ -191,4 +191,9 @@ public class ExtensionComponentAdapter implements LoadingOrder.Orderable, Assign
public void setNotificationSent(boolean notificationSent) {
myNotificationSent = notificationSent;
}
+
+ @Override
+ public String toString() {
+ return "ExtensionComponentAdapter[" + myImplementationClassName + "]: plugin=" + myPluginDescriptor;
+ }
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/execution/ExternalSystemExecutionConsoleManager.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/execution/ExternalSystemExecutionConsoleManager.java
index 6ab3679a6f98..b9f78c8c62d6 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/execution/ExternalSystemExecutionConsoleManager.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/execution/ExternalSystemExecutionConsoleManager.java
@@ -21,6 +21,7 @@ import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask;
@@ -50,4 +51,6 @@ public interface ExternalSystemExecutionConsoleManager<ExternalSystemRunConfigur
void onOutput(@NotNull String text, @NotNull Key processOutputType);
boolean isApplicableFor(@NotNull ExternalSystemTask task);
+
+ AnAction[] getRestartActions();
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java
index a9dacf975114..ad9dec8d1fe1 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/execution/ExternalSystemTaskExecutionSettings.java
@@ -21,6 +21,7 @@ import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -39,11 +40,21 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
private List<String> myTaskNames = ContainerUtilRt.newArrayList();
private List<String> myTaskDescriptions = ContainerUtilRt.newArrayList();
+ @Nullable private String myExecutionName;
private String myExternalSystemIdString;
private String myExternalProjectPath;
private String myVmOptions;
private String myScriptParameters;
+ @Nullable
+ public String getExecutionName() {
+ return myExecutionName;
+ }
+
+ public void setExecutionName(@Nullable String executionName) {
+ myExecutionName = executionName;
+ }
+
public String getExternalSystemIdString() {
return myExternalSystemIdString;
}
@@ -99,6 +110,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
@Override
public ExternalSystemTaskExecutionSettings clone() {
ExternalSystemTaskExecutionSettings result = new ExternalSystemTaskExecutionSettings();
+ result.setExecutionName(getExecutionName());
result.setExternalSystemIdString(getExternalSystemIdString());
result.setExternalProjectPath(getExternalProjectPath());
result.setVmOptions(getVmOptions());
@@ -111,6 +123,7 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
@Override
public int hashCode() {
int result = myTaskNames != null ? myTaskNames.hashCode() : 0;
+ result = 31 * result + (myExecutionName != null ? myExecutionName.hashCode() : 0);
result = 31 * result + (myExternalSystemIdString != null ? myExternalSystemIdString.hashCode() : 0);
result = 31 * result + (myExternalProjectPath != null ? myExternalProjectPath.hashCode() : 0);
result = 31 * result + (myVmOptions != null ? myVmOptions.hashCode() : 0);
@@ -125,6 +138,10 @@ public class ExternalSystemTaskExecutionSettings implements Cloneable {
ExternalSystemTaskExecutionSettings settings = (ExternalSystemTaskExecutionSettings)o;
+ if (myExecutionName != null ? !myExecutionName.equals(settings.myExecutionName) : settings.myExecutionName != null) {
+ return false;
+ }
+
if (myExternalProjectPath != null
? !myExternalProjectPath.equals(settings.myExternalProjectPath)
: settings.myExternalProjectPath != null)
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ContentRootData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ContentRootData.java
index 88ccc0cc3a24..fd4d198ab00b 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ContentRootData.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ContentRootData.java
@@ -146,7 +146,7 @@ public class ContentRootData extends AbstractExternalEntityData {
}
}
- private static final class SourceRootComparator implements Comparator<SourceRoot> {
+ private static final class SourceRootComparator implements Comparator<SourceRoot>, Serializable {
private static final SourceRootComparator INSTANCE = new SourceRootComparator();
@Override
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java
index 5c59120ef33d..f0139f090595 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/settings/ExternalSystemExecutionSettings.java
@@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public class ExternalSystemExecutionSettings implements Serializable {
- private static final String REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY = "external.system.remote.process.idle.ttl.ms";
+ public static final String REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY = "external.system.remote.process.idle.ttl.ms";
private static final int DEFAULT_REMOTE_PROCESS_TTL_MS = 60000;
private static final long serialVersionUID = 1L;
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java
index 4eff1de35e7e..cf74790621d8 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskNotificationListener.java
@@ -48,6 +48,14 @@ public interface ExternalSystemTaskNotificationListener {
*/
void onTaskOutput(@NotNull ExternalSystemTaskId id, @NotNull String text, boolean stdOut);
+ ///**
+ // * Notifies about stdin during the task execution
+ // *
+ // * @param id id of the task being executed
+ // * @param text text produced by external system during the target task execution
+ // */
+ //void onTaskInput(@NotNull ExternalSystemTaskId id, @NotNull String text);
+
/**
* Notifies that task with the given id is finished.
*
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallback.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallback.java
new file mode 100644
index 000000000000..ce6a11324e6f
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallback.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.task;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/19/2014
+ */
+public interface TaskCallback {
+ void onSuccess();
+
+ void onFailure();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallbackAdapter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallbackAdapter.java
new file mode 100644
index 000000000000..250af07934d0
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/task/TaskCallbackAdapter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.task;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/19/2014
+ */
+public class TaskCallbackAdapter implements TaskCallback {
+ @Override
+ public void onSuccess() {}
+
+ @Override
+ public void onFailure() {}
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
index eda9ad99da16..a6cfc65eb759 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.OrderRootType;
@@ -49,10 +50,10 @@ import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.TransferToEDTQueue;
import com.intellij.util.lang.UrlClassLoader;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -665,4 +666,19 @@ public class ExternalSystemApiUtil {
//noinspection unchecked
return (T)loader.loadClass(clazz.getName()).newInstance();
}
+
+ @Contract("_, null -> false")
+ public static boolean isExternalSystemAwareModule(@NotNull ProjectSystemId systemId, @Nullable Module module) {
+ return module != null && systemId.getId().equals(module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY));
+ }
+
+ @Contract("_, null -> false")
+ public static boolean isExternalSystemAwareModule(@NotNull String systemId, @Nullable Module module) {
+ return module != null && systemId.equals(module.getOptionValue(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY));
+ }
+
+ @Nullable
+ public static String getExternalProjectPath(@Nullable Module module) {
+ return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : null;
+ }
}
diff --git a/platform/external-system-impl/external-system-impl.iml b/platform/external-system-impl/external-system-impl.iml
index e38ad4248950..aa68fdc4d7b6 100644
--- a/platform/external-system-impl/external-system-impl.iml
+++ b/platform/external-system-impl/external-system-impl.iml
@@ -23,6 +23,7 @@
<orderEntry type="module" module-name="smRunner" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
</component>
</module>
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java
index 1345d495921b..3eb1dd6f4420 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/AbstractExternalSystemTaskConfigurationType.java
@@ -109,7 +109,9 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
@NotNull
public static String generateName(@NotNull Project project, @NotNull ExternalSystemTaskExecutionSettings settings) {
- return generateName(project, settings.getExternalSystemId(), settings.getExternalProjectPath(), settings.getTaskNames());
+ return generateName(
+ project, settings.getExternalSystemId(), settings.getExternalProjectPath(), settings.getTaskNames(), settings.getExecutionName()
+ );
}
@NotNull
@@ -121,8 +123,16 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
public static String generateName(@NotNull Project project,
@NotNull ProjectSystemId externalSystemId,
@Nullable String externalProjectPath,
- @NotNull List<String> taskNames)
- {
+ @NotNull List<String> taskNames) {
+ return generateName(project, externalSystemId, externalProjectPath, taskNames, null);
+ }
+
+ @NotNull
+ public static String generateName(@NotNull Project project,
+ @NotNull ProjectSystemId externalSystemId,
+ @Nullable String externalProjectPath,
+ @NotNull List<String> taskNames,
+ @Nullable String executionName) {
ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(externalSystemId);
assert manager != null;
AbstractExternalSystemSettings<?, ?,?> s = manager.getSettingsProvider().fun(project);
@@ -168,12 +178,16 @@ public abstract class AbstractExternalSystemTaskConfigurationType implements Con
}
buffer.append("[");
- if (!taskNames.isEmpty()) {
+ if (!StringUtil.isEmpty(executionName)) {
+ buffer.append(executionName);
+ }
+ else if (!taskNames.isEmpty()) {
for (String taskName : taskNames) {
buffer.append(taskName).append(" ");
}
buffer.setLength(buffer.length() - 1);
}
+
buffer.append("]");
return buffer.toString();
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/DefaultExternalSystemExecutionConsoleManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/DefaultExternalSystemExecutionConsoleManager.java
index b2a6bfd99b68..87b68e90bd69 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/DefaultExternalSystemExecutionConsoleManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/DefaultExternalSystemExecutionConsoleManager.java
@@ -22,6 +22,7 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask;
@@ -67,4 +68,9 @@ public class DefaultExternalSystemExecutionConsoleManager implements ExternalSys
public boolean isApplicableFor(@NotNull ExternalSystemTask task) {
return true;
}
+
+ @Override
+ public AnAction[] getRestartActions() {
+ return new AnAction[0];
+ }
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
index 4c27ae11a446..8b68dcc1ab03 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
@@ -43,8 +43,7 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.*;
import java.util.List;
/**
@@ -236,12 +235,15 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase {
});
}
});
- return new DefaultExecutionResult(consoleView, processHandler);
+ DefaultExecutionResult result = new DefaultExecutionResult(consoleView, processHandler);
+ result.setRestartActions(consoleManager.getRestartActions());
+ return result;
}
}
private static class MyProcessHandler extends ProcessHandler {
private final ExternalSystemExecuteTaskTask myTask;
+ @Nullable private volatile OutputStream myOutputStream;
public MyProcessHandler(ExternalSystemExecuteTaskTask task) {
myTask = task;
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java
index b38cda93ea1a..75a227518b46 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationManager.java
@@ -133,6 +133,7 @@ public class ExternalSystemNotificationManager {
public void run() {
app.runWriteAction(new Runnable() {
public void run() {
+ if (myProject.isDisposed()) return;
ExternalSystemUtil.ensureToolWindowContentInitialized(myProject, externalSystemId);
initializedExternalSystem.add(externalSystemId);
}
@@ -305,9 +306,11 @@ public class ExternalSystemNotificationManager {
}
@NotNull
- private NewErrorTreeViewPanel prepareMessagesView(@NotNull final ProjectSystemId externalSystemId,
+ public NewErrorTreeViewPanel prepareMessagesView(@NotNull final ProjectSystemId externalSystemId,
@NotNull final NotificationSource notificationSource,
boolean activateView) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
final NewErrorTreeViewPanel errorTreeView;
final String contentDisplayName = getContentDisplayName(notificationSource, externalSystemId);
final Pair<NotificationSource, ProjectSystemId> contentIdPair = Pair.create(notificationSource, externalSystemId);
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java
index 12828629a616..76c94b061bfb 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/ExternalSystemTasksTree.java
@@ -208,6 +208,8 @@ public class ExternalSystemTasksTree extends Tree implements Producer<ExternalTa
taskExecutionSettings.setExternalProjectPath(executionSettings.getExternalProjectPath());
taskExecutionSettings.setExternalSystemIdString(executionSettings.getExternalSystemIdString());
taskExecutionSettings.setVmOptions(executionSettings.getVmOptions());
+ taskExecutionSettings.setScriptParameters(executionSettings.getScriptParameters());
+ taskExecutionSettings.setExecutionName(executionSettings.getExecutionName());
executionInfo = new ExternalTaskExecutionInfo(taskExecutionSettings, taskExecutionInfo.getExecutorId());
map.put(key, executionInfo);
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
index 969c5b2c5815..786f96ffd8c2 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java
@@ -19,9 +19,13 @@ import com.intellij.execution.*;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
+import com.intellij.execution.process.ProcessAdapter;
+import com.intellij.execution.process.ProcessEvent;
+import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.rmi.RemoteUtil;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.Application;
@@ -58,6 +62,7 @@ import com.intellij.openapi.externalSystem.service.task.ui.ExternalSystemRecentT
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
+import com.intellij.openapi.externalSystem.task.TaskCallback;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -67,7 +72,9 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -83,6 +90,7 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
+import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.UIUtil;
@@ -539,23 +547,120 @@ public class ExternalSystemUtil {
@NotNull String executorId,
@NotNull Project project,
@NotNull ProjectSystemId externalSystemId) {
- runTask(taskSettings, executorId, project, externalSystemId, null);
+ runTask(taskSettings, executorId, project, externalSystemId, null, ProgressExecutionMode.IN_BACKGROUND_ASYNC);
}
- public static void runTask(@NotNull ExternalSystemTaskExecutionSettings taskSettings,
- @NotNull String executorId,
- @NotNull Project project,
- @NotNull ProjectSystemId externalSystemId,
- @Nullable ProgramRunner.Callback callback) {
+ public static void runTask(@NotNull final ExternalSystemTaskExecutionSettings taskSettings,
+ @NotNull final String executorId,
+ @NotNull final Project project,
+ @NotNull final ProjectSystemId externalSystemId,
+ @Nullable final TaskCallback callback,
+ @NotNull final ProgressExecutionMode progressExecutionMode) {
final Pair<ProgramRunner, ExecutionEnvironment> pair = createRunner(taskSettings, executorId, project, externalSystemId);
if (pair == null) return;
- try {
- pair.first.execute(pair.second, callback);
- }
- catch (ExecutionException e) {
- LOG.warn("Can't execute task " + taskSettings, e);
- }
+ final ProgramRunner runner = pair.first;
+ final ExecutionEnvironment environment = pair.second;
+
+ final TaskUnderProgress task = new TaskUnderProgress() {
+ @Override
+ public void execute(@NotNull ProgressIndicator indicator) {
+ final Semaphore targetDone = new Semaphore();
+ final Ref<Boolean> result = new Ref<Boolean>(false);
+ final Disposable disposable = Disposer.newDisposable();
+
+ project.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
+ public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
+ if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
+ targetDone.down();
+ }
+ }
+
+ public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
+ if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
+ targetDone.up();
+ }
+ }
+
+ public void processStarted(final String executorIdLocal,
+ @NotNull final ExecutionEnvironment environmentLocal,
+ @NotNull final ProcessHandler handler) {
+ if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
+ handler.addProcessListener(new ProcessAdapter() {
+ public void processTerminated(ProcessEvent event) {
+ result.set(event.getExitCode() == 0);
+ targetDone.up();
+ }
+ });
+ }
+ }
+ });
+
+ try {
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ runner.execute(environment);
+ }
+ catch (ExecutionException e) {
+ targetDone.up();
+ LOG.error(e);
+ }
+ }
+ }, ModalityState.NON_MODAL);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ Disposer.dispose(disposable);
+ return;
+ }
+
+ targetDone.waitFor();
+ Disposer.dispose(disposable);
+
+ if (callback != null) {
+ if (result.get()) {
+ callback.onSuccess();
+ }
+ else {
+ callback.onFailure();
+ }
+ }
+ }
+ };
+
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ final String title = AbstractExternalSystemTaskConfigurationType.generateName(project, taskSettings);
+ switch (progressExecutionMode) {
+ case MODAL_SYNC:
+ new Task.Modal(project, title, true) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ task.execute(indicator);
+ }
+ }.queue();
+ break;
+ case IN_BACKGROUND_ASYNC:
+ new Task.Backgroundable(project, title) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ task.execute(indicator);
+ }
+ }.queue();
+ break;
+ case START_IN_FOREGROUND_ASYNC:
+ new Task.Backgroundable(project, title, true, PerformInBackgroundOption.DEAF) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ task.execute(indicator);
+ }
+ }.queue();
+ }
+ }
+ });
}
@Nullable
@@ -579,7 +684,11 @@ public class ExternalSystemUtil {
RunnerAndConfigurationSettings settings = RunManager.getInstance(project).createRunConfiguration(name, configurationType.getFactory());
ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)settings.getConfiguration();
runConfiguration.getSettings().setExternalProjectPath(taskSettings.getExternalProjectPath());
- runConfiguration.getSettings().setTaskNames(taskSettings.getTaskNames());
+ runConfiguration.getSettings().setTaskNames(ContainerUtil.newArrayList(taskSettings.getTaskNames()));
+ runConfiguration.getSettings().setTaskDescriptions(ContainerUtil.newArrayList(taskSettings.getTaskDescriptions()));
+ runConfiguration.getSettings().setVmOptions(taskSettings.getVmOptions());
+ runConfiguration.getSettings().setScriptParameters(taskSettings.getScriptParameters());
+ runConfiguration.getSettings().setExecutionName(taskSettings.getExecutionName());
return Pair.create(runner, new ExecutionEnvironment(executor, runner, settings, project));
}
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java
new file mode 100644
index 000000000000..6107a00b7107
--- /dev/null
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.test;
+
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TestDialog;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.util.Function;
+import com.intellij.util.PathUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.ContainerUtilRt;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.JavaResourceRootType;
+import org.jetbrains.jps.model.java.JavaSourceRootProperties;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/30/2014
+ */
+public abstract class ExternalSystemImportingTestCase extends ExternalSystemTestCase {
+
+ @Override
+ protected void setUpInWriteAction() throws Exception {
+ super.setUpInWriteAction();
+ }
+
+ protected void assertModules(String... expectedNames) {
+ Module[] actual = ModuleManager.getInstance(myProject).getModules();
+ List<String> actualNames = new ArrayList<String>();
+
+ for (Module m : actual) {
+ actualNames.add(m.getName());
+ }
+
+ assertUnorderedElementsAreEqual(actualNames, expectedNames);
+ }
+
+ protected void assertContentRoots(String moduleName, String... expectedRoots) {
+ List<String> actual = new ArrayList<String>();
+ for (ContentEntry e : getContentRoots(moduleName)) {
+ actual.add(e.getUrl());
+ }
+
+ for (int i = 0; i < expectedRoots.length; i++) {
+ expectedRoots[i] = VfsUtilCore.pathToUrl(expectedRoots[i]);
+ }
+
+ assertUnorderedPathsAreEqual(actual, Arrays.asList(expectedRoots));
+ }
+
+ protected void assertSources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
+ }
+
+ protected void assertGeneratedSources(String moduleName, String... expectedSources) {
+ ContentEntry contentRoot = getContentRoot(moduleName);
+ List<ContentFolder> folders = new ArrayList<ContentFolder>();
+ for (SourceFolder folder : contentRoot.getSourceFolders(JavaSourceRootType.SOURCE)) {
+ JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaSourceRootType.SOURCE);
+ assertNotNull(properties);
+ if (properties.isForGeneratedSources()) {
+ folders.add(folder);
+ }
+ }
+ doAssertContentFolders(contentRoot, folders, expectedSources);
+ }
+
+ protected void assertResources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
+ }
+
+ protected void assertTestSources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
+ }
+
+ protected void assertTestResources(String moduleName, String... expectedSources) {
+ doAssertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
+ }
+
+ protected void assertExcludes(String moduleName, String... expectedExcludes) {
+ ContentEntry contentRoot = getContentRoot(moduleName);
+ doAssertContentFolders(contentRoot, Arrays.asList(contentRoot.getExcludeFolders()), expectedExcludes);
+ }
+
+ protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
+ ContentEntry root = getContentRoot(moduleName, contentRoot);
+ doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes);
+ }
+
+ private void doAssertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType<?> rootType, String... expected) {
+ ContentEntry contentRoot = getContentRoot(moduleName);
+ doAssertContentFolders(contentRoot, contentRoot.getSourceFolders(rootType), expected);
+ }
+
+ private static void doAssertContentFolders(ContentEntry e, final List<? extends ContentFolder> folders, String... expected) {
+ List<String> actual = new ArrayList<String>();
+ for (ContentFolder f : folders) {
+ String rootUrl = e.getUrl();
+ String folderUrl = f.getUrl();
+
+ if (folderUrl.startsWith(rootUrl)) {
+ int length = rootUrl.length() + 1;
+ folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
+ }
+
+ actual.add(folderUrl);
+ }
+
+ assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
+ }
+
+ protected void assertModuleOutput(String moduleName, String output, String testOutput) {
+ CompilerModuleExtension e = getCompilerExtension(moduleName);
+
+ assertFalse(e.isCompilerOutputPathInherited());
+ assertEquals(output, getAbsolutePath(e.getCompilerOutputUrl()));
+ assertEquals(testOutput, getAbsolutePath(e.getCompilerOutputUrlForTests()));
+ }
+
+ private static String getAbsolutePath(String path) {
+ path = VfsUtil.urlToPath(path);
+ path = PathUtil.getCanonicalPath(path);
+ return FileUtil.toSystemIndependentName(path);
+ }
+
+ protected void assertProjectOutput(String module) {
+ assertTrue(getCompilerExtension(module).isCompilerOutputPathInherited());
+ }
+
+ protected CompilerModuleExtension getCompilerExtension(String module) {
+ ModuleRootManager m = getRootManager(module);
+ return CompilerModuleExtension.getInstance(m.getModule());
+ }
+
+ protected void assertModuleLibDep(String moduleName, String depName) {
+ assertModuleLibDep(moduleName, depName, null);
+ }
+
+ protected void assertModuleLibDep(String moduleName, String depName, String classesPath) {
+ assertModuleLibDep(moduleName, depName, classesPath, null, null);
+ }
+
+ protected void assertModuleLibDep(String moduleName, String depName, String classesPath, String sourcePath, String javadocPath) {
+ LibraryOrderEntry lib = ContainerUtil.getFirstItem(getModuleLibDeps(moduleName, depName));
+
+ assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
+ assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
+ assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPath == null ? null : Collections.singletonList(javadocPath));
+ }
+
+ protected void assertModuleLibDep(String moduleName,
+ String depName,
+ List<String> classesPaths,
+ List<String> sourcePaths,
+ List<String> javadocPaths) {
+ LibraryOrderEntry lib = ContainerUtil.getFirstItem(getModuleLibDeps(moduleName, depName));
+
+ assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
+ assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePaths);
+ assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPaths);
+ }
+
+ private static void assertModuleLibDepPath(LibraryOrderEntry lib, OrderRootType type, List<String> paths) {
+ if (paths == null) return;
+ assertUnorderedPathsAreEqual(Arrays.asList(lib.getRootUrls(type)), paths);
+ // also check the library because it may contain slight different set of urls (e.g. with duplicates)
+ final Library library = lib.getLibrary();
+ assertNotNull(library);
+ assertUnorderedPathsAreEqual(Arrays.asList(library.getUrls(type)), paths);
+ }
+
+ protected void assertModuleLibDepScope(String moduleName, String depName, DependencyScope scopes) {
+ List<LibraryOrderEntry> deps = getModuleLibDeps(moduleName, depName);
+ assertUnorderedElementsAreEqual(ContainerUtil.map2Array(deps, new Function<LibraryOrderEntry, Object>() {
+ @Override
+ public Object fun(LibraryOrderEntry entry) {
+ return entry.getScope();
+ }
+ }), scopes);
+ }
+
+ private List<LibraryOrderEntry> getModuleLibDeps(String moduleName, String depName) {
+ return getModuleDep(moduleName, depName, LibraryOrderEntry.class);
+ }
+
+ protected void assertModuleLibDeps(String moduleName, String... expectedDeps) {
+ assertModuleDeps(moduleName, LibraryOrderEntry.class, expectedDeps);
+ }
+
+ protected void assertExportedDeps(String moduleName, String... expectedDeps) {
+ final List<String> actual = new ArrayList<String>();
+
+ getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly().process(new RootPolicy<Object>() {
+ @Override
+ public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) {
+ actual.add(e.getModuleName());
+ return null;
+ }
+
+ @Override
+ public Object visitLibraryOrderEntry(LibraryOrderEntry e, Object value) {
+ actual.add(e.getLibraryName());
+ return null;
+ }
+ }, null);
+
+ assertOrderedElementsAreEqual(actual, expectedDeps);
+ }
+
+ protected void assertModuleModuleDeps(String moduleName, String... expectedDeps) {
+ assertModuleDeps(moduleName, ModuleOrderEntry.class, expectedDeps);
+ }
+
+ private void assertModuleDeps(String moduleName, Class clazz, String... expectedDeps) {
+ assertOrderedElementsAreEqual(collectModuleDepsNames(moduleName, clazz), expectedDeps);
+ }
+
+ protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope... scopes) {
+ List<ModuleOrderEntry> deps = getModuleModuleDeps(moduleName, depName);
+ assertUnorderedElementsAreEqual(ContainerUtil.map2Array(deps, new Function<ModuleOrderEntry, Object>() {
+ @Override
+ public Object fun(ModuleOrderEntry entry) {
+ return entry.getScope();
+ }
+ }), scopes);
+ }
+
+ @NotNull
+ private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
+ return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
+ }
+
+ private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
+ List<String> actual = new ArrayList<String>();
+
+ for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
+ if (clazz.isInstance(e)) {
+ actual.add(e.getPresentableName());
+ }
+ }
+ return actual;
+ }
+
+ @NotNull
+ private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
+ List<T> deps = ContainerUtil.newArrayList();
+
+ for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
+ if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
+ deps.add((T)e);
+ }
+ }
+ assertNotNull("Dependency not found: " + depName + "\namong: " + collectModuleDepsNames(moduleName, clazz), deps);
+ return deps;
+ }
+
+ public void assertProjectLibraries(String... expectedNames) {
+ List<String> actualNames = new ArrayList<String>();
+ for (Library each : ProjectLibraryTable.getInstance(myProject).getLibraries()) {
+ String name = each.getName();
+ actualNames.add(name == null ? "<unnamed>" : name);
+ }
+ assertUnorderedElementsAreEqual(actualNames, expectedNames);
+ }
+
+ protected void assertModuleGroupPath(String moduleName, String... expected) {
+ String[] path = ModuleManager.getInstance(myProject).getModuleGroupPath(getModule(moduleName));
+
+ if (expected.length == 0) {
+ assertNull(path);
+ }
+ else {
+ assertNotNull(path);
+ assertOrderedElementsAreEqual(Arrays.asList(path), expected);
+ }
+ }
+
+ protected Module getModule(final String name) {
+ AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
+ try {
+ Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
+ assertNotNull("Module " + name + " not found", m);
+ return m;
+ }
+ finally {
+ accessToken.finish();
+ }
+ }
+
+ private ContentEntry getContentRoot(String moduleName) {
+ ContentEntry[] ee = getContentRoots(moduleName);
+ List<String> roots = new ArrayList<String>();
+ for (ContentEntry e : ee) {
+ roots.add(e.getUrl());
+ }
+
+ String message = "Several content roots found: [" + StringUtil.join(roots, ", ") + "]";
+ assertEquals(message, 1, ee.length);
+
+ return ee[0];
+ }
+
+ private ContentEntry getContentRoot(String moduleName, String path) {
+ for (ContentEntry e : getContentRoots(moduleName)) {
+ if (e.getUrl().equals(VfsUtilCore.pathToUrl(path))) return e;
+ }
+ throw new AssertionError("content root not found");
+ }
+
+ public ContentEntry[] getContentRoots(String moduleName) {
+ return getRootManager(moduleName).getContentEntries();
+ }
+
+ private ModuleRootManager getRootManager(String module) {
+ return ModuleRootManager.getInstance(getModule(module));
+ }
+
+ protected void importProject(@NonNls String config) throws IOException {
+ createProjectConfig(config);
+ importProject();
+ }
+
+ protected void importProject() {
+ doImportProject();
+ }
+
+ private void doImportProject() {
+ AbstractExternalSystemSettings systemSettings = ExternalSystemApiUtil.getSettings(myProject, getExternalSystemId());
+ final ExternalProjectSettings projectSettings = getCurrentExternalProjectSettings();
+ projectSettings.setExternalProjectPath(getProjectPath());
+ Set<ExternalProjectSettings> projects = ContainerUtilRt.newHashSet(systemSettings.getLinkedProjectsSettings());
+ projects.remove(projectSettings);
+ projects.add(projectSettings);
+ systemSettings.setLinkedProjectsSettings(projects);
+
+ ExternalSystemUtil.refreshProjects(
+ new ImportSpecBuilder(myProject, getExternalSystemId()).use(ProgressExecutionMode.MODAL_SYNC)
+ );
+ }
+
+ protected abstract ExternalProjectSettings getCurrentExternalProjectSettings();
+
+ protected abstract ProjectSystemId getExternalSystemId();
+
+ protected void setupJdkForModules(String... moduleNames) {
+ for (String each : moduleNames) {
+ setupJdkForModule(each);
+ }
+ }
+
+ protected Sdk setupJdkForModule(final String moduleName) {
+ final Sdk sdk = true ? JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk() : createJdk("Java 1.5");
+ ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
+ return sdk;
+ }
+
+ protected static Sdk createJdk(String versionName) {
+ return IdeaTestUtil.getMockJdk17(versionName);
+ }
+
+ protected static AtomicInteger configConfirmationForYesAnswer() {
+ final AtomicInteger counter = new AtomicInteger();
+ Messages.setTestDialog(new TestDialog() {
+ @Override
+ public int show(String message) {
+ counter.set(counter.get() + 1);
+ return 0;
+ }
+ });
+ return counter;
+ }
+
+ protected static AtomicInteger configConfirmationForNoAnswer() {
+ final AtomicInteger counter = new AtomicInteger();
+ Messages.setTestDialog(new TestDialog() {
+ @Override
+ public int show(String message) {
+ counter.set(counter.get() + 1);
+ return 1;
+ }
+ });
+ return counter;
+ }
+
+ //protected void assertProblems(String... expectedProblems) {
+ // final List<String> actualProblems = new ArrayList<String>();
+ // UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ // @Override
+ // public void run() {
+ // final NewErrorTreeViewPanel messagesView = ExternalSystemNotificationManager.getInstance(myProject)
+ // .prepareMessagesView(getExternalSystemId(), NotificationSource.PROJECT_SYNC, false);
+ // final ErrorViewStructure treeStructure = messagesView.getErrorViewStructure();
+ //
+ // ErrorTreeElement[] elements = treeStructure.getChildElements(treeStructure.getRootElement());
+ // for (ErrorTreeElement element : elements) {
+ // if (element.getKind() == ErrorTreeElementKind.ERROR ||
+ // element.getKind() == ErrorTreeElementKind.WARNING) {
+ // actualProblems.add(StringUtil.join(element.getText(), "\n"));
+ // }
+ // }
+ // }
+ // });
+ //
+ // assertOrderedElementsAreEqual(actualProblems, expectedProblems);
+ //}
+}
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java
new file mode 100644
index 000000000000..22ec927eb30d
--- /dev/null
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.test;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
+import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
+import com.intellij.util.ui.UIUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.junit.After;
+import org.junit.Before;
+
+import java.awt.*;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/30/2014
+ */
+public abstract class ExternalSystemTestCase extends UsefulTestCase {
+ private static File ourTempDir;
+
+ protected IdeaProjectTestFixture myTestFixture;
+
+ protected Project myProject;
+
+ protected File myTestDir;
+ protected VirtualFile myProjectRoot;
+ protected VirtualFile myProjectConfig;
+ protected List<VirtualFile> myAllConfigs = new ArrayList<VirtualFile>();
+
+ static {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ensureTempDirCreated();
+
+ myTestDir = new File(ourTempDir, getTestName(false));
+ FileUtil.ensureExists(myTestDir);
+
+ setUpFixtures();
+ myProject = myTestFixture.getProject();
+
+ edt(new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ setUpInWriteAction();
+ }
+ catch (Throwable e) {
+ try {
+ tearDown();
+ }
+ catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+ });
+ }
+
+ private void ensureTempDirCreated() throws IOException {
+ if (ourTempDir != null) return;
+
+ ourTempDir = new File(FileUtil.getTempDirectory(), getTestsTempDir());
+ FileUtil.delete(ourTempDir);
+ FileUtil.ensureExists(ourTempDir);
+ }
+
+ protected abstract String getTestsTempDir();
+
+ protected void setUpFixtures() throws Exception {
+ myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture();
+ myTestFixture.setUp();
+ }
+
+ protected void setUpInWriteAction() throws Exception {
+ File projectDir = new File(myTestDir, "project");
+ FileUtil.ensureExists(projectDir);
+ myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir);
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ myProject = null;
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ tearDownFixtures();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ if (!FileUtil.delete(myTestDir) && myTestDir.exists()) {
+ System.err.println("Cannot delete " + myTestDir);
+ //printDirectoryContent(myDir);
+ myTestDir.deleteOnExit();
+ }
+ }
+ finally {
+ super.tearDown();
+ resetClassFields(getClass());
+ }
+ }
+
+ private static void printDirectoryContent(File dir) {
+ File[] files = dir.listFiles();
+ if (files == null) return;
+
+ for (File file : files) {
+ System.out.println(file.getAbsolutePath());
+
+ if (file.isDirectory()) {
+ printDirectoryContent(file);
+ }
+ }
+ }
+
+ protected void tearDownFixtures() throws Exception {
+ myTestFixture.tearDown();
+ myTestFixture = null;
+ }
+
+ private void resetClassFields(final Class<?> aClass) {
+ if (aClass == null) return;
+
+ final Field[] fields = aClass.getDeclaredFields();
+ for (Field field : fields) {
+ final int modifiers = field.getModifiers();
+ if ((modifiers & Modifier.FINAL) == 0
+ && (modifiers & Modifier.STATIC) == 0
+ && !field.getType().isPrimitive()) {
+ field.setAccessible(true);
+ try {
+ field.set(this, null);
+ }
+ catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ if (aClass == ExternalSystemTestCase.class) return;
+ resetClassFields(aClass.getSuperclass());
+ }
+
+ @Override
+ protected void runTest() throws Throwable {
+ try {
+ if (runInWriteAction()) {
+ new WriteAction() {
+ @Override
+ protected void run(@NotNull Result result) throws Throwable {
+ ExternalSystemTestCase.super.runTest();
+ }
+ }.executeSilently().throwException();
+ }
+ else {
+ ExternalSystemTestCase.super.runTest();
+ }
+ }
+ catch (Exception throwable) {
+ Throwable each = throwable;
+ do {
+ if (each instanceof HeadlessException) {
+ printIgnoredMessage("Doesn't work in Headless environment");
+ return;
+ }
+ }
+ while ((each = each.getCause()) != null);
+ throw throwable;
+ }
+ }
+
+ @Override
+ protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
+ runnable.run();
+ }
+
+ protected boolean runInWriteAction() {
+ return false;
+ }
+
+ protected static String getRoot() {
+ if (SystemInfo.isWindows) return "c:";
+ return "";
+ }
+
+ protected static String getEnvVar() {
+ if (SystemInfo.isWindows) return "TEMP";
+ else if (SystemInfo.isLinux) return "HOME";
+ return "TMPDIR";
+ }
+
+ protected String getProjectPath() {
+ return myProjectRoot.getPath();
+ }
+
+ protected String getParentPath() {
+ return myProjectRoot.getParent().getPath();
+ }
+
+ protected String pathFromBasedir(String relPath) {
+ return pathFromBasedir(myProjectRoot, relPath);
+ }
+
+ protected static String pathFromBasedir(VirtualFile root, String relPath) {
+ return FileUtil.toSystemIndependentName(root.getPath() + "/" + relPath);
+ }
+
+ protected Module createModule(String name) throws IOException {
+ return createModule(name, StdModuleTypes.JAVA);
+ }
+
+ protected Module createModule(final String name, final ModuleType type) throws IOException {
+ return new WriteCommandAction<Module>(myProject) {
+ @Override
+ protected void run(Result<Module> moduleResult) throws Throwable {
+ VirtualFile f = createProjectSubFile(name + "/" + name + ".iml");
+ Module module = ModuleManager.getInstance(myProject).newModule(f.getPath(), type.getId());
+ PsiTestUtil.addContentRoot(module, f.getParent());
+ moduleResult.setResult(module);
+ }
+ }.execute().getResultObject();
+ }
+
+ protected VirtualFile createProjectConfig(@NonNls String config) throws IOException {
+ return myProjectConfig = createConfigFile(myProjectRoot, config);
+ }
+
+ protected VirtualFile createConfigFile(final VirtualFile dir, String config) throws IOException {
+ final String configFileName = getExternalSystemConfigFileName();
+ VirtualFile f = dir.findChild(configFileName);
+ if (f == null) {
+ f = new WriteAction<VirtualFile>() {
+ @Override
+ protected void run(Result<VirtualFile> result) throws Throwable {
+ VirtualFile res = dir.createChildData(null, configFileName);
+ result.setResult(res);
+ }
+ }.execute().getResultObject();
+ myAllConfigs.add(f);
+ }
+ setFileContent(f, config, true);
+ return f;
+ }
+
+ protected abstract String getExternalSystemConfigFileName();
+
+ protected void createStdProjectFolders() throws IOException {
+ createProjectSubDirs("src/main/java",
+ "src/main/resources",
+ "src/test/java",
+ "src/test/resources");
+ }
+
+ protected void createProjectSubDirs(String... relativePaths) throws IOException {
+ for (String path : relativePaths) {
+ createProjectSubDir(path);
+ }
+ }
+
+ protected VirtualFile createProjectSubDir(String relativePath) throws IOException {
+ File f = new File(getProjectPath(), relativePath);
+ FileUtil.ensureExists(f);
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
+ }
+
+ protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
+ File f = new File(getProjectPath(), relativePath);
+ FileUtil.ensureExists(f.getParentFile());
+ f.createNewFile();
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
+ }
+
+ protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException {
+ VirtualFile file = createProjectSubFile(relativePath);
+ setFileContent(file, content, false);
+ return file;
+ }
+
+ private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
+ new WriteAction<VirtualFile>() {
+ @Override
+ protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
+ if (advanceStamps) {
+ file.setBinaryContent(content.getBytes("UTF-8"), -1, file.getTimeStamp() + 4000);
+ }
+ else {
+ file.setBinaryContent(content.getBytes("UTF-8"), file.getModificationStamp(), file.getTimeStamp());
+ }
+ }
+ }.execute().getResultObject();
+ }
+
+ protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, Collection<T> expected) {
+ assertOrderedElementsAreEqual(actual, expected.toArray());
+ }
+
+ protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) {
+ assertEquals(new HashSet<T>(expected), new HashSet<T>(actual));
+ }
+ protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) {
+ assertEquals(new SetWithToString<String>(new THashSet<String>(expected, FileUtil.PATH_HASHING_STRATEGY)),
+ new SetWithToString<String>(new THashSet<String>(actual, FileUtil.PATH_HASHING_STRATEGY)));
+ }
+
+ protected static <T> void assertUnorderedElementsAreEqual(T[] actual, T... expected) {
+ assertUnorderedElementsAreEqual(Arrays.asList(actual), expected);
+ }
+
+ protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, T... expected) {
+ assertUnorderedElementsAreEqual(actual, Arrays.asList(expected));
+ }
+
+ protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, T... expected) {
+ String s = "\nexpected: " + Arrays.asList(expected) + "\nactual: " + new ArrayList<U>(actual);
+ assertEquals(s, expected.length, actual.size());
+
+ java.util.List<U> actualList = new ArrayList<U>(actual);
+ for (int i = 0; i < expected.length; i++) {
+ T expectedElement = expected[i];
+ U actualElement = actualList.get(i);
+ assertEquals(s, expectedElement, actualElement);
+ }
+ }
+
+ protected static <T> void assertContain(java.util.List<? extends T> actual, T... expected) {
+ java.util.List<T> expectedList = Arrays.asList(expected);
+ assertTrue("expected: " + expectedList + "\n" + "actual: " + actual.toString(), actual.containsAll(expectedList));
+ }
+
+ protected static <T> void assertDoNotContain(java.util.List<T> actual, T... expected) {
+ java.util.List<T> actualCopy = new ArrayList<T>(actual);
+ actualCopy.removeAll(Arrays.asList(expected));
+ assertEquals(actual.toString(), actualCopy.size(), actual.size());
+ }
+
+ protected boolean ignore() {
+ printIgnoredMessage(null);
+ return true;
+ }
+
+ private void printIgnoredMessage(String message) {
+ String toPrint = "Ignored";
+ if (message != null) {
+ toPrint += ", because " + message;
+ }
+ toPrint += ": " + getClass().getSimpleName() + "." + getName();
+ System.out.println(toPrint);
+ }
+
+ private static class SetWithToString<T> extends AbstractSet<T> {
+
+ private final Set<T> myDelegate;
+
+ public SetWithToString(@NotNull Set<T> delegate) {
+ myDelegate = delegate;
+ }
+
+ @Override
+ public int size() {
+ return myDelegate.size();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return myDelegate.contains(o);
+ }
+
+ @NotNull
+ @Override
+ public Iterator<T> iterator() {
+ return myDelegate.iterator();
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return myDelegate.containsAll(c);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return myDelegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return myDelegate.hashCode();
+ }
+ }
+
+}
diff --git a/platform/funcTests/config/disabled_plugins.txt b/platform/funcTests/config/disabled_plugins.txt
index 42ea4781809e..64c25fd2d5e9 100644
--- a/platform/funcTests/config/disabled_plugins.txt
+++ b/platform/funcTests/config/disabled_plugins.txt
@@ -78,7 +78,6 @@ com.jetbrains.jarFinder
com.jetbrains.php.framework
com.intellij.seam.pages
JSR45Plugin
-com.intellij.sql
ActionScript Profiler
JavaScriptDebugger
com.intellij.tapestry
@@ -92,7 +91,7 @@ org.jetbrains.android
com.intellij.gwt
com.intellij.spring.data
JSIntentionPowerPack
-com.intellij.persistence.database
+com.intellij.database
com.intellij.seam
ClearcasePlugin
SourceSafe
diff --git a/platform/icons/src/css/pseudo-class.png b/platform/icons/src/css/pseudo-class.png
new file mode 100755
index 000000000000..5d96d962ec1d
--- /dev/null
+++ b/platform/icons/src/css/pseudo-class.png
Binary files differ
diff --git a/platform/icons/src/css/pseudo-class@2x.png b/platform/icons/src/css/pseudo-class@2x.png
new file mode 100644
index 000000000000..ab53f693baef
--- /dev/null
+++ b/platform/icons/src/css/pseudo-class@2x.png
Binary files differ
diff --git a/platform/icons/src/css/pseudo-element.png b/platform/icons/src/css/pseudo-element.png
index 5d96d962ec1d..93f789d24838 100755..100644
--- a/platform/icons/src/css/pseudo-element.png
+++ b/platform/icons/src/css/pseudo-element.png
Binary files differ
diff --git a/platform/icons/src/css/pseudo-element@2x.png b/platform/icons/src/css/pseudo-element@2x.png
index ab53f693baef..db9608aa7216 100644
--- a/platform/icons/src/css/pseudo-element@2x.png
+++ b/platform/icons/src/css/pseudo-element@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/desktop.png b/platform/icons/src/nodes/desktop.png
new file mode 100644
index 000000000000..87ff8cdbd5c7
--- /dev/null
+++ b/platform/icons/src/nodes/desktop.png
Binary files differ
diff --git a/platform/icons/src/nodes/desktop@2x.png b/platform/icons/src/nodes/desktop@2x.png
new file mode 100644
index 000000000000..ea76a8f62b59
--- /dev/null
+++ b/platform/icons/src/nodes/desktop@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/pluginLogo.png b/platform/icons/src/nodes/pluginLogo.png
new file mode 100644
index 000000000000..83604cc023ed
--- /dev/null
+++ b/platform/icons/src/nodes/pluginLogo.png
Binary files differ
diff --git a/platform/icons/src/nodes/ppWebLogo.png b/platform/icons/src/nodes/ppWebLogo.png
new file mode 100644
index 000000000000..28cef24ac185
--- /dev/null
+++ b/platform/icons/src/nodes/ppWebLogo.png
Binary files differ
diff --git a/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java b/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
index 098bd862cab7..fc5de78f9407 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -81,6 +81,7 @@ public class IndexPattern {
}
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -93,6 +94,7 @@ public class IndexPattern {
return true;
}
+ @Override
public int hashCode() {
int result = myPatternString.hashCode();
result = 29 * result + (myCaseSensitive ? 1 : 0);
diff --git a/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java b/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java
index 0e40573d9c97..9217e15d7987 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -86,6 +86,7 @@ public class ProjectAndLibrariesScope extends GlobalSearchScope {
return true;
}
+ @NotNull
public String getDisplayName() {
return PsiBundle.message("psi.search.scope.project.and.libraries");
}
diff --git a/platform/indexing-api/src/com/intellij/psi/search/PsiSearchRequest.java b/platform/indexing-api/src/com/intellij/psi/search/PsiSearchRequest.java
index 3bb6792653f0..bc4f8c7f0f5e 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/PsiSearchRequest.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/PsiSearchRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,8 +21,8 @@ import org.jetbrains.annotations.NotNull;
* @author peter
*/
public class PsiSearchRequest {
- public final SearchScope searchScope;
- public final String word;
+ @NotNull public final SearchScope searchScope;
+ @NotNull public final String word;
public final short searchContext;
public final boolean caseSensitive;
public final RequestResultProcessor processor;
diff --git a/platform/indexing-api/src/com/intellij/psi/search/TextOccurenceProcessor.java b/platform/indexing-api/src/com/intellij/psi/search/TextOccurenceProcessor.java
index bd533a186bc7..929fb543e497 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/TextOccurenceProcessor.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/TextOccurenceProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,10 +17,11 @@
package com.intellij.psi.search;
import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
public interface TextOccurenceProcessor {
- boolean execute (PsiElement element, int offsetInElement);
+ boolean execute(@NotNull PsiElement element, int offsetInElement);
}
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
index 5b3765930b41..4e94617e7681 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/DefinitionsScopedSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -63,16 +63,17 @@ public class DefinitionsScopedSearch extends ExtensibleQueryFactory<PsiElement,
private final SearchScope myScope;
private final boolean myCheckDeep;
- public SearchParameters(PsiElement element) {
+ public SearchParameters(@NotNull PsiElement element) {
this(element, element.getUseScope(), true);
}
- public SearchParameters(final PsiElement element, SearchScope scope, final boolean checkDeep) {
+ public SearchParameters(@NotNull PsiElement element, @NotNull SearchScope scope, final boolean checkDeep) {
myElement = element;
myScope = scope;
myCheckDeep = checkDeep;
}
+ @NotNull
public PsiElement getElement() {
return myElement;
}
@@ -81,6 +82,7 @@ public class DefinitionsScopedSearch extends ExtensibleQueryFactory<PsiElement,
return myCheckDeep;
}
+ @NotNull
public SearchScope getScope() {
return ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/IndexPatternSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/IndexPatternSearch.java
index 38044782796d..53f71e882ff7 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/IndexPatternSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/IndexPatternSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -64,6 +64,7 @@ public abstract class IndexPatternSearch extends QueryFactory<IndexPatternOccurr
myPattern = null;
}
+ @NotNull
public PsiFile getFile() {
return myFile;
}
@@ -92,6 +93,7 @@ public abstract class IndexPatternSearch extends QueryFactory<IndexPatternOccurr
* @param pattern the pattern to search for.
* @return the query instance.
*/
+ @NotNull
public static Query<IndexPatternOccurrence> search(@NotNull PsiFile file, @NotNull IndexPattern pattern) {
final SearchParameters parameters = new SearchParameters(file, pattern);
return INDEX_PATTERN_SEARCH_INSTANCE.createQuery(parameters);
@@ -107,9 +109,11 @@ public abstract class IndexPatternSearch extends QueryFactory<IndexPatternOccurr
* @param endOffset the end offset of the range to search.
* @return the query instance.
*/
+ @NotNull
public static Query<IndexPatternOccurrence> search(@NotNull PsiFile file,
@NotNull IndexPattern pattern,
- int startOffset, int endOffset) {
+ int startOffset,
+ int endOffset) {
final SearchParameters parameters = new SearchParameters(file, pattern, new TextRange(startOffset, endOffset));
return INDEX_PATTERN_SEARCH_INSTANCE.createQuery(parameters);
}
@@ -123,6 +127,7 @@ public abstract class IndexPatternSearch extends QueryFactory<IndexPatternOccurr
* @param patternProvider the provider the patterns from which are searched.
* @return the query instance.
*/
+ @NotNull
public static Query<IndexPatternOccurrence> search(@NotNull PsiFile file, @NotNull IndexPatternProvider patternProvider) {
final SearchParameters parameters = new SearchParameters(file, patternProvider);
return INDEX_PATTERN_SEARCH_INSTANCE.createQuery(parameters);
@@ -139,6 +144,7 @@ public abstract class IndexPatternSearch extends QueryFactory<IndexPatternOccurr
* @param endOffset the end offset of the range to search.
* @return the query instance.
*/
+ @NotNull
public static Query<IndexPatternOccurrence> search(@NotNull PsiFile file, @NotNull IndexPatternProvider patternProvider,
int startOffset, int endOffset) {
final SearchParameters parameters = new SearchParameters(file, patternProvider, new TextRange(startOffset, endOffset));
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java
index 7653595d4e2b..153b34b8a46b 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
* @author max
*/
public class ReferenceDescriptor {
+ @NotNull
public static final Function<PsiReference, ReferenceDescriptor> MAPPER = new Function<PsiReference, ReferenceDescriptor>() {
@Override
public ReferenceDescriptor fun(PsiReference psiReference) {
@@ -36,7 +37,7 @@ public class ReferenceDescriptor {
private final PsiFile file;
private final int offset;
- ReferenceDescriptor(@NotNull PsiFile file, int offset) {
+ private ReferenceDescriptor(@NotNull PsiFile file, int offset) {
this.file = file;
this.offset = offset;
}
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
index fdaea59acd0c..aafb85d529bc 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -41,7 +41,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
private final SearchRequestCollector myOptimizer;
private final boolean isSharedOptimizer;
- public SearchParameters(@NotNull PsiElement elementToSearch, SearchScope scope, boolean ignoreAccessScope, @Nullable SearchRequestCollector optimizer) {
+ public SearchParameters(@NotNull PsiElement elementToSearch, @NotNull SearchScope scope, boolean ignoreAccessScope, @Nullable SearchRequestCollector optimizer) {
myElementToSearch = elementToSearch;
myScope = scope;
myIgnoreAccessScope = ignoreAccessScope;
@@ -49,7 +49,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
myOptimizer = optimizer == null ? new SearchRequestCollector(new SearchSession()) : optimizer;
}
- public SearchParameters(@NotNull final PsiElement elementToSearch, final SearchScope scope, final boolean ignoreAccessScope) {
+ public SearchParameters(@NotNull PsiElement elementToSearch, @NotNull SearchScope scope, final boolean ignoreAccessScope) {
this(elementToSearch, scope, ignoreAccessScope, null);
}
@@ -62,6 +62,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
* Use {@link #getEffectiveSearchScope} instead
*/
@Deprecated()
+ @NotNull
public SearchScope getScope() {
return myScope;
}
@@ -85,18 +86,22 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
}
}
+ @NotNull
public static Query<PsiReference> search(@NotNull PsiElement element) {
return search(element, GlobalSearchScope.allScope(element.getProject()), false);
}
+ @NotNull
public static Query<PsiReference> search(@NotNull PsiElement element, @NotNull SearchScope searchScope) {
return search(element, searchScope, false);
}
+ @NotNull
public static Query<PsiReference> search(@NotNull PsiElement element, @NotNull SearchScope searchScope, boolean ignoreAccessScope) {
return search(new SearchParameters(element, searchScope, ignoreAccessScope));
}
+ @NotNull
public static Query<PsiReference> search(@NotNull final SearchParameters parameters) {
final Query<PsiReference> result = INSTANCE.createQuery(parameters);
if (parameters.isSharedOptimizer) {
@@ -110,7 +115,8 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(element.getProject(), requests)));
}
- private static UniqueResultsQuery<PsiReference, ReferenceDescriptor> uniqueResults(Query<PsiReference> composite) {
+ @NotNull
+ private static UniqueResultsQuery<PsiReference, ReferenceDescriptor> uniqueResults(@NotNull Query<PsiReference> composite) {
return new UniqueResultsQuery<PsiReference, ReferenceDescriptor>(composite, ContainerUtil.<ReferenceDescriptor>canonicalStrategy(), ReferenceDescriptor.MAPPER);
}
diff --git a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
index d9b02a5be7f6..6726e56fad7e 100644
--- a/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
+++ b/platform/indexing-api/src/com/intellij/util/indexing/FileBasedIndexExtension.java
@@ -78,7 +78,7 @@ public abstract class FileBasedIndexExtension<K, V> {
return Collections.emptyList();
}
- public boolean isKeyHighlySelective() {
+ public boolean keyIsUniqueForIndexedFile() {
return false;
}
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryScope.java
index 2dcbf3558292..f78b69704db3 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
/**
* @author nik
@@ -32,6 +33,7 @@ public class LibraryScope extends LibraryScopeBase {
myLibrary = library;
}
+ @NotNull
@Override
public String getDisplayName() {
String name = myLibrary.getName();
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleScopeProviderImpl.java
index 052c73022d53..2e7c581f0976 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/ModuleScopeProviderImpl.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleScopeProviderImpl.java
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.openapi.module.impl;
+package com.intellij.openapi.module.impl.scopes;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope;
-import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope;
+import com.intellij.openapi.module.impl.ModuleScopeProvider;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -27,16 +27,15 @@ import org.jetbrains.annotations.NotNull;
*/
public class ModuleScopeProviderImpl implements ModuleScopeProvider {
private final Module myModule;
- private final StripedLockIntObjectConcurrentHashMap<GlobalSearchScope> myScopeCache = new StripedLockIntObjectConcurrentHashMap<GlobalSearchScope>();
- private GlobalSearchScope myModuleWithDependentsScope;
- private GlobalSearchScope myModuleTestsWithDependentsScope;
+ private final ConcurrentIntObjectMap<GlobalSearchScope> myScopeCache = new StripedLockIntObjectConcurrentHashMap<GlobalSearchScope>();
+ private ModuleWithDependentsTestScope myModuleTestsWithDependentsScope;
public ModuleScopeProviderImpl(@NotNull Module module) {
myModule = module;
}
@NotNull
- public GlobalSearchScope getCachedScope(@ModuleWithDependenciesScope.ScopeConstant int options) {
+ private GlobalSearchScope getCachedScope(@ModuleWithDependenciesScope.ScopeConstant int options) {
GlobalSearchScope scope = myScopeCache.get(options);
if (scope == null) {
scope = new ModuleWithDependenciesScope(myModule, options);
@@ -45,7 +44,6 @@ public class ModuleScopeProviderImpl implements ModuleScopeProvider {
return scope;
}
-
@Override
@NotNull
public GlobalSearchScope getModuleScope() {
@@ -93,19 +91,15 @@ public class ModuleScopeProviderImpl implements ModuleScopeProvider {
@Override
@NotNull
public GlobalSearchScope getModuleWithDependentsScope() {
- GlobalSearchScope scope = myModuleWithDependentsScope;
- if (scope == null) {
- myModuleWithDependentsScope = scope = new ModuleWithDependentsScope(myModule, false);
- }
- return scope;
+ return getModuleTestsWithDependentsScope().getBaseScope();
}
@Override
@NotNull
- public GlobalSearchScope getModuleTestsWithDependentsScope() {
- GlobalSearchScope scope = myModuleTestsWithDependentsScope;
+ public ModuleWithDependentsTestScope getModuleTestsWithDependentsScope() {
+ ModuleWithDependentsTestScope scope = myModuleTestsWithDependentsScope;
if (scope == null) {
- myModuleTestsWithDependentsScope = scope = new ModuleWithDependentsScope(myModule, true);
+ myModuleTestsWithDependentsScope = scope = new ModuleWithDependentsTestScope(myModule);
}
return scope;
}
@@ -120,8 +114,6 @@ public class ModuleScopeProviderImpl implements ModuleScopeProvider {
@Override
public void clearCache() {
myScopeCache.clear();
- myModuleWithDependentsScope = null;
myModuleTestsWithDependentsScope = null;
}
-
}
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
index 477a04f1d549..05b0ef34be7e 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
@@ -34,7 +34,6 @@ import org.jetbrains.annotations.TestOnly;
import java.util.*;
public class ModuleWithDependenciesScope extends GlobalSearchScope {
-
public static final int COMPILE = 0x01;
public static final int LIBRARIES = 0x02;
public static final int MODULES = 0x04;
@@ -59,10 +58,10 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope {
myModule = module;
myOptions = options;
- myProjectFileIndex = ProjectRootManager.getInstance(getProject()).getFileIndex();
+ myProjectFileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
OrderEnumerator en = ModuleRootManager.getInstance(module).orderEntries();
- /*if (myIncludeOtherModules) */en.recursively();
+ en.recursively();
if (hasOption(COMPILE)) {
en.exportedOnly().compileOnly();
@@ -117,6 +116,7 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope {
}
}
+ @NotNull
public Module getModule() {
return myModule;
}
@@ -125,6 +125,7 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope {
return (myOptions & option) != 0;
}
+ @NotNull
@Override
public String getDisplayName() {
return hasOption(COMPILE) ? PsiBundle.message("search.scope.module", myModule.getName())
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
index 367ebd2a4f05..0a575acdc550 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,82 +17,112 @@ package com.intellij.openapi.module.impl.scopes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.Queue;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* @author max
*/
-public class ModuleWithDependentsScope extends GlobalSearchScope {
+class ModuleWithDependentsScope extends GlobalSearchScope {
private final Module myModule;
- private final boolean myOnlyTests;
private final ProjectFileIndex myProjectFileIndex;
private final Set<Module> myModules;
private final GlobalSearchScope myProjectScope;
- public ModuleWithDependentsScope(Module module, boolean onlyTests) {
+ ModuleWithDependentsScope(@NotNull Module module) {
super(module.getProject());
myModule = module;
- myOnlyTests = onlyTests;
- myProjectFileIndex = ProjectRootManager.getInstance(myModule.getProject()).getFileIndex();
- myProjectScope = ProjectScope.getProjectScope(myModule.getProject());
+ myProjectFileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
+ myProjectScope = ProjectScope.getProjectScope(module.getProject());
myModules = new THashSet<Module>();
- myModules.add(myModule);
+ myModules.add(module);
fillModules();
}
private void fillModules() {
+ ModuleIndex index = getModuleIndex(myModule.getProject());
+
Queue<Module> walkingQueue = new Queue<Module>(10);
walkingQueue.addLast(myModule);
- Module[] allModules = ModuleManager.getInstance(myModule.getProject()).getModules();
- Set<Module> processed = new THashSet<Module>();
-
while (!walkingQueue.isEmpty()) {
Module current = walkingQueue.pullFirst();
- processed.add(current);
- for (Module dependent : allModules) {
- for (OrderEntry orderEntry : ModuleRootManager.getInstance(dependent).getOrderEntries()) {
- if (orderEntry instanceof ModuleOrderEntry && current.equals(((ModuleOrderEntry)orderEntry).getModule())) {
- myModules.add(dependent);
- if (!processed.contains(dependent) && ((ModuleOrderEntry)orderEntry).isExported()) {
- walkingQueue.addLast(dependent);
- }
- }
+ myModules.addAll(index.plainUsages.get(current));
+ for (Module dependent : index.exportingUsages.get(current)) {
+ if (myModules.add(dependent)) {
+ walkingQueue.addLast(dependent);
}
}
}
}
+ private static class ModuleIndex {
+ final MultiMap<Module, Module> plainUsages = MultiMap.create();
+ final MultiMap<Module, Module> exportingUsages = MultiMap.create();
+ }
+ private static ModuleIndex getModuleIndex(final Project project) {
+ return CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider<ModuleIndex>() {
+ @Nullable
+ @Override
+ public Result<ModuleIndex> compute() {
+ ModuleIndex index = new ModuleIndex();
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ for (OrderEntry orderEntry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+ if (orderEntry instanceof ModuleOrderEntry) {
+ Module referenced = ((ModuleOrderEntry)orderEntry).getModule();
+ if (referenced != null) {
+ MultiMap<Module, Module> map = ((ModuleOrderEntry)orderEntry).isExported() ? index.exportingUsages : index.plainUsages;
+ map.putValue(referenced, module);
+ }
+ }
+ }
+ }
+ return Result.create(index, ProjectRootManager.getInstance(project));
+ }
+ });
+ }
+
+ @Override
public boolean contains(@NotNull VirtualFile file) {
+ return contains(file, false);
+ }
+
+ boolean contains(@NotNull VirtualFile file, boolean myOnlyTests) {
Module moduleOfFile = myProjectFileIndex.getModuleForFile(file);
- if (moduleOfFile == null) return false;
- if (!myModules.contains(moduleOfFile)) return false;
+ if (moduleOfFile == null || !myModules.contains(moduleOfFile)) return false;
if (myOnlyTests && !myProjectFileIndex.isInTestSourceContent(file)) return false;
return myProjectScope.contains(file);
}
+ @Override
public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
return 0;
}
+ @Override
public boolean isSearchInModuleContent(@NotNull Module aModule) {
return myModules.contains(aModule);
}
+ @Override
public boolean isSearchInLibraries() {
return false;
}
@@ -108,10 +138,7 @@ public class ModuleWithDependentsScope extends GlobalSearchScope {
final ModuleWithDependentsScope moduleWithDependentsScope = (ModuleWithDependentsScope)o;
- if (myOnlyTests != moduleWithDependentsScope.myOnlyTests) return false;
- if (!myModule.equals(moduleWithDependentsScope.myModule)) return false;
-
- return true;
+ return myModule.equals(moduleWithDependentsScope.myModule);
}
public int hashCode() {
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsTestScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsTestScope.java
new file mode 100644
index 000000000000..f9ec689a40ab
--- /dev/null
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsTestScope.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.module.impl.scopes;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.search.DelegatingGlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+
+// Tests only (module plus dependencies) scope
+// Delegates to ModuleWithDependentsScope with extra flag testOnly to reduce memory for holding modules and CPU for traversing dependencies.
+class ModuleWithDependentsTestScope extends DelegatingGlobalSearchScope {
+ ModuleWithDependentsTestScope(@NotNull Module module) {
+ // the additional equality argument allows to distinguish ModuleWithDependentsTestScope from ModuleWithDependentsScope
+ super(new ModuleWithDependentsScope(module), true);
+ }
+
+ @Override
+ public boolean contains(@NotNull VirtualFile file) {
+ return getBaseScope().contains(file, true);
+ }
+
+ @NotNull
+ ModuleWithDependentsScope getBaseScope() {
+ return (ModuleWithDependentsScope)myBaseScope;
+ }
+}
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
index 5d301599395d..b5c3dd17afb7 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
@@ -104,7 +104,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@NotNull final Processor<PsiElement> processor) {
TextOccurenceProcessor occurrenceProcessor = new TextOccurenceProcessor() {
@Override
- public boolean execute(PsiElement element, int offsetInElement) {
+ public boolean execute(@NotNull PsiElement element, int offsetInElement) {
if (CommentUtilCore.isCommentTextElement(element)) {
if (element.findReferenceAt(offsetInElement) == null) {
return processor.process(element);
@@ -846,7 +846,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
final RequestResultProcessor wrapped = singleRequest.processor;
return new TextOccurenceProcessor() {
@Override
- public boolean execute(PsiElement element, int offsetInElement) {
+ public boolean execute(@NotNull PsiElement element, int offsetInElement) {
if (ignoreInjectedPsi && element instanceof PsiLanguageInjectionHost) return true;
return wrapped.processTextOccurrence(element, offsetInElement, consumer);
diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java b/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java
index 1e111b2d01de..d197b2819ffd 100644
--- a/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java
+++ b/platform/indexing-impl/src/com/intellij/util/indexing/SingleEntryFileBasedIndexExtension.java
@@ -43,7 +43,7 @@ public abstract class SingleEntryFileBasedIndexExtension<V> extends FileBasedInd
public abstract SingleEntryIndexer<V> getIndexer();
@Override
- public boolean isKeyHighlySelective() {
+ public boolean keyIsUniqueForIndexedFile() {
return true;
}
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
index 831e056e7efb..06edc72a06f8 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java
@@ -128,7 +128,8 @@ public abstract class CompletionContributor {
private final MultiMap<CompletionType, Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>> myMap =
new MultiMap<CompletionType, Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>>();
- public final void extend(@Nullable CompletionType type, final ElementPattern<? extends PsiElement> place, CompletionProvider<CompletionParameters> provider) {
+ public final void extend(@Nullable CompletionType type,
+ @NotNull final ElementPattern<? extends PsiElement> place, CompletionProvider<CompletionParameters> provider) {
myMap.putValue(type, new Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>(place, provider));
}
@@ -144,11 +145,8 @@ public abstract class CompletionContributor {
* is of your favourite kind. This method is run inside a read action. If you do any long activity non-related to PSI in it, please
* ensure you call {@link com.intellij.openapi.progress.ProgressManager#checkCanceled()} often enough so that the completion process
* can be cancelled smoothly when the user begins to type in the editor.
- *
- * @param parameters
- * @param result
*/
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>> pair : myMap.get(parameters.getCompletionType())) {
final ProcessingContext context = new ProcessingContext();
if (pair.first.accepts(parameters.getPosition(), context)) {
@@ -171,7 +169,6 @@ public abstract class CompletionContributor {
/**
* Invoked before completion is started. Is used mainly for determining custom offsets in editor, and to change default dummy identifier.
- * @param context
*/
public void beforeCompletion(@NotNull CompletionInitializationContext context) {
}
@@ -188,8 +185,6 @@ public abstract class CompletionContributor {
/**
*
- * @param parameters
- * @param editor
* @return hint text to be shown if no variants are found, typically "No suggestions"
*/
@Nullable
@@ -201,7 +196,7 @@ public abstract class CompletionContributor {
* Called when the completion is finished quickly, lookup hasn't been shown and gives possibility to autoinsert some item (typically - the only one).
*/
@Nullable
- public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
+ public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
return null;
}
@@ -226,15 +221,16 @@ public abstract class CompletionContributor {
}
/**
- * @param actionId
* @return String representation of action shortcut. Useful while advertising something
* @see #advertise(CompletionParameters)
*/
- protected static String getActionShortcut(@NonNls final String actionId) {
+ @NotNull
+ protected static String getActionShortcut(@NonNls @NotNull final String actionId) {
return KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(actionId));
}
- public static List<CompletionContributor> forParameters(final CompletionParameters parameters) {
+ @NotNull
+ public static List<CompletionContributor> forParameters(@NotNull final CompletionParameters parameters) {
return ApplicationManager.getApplication().runReadAction(new Computable<List<CompletionContributor>>() {
@Override
public List<CompletionContributor> compute() {
@@ -243,6 +239,7 @@ public abstract class CompletionContributor {
});
}
+ @NotNull
public static List<CompletionContributor> forLanguage(@NotNull Language language) {
return MyExtensionPointManager.INSTANCE.forKey(language);
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
index 7cf2c7d7db11..624d60fd8688 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -40,13 +41,15 @@ public class CompletionInitializationContext {
private final Editor myEditor;
private final PsiFile myFile;
private final CompletionType myCompletionType;
+ private final int myInvocationCount;
private final OffsetMap myOffsetMap;
private String myDummyIdentifier = DUMMY_IDENTIFIER;
- public CompletionInitializationContext(final Editor editor, final PsiFile file, final CompletionType completionType) {
+ public CompletionInitializationContext(final Editor editor, final PsiFile file, final CompletionType completionType, int invocationCount) {
myEditor = editor;
myFile = file;
myCompletionType = completionType;
+ myInvocationCount = invocationCount;
myOffsetMap = new OffsetMap(editor.getDocument());
myOffsetMap.addOffset(START_OFFSET, calcStartOffset(editor));
@@ -79,7 +82,7 @@ public class CompletionInitializationContext {
@NotNull
public Language getPositionLanguage() {
- return PsiUtilBase.getLanguageInEditor(getEditor(), getProject());
+ return ObjectUtils.assertNotNull(PsiUtilBase.getLanguageInEditor(getEditor(), getProject()));
}
public String getDummyIdentifier() {
@@ -127,9 +130,12 @@ public class CompletionInitializationContext {
return getIdentifierEndOffset();
}
+ public int getInvocationCount() {
+ return myInvocationCount;
+ }
+
/**
* Mark the offset up to which the text will be deleted if a completion variant is selected using Replace character (Tab)
- * @param idEnd
*/
public void setReplacementOffset(int idEnd) {
myOffsetMap.addOffset(IDENTIFIER_END_OFFSET, idEnd);
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java
index dcc1f8562bd2..a400b201ba34 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.completion;
-import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,12 +28,12 @@ public final class CompletionParameters {
private final PsiElement myPosition;
private final PsiFile myOriginalFile;
private final CompletionType myCompletionType;
- private final Lookup myLookup;
+ private final Editor myEditor;
private final int myOffset;
private final int myInvocationCount;
CompletionParameters(@NotNull final PsiElement position, @NotNull final PsiFile originalFile,
- final CompletionType completionType, int offset, final int invocationCount, Lookup lookup) {
+ final CompletionType completionType, int offset, final int invocationCount, @NotNull Editor editor) {
assert offset >= position.getTextRange().getStartOffset();
myPosition = position;
assert position.isValid();
@@ -42,7 +41,7 @@ public final class CompletionParameters {
myCompletionType = completionType;
myOffset = offset;
myInvocationCount = invocationCount;
- myLookup = lookup;
+ myEditor = editor;
}
public CompletionParameters delegateToClassName() {
@@ -50,11 +49,11 @@ public final class CompletionParameters {
}
public CompletionParameters withType(CompletionType type) {
- return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myLookup);
+ return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myEditor);
}
public CompletionParameters withInvocationCount(int newCount) {
- return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myLookup);
+ return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myEditor);
}
@NotNull
@@ -62,11 +61,6 @@ public final class CompletionParameters {
return myPosition;
}
- @NotNull
- public Lookup getLookup() {
- return myLookup;
- }
-
@Nullable
public PsiElement getOriginalPosition() {
return myOriginalFile.findElementAt(myPosition.getTextRange().getStartOffset());
@@ -101,7 +95,7 @@ public final class CompletionParameters {
}
public CompletionParameters withPosition(PsiElement element, int offset) {
- return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myLookup);
+ return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myEditor);
}
public boolean isExtendedCompletion() {
@@ -109,6 +103,6 @@ public final class CompletionParameters {
}
public Editor getEditor() {
- return myLookup.getEditor();
+ return myEditor;
}
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
index 9b980c50198c..189e6581d171 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -210,9 +210,14 @@ public final class LookupElementBuilder extends LookupElement {
public LookupElementBuilder setTypeText(@Nullable String typeText, boolean grayed) {
return withTypeText(typeText, grayed);
}
+
public LookupElementBuilder withTypeText(@Nullable String typeText, boolean grayed) {
+ return withTypeText(typeText, null, grayed);
+ }
+
+ public LookupElementBuilder withTypeText(@Nullable String typeText, @Nullable Icon typeIcon, boolean grayed) {
final LookupElementPresentation presentation = copyPresentation();
- presentation.setTypeText(typeText);
+ presentation.setTypeText(typeText, typeIcon);
presentation.setTypeGrayed(grayed);
return new LookupElementBuilder(myLookupString, myObject, myInsertHandler, null, presentation,
myAllLookupStrings, myCaseSensitive);
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
index 30c97a8c804a..328c3dd8fcf1 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
@@ -50,6 +50,13 @@ public abstract class LookupElementWeigher {
}
@Nullable
- public abstract Comparable weigh(@NotNull LookupElement element);
+ public Comparable weigh(@NotNull LookupElement element, @NotNull WeighingContext context) {
+ return weigh(element);
+ }
+
+ @Nullable
+ public Comparable weigh(@NotNull LookupElement element) {
+ throw new UnsupportedOperationException("weigh not implemented in " + getClass());
+ }
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/WeighingContext.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/WeighingContext.java
new file mode 100644
index 000000000000..b005eae75ec3
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/WeighingContext.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.lookup;
+
+import com.intellij.codeInsight.completion.PrefixMatcher;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public interface WeighingContext {
+ @NotNull
+ String itemPattern(@NotNull LookupElement element);
+
+ @NotNull
+ PrefixMatcher itemMatcher(@NotNull LookupElement item);
+
+}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java b/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
index 87d8b4a89240..21c7deabff9f 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
+++ b/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
@@ -21,35 +21,21 @@
package com.intellij.execution.configuration;
import com.intellij.execution.ExecutionBundle;
-import com.intellij.execution.util.EnvVariablesTable;
-import com.intellij.execution.util.EnvironmentVariable;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.UserActivityProviderComponent;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.StringBuilderSpinAllocator;
-import com.intellij.util.containers.ContainerUtil;
-import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.io.File;
-import java.util.*;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWithBrowseButton> implements UserActivityProviderComponent {
- private boolean myPassParentEnvs;
- private final Map<String, String> myEnvs = new THashMap<String, String>();
@NonNls private static final String ENVS = "envs";
@NonNls public static final String ENV = "env";
@NonNls public static final String NAME = "name";
@@ -57,52 +43,30 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
@NonNls private static final String OPTION = "option";
@NonNls private static final String ENV_VARIABLES = "ENV_VARIABLES";
- private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final EnvironmentVariablesTextFieldWithBrowseButton myEnvVars;
public EnvironmentVariablesComponent() {
super();
- final TextFieldWithBrowseButton envsTestField = new TextFieldWithBrowseButton();
- envsTestField.setEditable(false);
- setComponent(envsTestField);
+ myEnvVars = new EnvironmentVariablesTextFieldWithBrowseButton();
+ setComponent(myEnvVars);
setText(ExecutionBundle.message("environment.variables.component.title"));
- getComponent().addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- new MyEnvironmentVariablesDialog().show();
- }
- });
}
public void setEnvs(@NotNull Map<String, String> envs) {
- myEnvs.clear();
- myEnvs.putAll(envs);
- @NonNls final StringBuilder buf = StringBuilderSpinAllocator.alloc();
- try {
- for (String variable : myEnvs.keySet()) {
- buf.append(variable).append("=").append(myEnvs.get(variable)).append(";");
- }
- if (buf.length() > 0) buf.deleteCharAt(buf.length() - 1); //trim last ;
- getComponent().setText(buf.toString());
- }
- finally {
- StringBuilderSpinAllocator.dispose(buf);
- }
+ myEnvVars.setEnvs(envs);
}
@NotNull
public Map<String, String> getEnvs() {
- return myEnvs;
+ return myEnvVars.getEnvs();
}
public boolean isPassParentEnvs() {
- return myPassParentEnvs;
+ return myEnvVars.isPassParentEnvs();
}
- public void setPassParentEnvs(final boolean passDefaultVariables) {
- if (myPassParentEnvs != passDefaultVariables) {
- myPassParentEnvs = passDefaultVariables;
- fireStateChanged();
- }
+ public void setPassParentEnvs(final boolean passParentEnvs) {
+ myEnvVars.setPassParentEnvs(passParentEnvs);
}
public static void readExternal(Element element, Map<String, String> envs) {
@@ -129,12 +93,10 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
private static void splitVars(final Map<String, String> envs, final String val) {
if (val != null) {
final String[] envVars = val.split(";");
- if (envVars != null) {
- for (String envVar : envVars) {
- final int idx = envVar.indexOf('=');
- if (idx > -1) {
- envs.put(envVar.substring(0, idx), idx < envVar.length() - 1 ? envVar.substring(idx + 1) : "");
- }
+ for (String envVar : envVars) {
+ final int idx = envVar.indexOf('=');
+ if (idx > -1) {
+ envs.put(envVar.substring(0, idx), idx < envVar.length() - 1 ? envVar.substring(idx + 1) : "");
}
}
}
@@ -170,56 +132,11 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
@Override
public void addChangeListener(final ChangeListener changeListener) {
- myListeners.add(changeListener);
+ myEnvVars.addChangeListener(changeListener);
}
@Override
public void removeChangeListener(final ChangeListener changeListener) {
- myListeners.remove(changeListener);
- }
-
- private void fireStateChanged() {
- for (ChangeListener listener : myListeners) {
- listener.stateChanged(new ChangeEvent(this));
- }
- }
-
- private class MyEnvironmentVariablesDialog extends DialogWrapper {
- private final EnvVariablesTable myEnvVariablesTable;
- private final JCheckBox myUseDefaultCb = new JCheckBox(ExecutionBundle.message("env.vars.checkbox.title"));
- private final JPanel myWholePanel = new JPanel(new BorderLayout());
-
- protected MyEnvironmentVariablesDialog() {
- super(EnvironmentVariablesComponent.this, true);
- myEnvVariablesTable = new EnvVariablesTable();
- final List<EnvironmentVariable> envVariables = new ArrayList<EnvironmentVariable>();
- for (String envVariable : myEnvs.keySet()) {
- envVariables.add(new EnvironmentVariable(envVariable, myEnvs.get(envVariable), false));
- }
- myEnvVariablesTable.setValues(envVariables);
- myUseDefaultCb.setSelected(isPassParentEnvs());
- myWholePanel.add(myEnvVariablesTable.getComponent(), BorderLayout.CENTER);
- myWholePanel.add(myUseDefaultCb, BorderLayout.SOUTH);
- setTitle(ExecutionBundle.message("environment.variables.dialog.title"));
- init();
- }
-
- @Override
- @Nullable
- protected JComponent createCenterPanel() {
- return myWholePanel;
- }
-
- @Override
- protected void doOKAction() {
- myEnvVariablesTable.stopEditing();
- final Map<String, String> envs = new LinkedHashMap<String, String>();
- for (EnvironmentVariable variable : myEnvVariablesTable.getEnvironmentVariables()) {
- envs.put(variable.getName(), variable.getValue());
- }
- setEnvs(envs);
- setPassParentEnvs(myUseDefaultCb.isSelected());
- super.doOKAction();
- }
+ myEnvVars.removeChangeListener(changeListener);
}
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java b/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
new file mode 100644
index 000000000000..0fe445371186
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.configuration;
+
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.execution.util.EnvVariablesTable;
+import com.intellij.execution.util.EnvironmentVariable;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.*;
+import java.util.List;
+
+public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton {
+
+ private final Map<String, String> myEnvs = new THashMap<String, String>();
+ private boolean myPassParentEnvs;
+ private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+
+ public EnvironmentVariablesTextFieldWithBrowseButton() {
+ super();
+ setEditable(false);
+ addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ new MyEnvironmentVariablesDialog().show();
+ }
+ });
+ }
+
+ @NotNull
+ public Map<String, String> getEnvs() {
+ return myEnvs;
+ }
+
+ public void setEnvs(@NotNull Map<String, String> envs) {
+ myEnvs.clear();
+ myEnvs.putAll(envs);
+ String envsStr = stringifyEnvs(myEnvs);
+ setText(envsStr);
+ }
+
+ @NotNull
+ private static String stringifyEnvs(@NotNull Map<String, String> envs) {
+ if (envs.isEmpty()) {
+ return "";
+ }
+ StringBuilder buf = new StringBuilder();
+ for (Map.Entry<String, String> entry : envs.entrySet()) {
+ if (buf.length() > 0) {
+ buf.append(";");
+ }
+ buf.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+ return buf.toString();
+ }
+
+ public boolean isPassParentEnvs() {
+ return myPassParentEnvs;
+ }
+
+ public void setPassParentEnvs(boolean passParentEnvs) {
+ if (myPassParentEnvs != passParentEnvs) {
+ myPassParentEnvs = passParentEnvs;
+ fireStateChanged();
+ }
+ }
+
+ public void addChangeListener(ChangeListener changeListener) {
+ myListeners.add(changeListener);
+ }
+
+ public void removeChangeListener(ChangeListener changeListener) {
+ myListeners.remove(changeListener);
+ }
+
+ private void fireStateChanged() {
+ for (ChangeListener listener : myListeners) {
+ listener.stateChanged(new ChangeEvent(this));
+ }
+ }
+
+ private class MyEnvironmentVariablesDialog extends DialogWrapper {
+ private final EnvVariablesTable myEnvVariablesTable;
+ private final JCheckBox myUseDefaultCb = new JCheckBox(ExecutionBundle.message("env.vars.checkbox.title"));
+ private final JPanel myWholePanel = new JPanel(new BorderLayout());
+
+ protected MyEnvironmentVariablesDialog() {
+ super(EnvironmentVariablesTextFieldWithBrowseButton.this, true);
+ myEnvVariablesTable = new EnvVariablesTable();
+ List<EnvironmentVariable> envVariables = ContainerUtil.newArrayList();
+ for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
+ envVariables.add(new EnvironmentVariable(entry.getKey(), entry.getValue(), false));
+ }
+ myEnvVariablesTable.setValues(envVariables);
+ myUseDefaultCb.setSelected(isPassParentEnvs());
+ myWholePanel.add(myEnvVariablesTable.getComponent(), BorderLayout.CENTER);
+ myWholePanel.add(myUseDefaultCb, BorderLayout.SOUTH);
+ setTitle(ExecutionBundle.message("environment.variables.dialog.title"));
+ init();
+ }
+
+ @Override
+ @Nullable
+ protected JComponent createCenterPanel() {
+ return myWholePanel;
+ }
+
+ @Override
+ protected void doOKAction() {
+ myEnvVariablesTable.stopEditing();
+ final Map<String, String> envs = new LinkedHashMap<String, String>();
+ for (EnvironmentVariable variable : myEnvVariablesTable.getEnvironmentVariables()) {
+ envs.put(variable.getName(), variable.getValue());
+ }
+ setEnvs(envs);
+ setPassParentEnvs(myUseDefaultCb.isSelected());
+ super.doOKAction();
+ }
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/facet/ProjectFacetManager.java b/platform/lang-api/src/com/intellij/facet/ProjectFacetManager.java
index 9faca51af444..1cbc548d0f22 100644
--- a/platform/lang-api/src/com/intellij/facet/ProjectFacetManager.java
+++ b/platform/lang-api/src/com/intellij/facet/ProjectFacetManager.java
@@ -39,6 +39,9 @@ public abstract class ProjectFacetManager {
@NotNull
public abstract <F extends Facet> List<F> getFacets(@NotNull FacetTypeId<F> typeId);
+ @NotNull
+ public abstract List<Module> getModulesWithFacet(@NotNull FacetTypeId<?> typeId);
+
public abstract <C extends FacetConfiguration> C createDefaultConfiguration(@NotNull FacetType<?, C> facetType);
public abstract <C extends FacetConfiguration> void setDefaultConfiguration(@NotNull FacetType<?, C> facetType, @NotNull C configuration);
diff --git a/platform/lang-api/src/com/intellij/find/FindManager.java b/platform/lang-api/src/com/intellij/find/FindManager.java
index 102872655dca..56339d116e14 100644
--- a/platform/lang-api/src/com/intellij/find/FindManager.java
+++ b/platform/lang-api/src/com/intellij/find/FindManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.SearchScope;
import com.intellij.util.messages.Topic;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
@@ -217,6 +218,7 @@ public abstract class FindManager {
* @param element the element to find the usages for.
*/
public abstract void findUsages(@NotNull PsiElement element);
+ public abstract void findUsagesInScope(@NotNull PsiElement element, @NotNull SearchScope searchScope);
/**
* Shows the Find Usages dialog (if {@code showDialog} is true} and performs the Find Usages operation for the
diff --git a/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java b/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java
index a7f7f326cdaf..bf56114a2467 100644
--- a/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java
+++ b/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,9 +19,14 @@
*/
package com.intellij.openapi.module;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.ParameterizedCachedValue;
@@ -103,4 +108,33 @@ public class ModuleUtil extends ModuleUtilCore {
String type = module.getOptionValue(Module.ELEMENT_TYPE);
return ModuleTypeManager.getInstance().findByID(type);
}
+
+ public static void updateExcludedFoldersInWriteAction(final Module module,
+ @NotNull final VirtualFile contentRoot,
+ final Collection<String> urlsToUnExclude,
+ final Collection<String> urlsToExclude) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel();
+ try {
+ for (final ContentEntry contentEntry : modifiableModel.getContentEntries()) {
+ if (contentRoot.equals(contentEntry.getFile())) {
+ for (String url : urlsToUnExclude) {
+ contentEntry.removeExcludeFolder(url);
+ }
+ for (String url : urlsToExclude) {
+ contentEntry.addExcludeFolder(url);
+ }
+ break;
+ }
+ }
+ modifiableModel.commit();
+ }
+ catch (Exception e) {
+ modifiableModel.dispose();
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+ });
+ }
}
diff --git a/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java b/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java
index 62a2b91d3777..85e7c3701e0d 100644
--- a/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java
+++ b/platform/lang-api/src/com/intellij/openapi/project/ProjectUtil.java
@@ -34,7 +34,8 @@ import javax.swing.*;
* @author max
*/
public class ProjectUtil {
- private ProjectUtil() { }
+ private ProjectUtil() {
+ }
@Nullable
public static String getProjectLocationString(@NotNull final Project project) {
@@ -83,9 +84,16 @@ public class ProjectUtil {
}
@Nullable
- // guessProjectForFile works incorrectly - even if file is config (idea config file) first opened project will be returned
public static Project guessProjectForContentFile(@NotNull VirtualFile file) {
- if (isProjectOrWorkspaceFile(file)) {
+ return guessProjectForContentFile(file, file.getFileType());
+ }
+
+ @Nullable
+ /***
+ * guessProjectForFile works incorrectly - even if file is config (idea config file) first opened project will be returned
+ */
+ public static Project guessProjectForContentFile(@NotNull VirtualFile file, @NotNull FileType fileType) {
+ if (isProjectOrWorkspaceFile(file, fileType)) {
return null;
}
@@ -102,10 +110,8 @@ public class ProjectUtil {
return isProjectOrWorkspaceFile(file, file.getFileType());
}
- public static boolean isProjectOrWorkspaceFile(final VirtualFile file,
- final FileType fileType) {
- if (fileType instanceof InternalFileType) return true;
- return file.getPath().contains("/"+ Project.DIRECTORY_STORE_FOLDER +"/");
+ public static boolean isProjectOrWorkspaceFile(@NotNull VirtualFile file, @NotNull FileType fileType) {
+ return fileType instanceof InternalFileType || file.getPath().contains('/' + ProjectCoreUtil.DIRECTORY_BASED_PROJECT_DIR + '/');
}
@NotNull
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
index f75fbc679afb..4291e9b401bf 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/JdkUtil.java
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
import java.util.jar.Attributes;
@@ -282,6 +283,8 @@ public class JdkUtil {
}
catch (UnsupportedCharsetException ignore) {
}
+ catch (IllegalCharsetNameException ignore) {
+ }
}
}
diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
index 33f1cced24bf..ecebb9db73f3 100644
--- a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
+++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java
@@ -175,7 +175,7 @@ public class PathEditor {
requestDefaultFocus();
}
- private VirtualFile[] doAdd() {
+ protected VirtualFile[] doAdd() {
VirtualFile baseDir = myAddBaseDir;
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myPanel));
if (baseDir == null && project != null) {
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
index ee36676ec5fc..021c055dd70f 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * User: anna
- * Date: 26-Dec-2007
- */
package com.intellij.openapi.roots.ui;
import com.intellij.openapi.application.ApplicationManager;
@@ -31,16 +26,20 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+/**
+ * @author anna
+ * @since 26-Dec-2007
+ */
public interface OrderRootTypeUIFactory {
ExtensionPointName<KeyedFactoryEPBean> EP_NAME = ExtensionPointName.create("com.intellij.OrderRootTypeUI");
- KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, EP_NAME,
- ApplicationManager
- .getApplication().getPicoContainer()) {
- @Override
- public String getKey(@NotNull final OrderRootType key) {
- return key.name();
- }
- };
+
+ KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY =
+ new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, EP_NAME, ApplicationManager.getApplication().getPicoContainer()) {
+ @Override
+ public String getKey(@NotNull final OrderRootType key) {
+ return key.name();
+ }
+ };
SdkPathEditor createPathEditor(Sdk sdk);
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
index f3ed4620c3fa..3eb09544bb7f 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
@@ -575,7 +575,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
for (final CustomCodeStyleSettings settings : customSettings) {
final CustomCodeStyleSettings parentCustomSettings = parentSettings.getCustomSettings(settings.getClass());
- assert parentCustomSettings != null;
+ assert parentCustomSettings != null : "Custom settings are null for " + settings.getClass();
settings.writeExternal(element, parentCustomSettings);
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
index 71d1ddc3ac4c..3b97016645c2 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,12 +21,10 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
-import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
@@ -225,6 +223,10 @@ public abstract class LanguageCodeStyleSettingsProvider {
return fieldCollector.getCollectedFields();
}
+ public boolean isIndentBasedLanguageSemantics() {
+ return false;
+ }
+
private final class SupportedFieldCollector implements CodeStyleSettingsCustomizable {
private final Set<String> myCollectedFields = new HashSet<String>();
private SettingsType myCurrSettingsType;
diff --git a/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java b/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java
index 442e9d117806..e9e72103f612 100644
--- a/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java
+++ b/platform/lang-api/src/com/intellij/usageView/UsageTreeColorsScheme.java
@@ -19,25 +19,21 @@ import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.EditorColorsUtil;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.ui.ColorUtil;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import java.awt.*;
-
-public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable{
+public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable {
private EditorColorsScheme myColorsScheme;
- private final EditorColorsManager myEditorColorsManager;
- @Deprecated
- @NonNls public static final String DEFAULT_SCHEME_NAME = EditorColorsManager.DEFAULT_SCHEME_NAME; // it is API, let's do not break it and do not inline constant
+ /**
+ * @noinspection UnusedParameters
+ */
public UsageTreeColorsScheme(EditorColorsManager editorColorsManager) {
- myEditorColorsManager = editorColorsManager;
}
public static UsageTreeColorsScheme getInstance() {
@@ -56,14 +52,9 @@ public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable
@Override
public void readExternal(Element element) throws InvalidDataException {
- if (myColorsScheme == null){
- Color color = UIUtil.getTreeTextBackground();
- if (color != null && ColorUtil.isDark(color)) {
- myColorsScheme = (EditorColorsScheme)myEditorColorsManager.getGlobalScheme().clone();
- }
- else {
- myColorsScheme = (EditorColorsScheme)myEditorColorsManager.getScheme(EditorColorsManager.DEFAULT_SCHEME_NAME).clone();
- }
+ if (myColorsScheme == null) {
+ EditorColorsScheme scheme = EditorColorsUtil.getColorSchemeForBackground(UIUtil.getTreeTextBackground());
+ myColorsScheme = (EditorColorsScheme)scheme.clone();
}
myColorsScheme.readExternal(element);
}
diff --git a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java
index aaebe0d7892c..c63f8cdc2fd7 100644
--- a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java
+++ b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java
@@ -17,7 +17,6 @@
package com.intellij.analysis;
import com.intellij.ide.highlighter.ArchiveFileType;
-import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -29,9 +28,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.JarFileSystem;
-import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -177,11 +174,7 @@ public abstract class BaseAnalysisAction extends AnAction {
Set<VirtualFile> files = new HashSet<VirtualFile>();
for (VirtualFile vFile : virtualFiles) {
if (fileIndex.isInContent(vFile)) {
- if (vFile instanceof VirtualFileWindow) {
- files.add(vFile);
- vFile = ((VirtualFileWindow)vFile).getDelegate();
- }
- collectFilesUnder(vFile, files);
+ files.add(vFile);
}
}
return new AnalysisScope(project, files);
@@ -208,15 +201,4 @@ public abstract class BaseAnalysisAction extends AnAction {
return null;
}
- private static void collectFilesUnder(@NotNull VirtualFile vFile, @NotNull final Set<VirtualFile> files) {
- VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor() {
- @Override
- public boolean visitFile(@NotNull VirtualFile file) {
- if (!file.isDirectory()) {
- files.add(file);
- }
- return true;
- }
- });
- }
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
index c96f5e785901..d51ddbd827d5 100644
--- a/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/GeneralCodeStylePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -130,14 +130,14 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
IdeBorderFactory.createTitledBorder(ApplicationBundle.message("settings.code.style.general.formatter.marker.options.title"), true));
myScrollPane = new JBScrollPane(myPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ myScrollPane.setBorder(IdeBorderFactory.createEmptyBorder());
}
@Nullable
private static Language getLanguage(FileType fileType) {
- return (fileType instanceof LanguageFileType) ? ((LanguageFileType)fileType).getLanguage() : null;
+ return fileType instanceof LanguageFileType ? ((LanguageFileType)fileType).getLanguage() : null;
}
-
@Override
protected void somethingChanged() {
super.somethingChanged();
diff --git a/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java b/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java
new file mode 100644
index 000000000000..17434cb0c7ba
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/ModulesComboBox.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.ui.ComboboxSpeedSearch;
+import com.intellij.ui.SortedComboBoxModel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ModulesComboBox extends ComboBox {
+ private final SortedComboBoxModel<Module> myModel;
+
+ public ModulesComboBox() {
+ this(new SortedComboBoxModel<Module>(ModulesAlphaComparator.INSTANCE));
+ }
+
+ private ModulesComboBox(final SortedComboBoxModel<Module> model) {
+ super(model);
+ myModel = model;
+ new ComboboxSpeedSearch(this){
+ @Override
+ protected String getElementText(Object element) {
+ if (element instanceof Module) {
+ return ((Module)element).getName();
+ } else if (element == null) {
+ return "";
+ }
+ return super.getElementText(element);
+ }
+ };
+ setRenderer(new ModuleListCellRenderer());
+ }
+
+ public void setModules(@NotNull Collection<Module> modules) {
+ myModel.setAll(modules);
+ }
+
+ public void fillModules(@NotNull Project project) {
+ fillModules(project, null);
+ }
+
+ public void fillModules(@NotNull Project project, final @Nullable ModuleType moduleType) {
+ Module[] allModules = ModuleManager.getInstance(project).getModules();
+ if (moduleType == null) {
+ setModules(Arrays.asList(allModules));
+ }
+ else {
+ List<Module> modules = new ArrayList<Module>();
+ for (Module module : allModules) {
+ if (moduleType.equals(ModuleType.get(module))) {
+ modules.add(module);
+ }
+ }
+ setModules(modules);
+ }
+ }
+
+ public void setSelectedModule(@Nullable Module module) {
+ myModel.setSelectedItem(module);
+ }
+
+ @Nullable
+ public Module getSelectedModule() {
+ return myModel.getSelectedItem();
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java b/platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java
index 2a751603afa3..e578dcc87765 100644
--- a/platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java
+++ b/platform/lang-impl/src/com/intellij/application/options/colors/ScopeColorsPageFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,12 +20,11 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.util.scopeChooser.EditScopesDialog;
import com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -33,8 +32,9 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
+ @NotNull
@Override
- public NewColorAndFontPanel createPanel(ColorAndFontOptions options) {
+ public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
final JPanel scopePanel = createChooseScopePanel();
return NewColorAndFontPanel.create(new PreviewPanel.Empty(){
@Override
@@ -45,6 +45,7 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
}, ColorAndFontOptions.SCOPES_GROUP, options, null, null);
}
+ @NotNull
@Override
public String getPanelDisplayName() {
return ColorAndFontOptions.SCOPES_GROUP;
@@ -60,7 +61,7 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
final Project contextProject = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
final Project project = contextProject != null ? contextProject : projects[0];
- JButton button = new JButton(ApplicationBundle.message("button.edit.scopes"));
+ JButton button = new JButton("Manage Scopes...");
button.setPreferredSize(new Dimension(230, button.getPreferredSize().height));
panel.add(button, gc);
gc.gridx = GridBagConstraints.REMAINDER;
@@ -73,7 +74,7 @@ class ScopeColorsPageFactory implements ColorAndFontPanelFactory {
panel.add(new JPanel(), gc);
button.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext());
if (optionsEditor != null) {
try {
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
index 3e5c8a0f1d88..586f9b48779e 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
@@ -417,7 +417,7 @@
</component>
</children>
</grid>
- <grid id="70a4f" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="70a4f" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -444,6 +444,14 @@
<text resource-bundle="messages/ApplicationBundle" key="checkbox.rename.local.variables.preselect"/>
</properties>
</component>
+ <component id="b2798" class="javax.swing.JCheckBox" binding="myShowInlineDialogForCheckBox" default-binding="true">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Show inline dialog for local variables"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="62a96" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java
index 9e5d8558b4d1..3646e2632273 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java
@@ -97,6 +97,7 @@ public class EditorOptionsPanel {
private JBLabel myQuickDocDelayLabel;
private JTextField myQuickDocDelayTextField;
private JComboBox myRichCopyColorSchemeComboBox;
+ private JCheckBox myShowInlineDialogForCheckBox;
private static final String ACTIVE_COLOR_SCHEME = ApplicationBundle.message("combobox.richcopy.color.scheme.active");
@@ -206,6 +207,7 @@ public class EditorOptionsPanel {
myCbRenameLocalVariablesInplace.setSelected(editorSettings.isVariableInplaceRenameEnabled());
myPreselectCheckBox.setSelected(editorSettings.isPreselectRename());
+ myShowInlineDialogForCheckBox.setSelected(editorSettings.isShowInlineLocalDialog());
myShowReformatCodeDialogCheckBox.setSelected(editorSettings.getOptions().SHOW_REFORMAT_DIALOG);
myShowOptimizeImportsDialogCheckBox.setSelected(editorSettings.getOptions().SHOW_OPIMIZE_IMPORTS_DIALOG);
@@ -301,6 +303,7 @@ public class EditorOptionsPanel {
editorSettings.setVariableInplaceRenameEnabled(myCbRenameLocalVariablesInplace.isSelected());
editorSettings.setPreselectRename(myPreselectCheckBox.isSelected());
+ editorSettings.setShowInlineLocalDialog(myShowInlineDialogForCheckBox.isSelected());
editorSettings.getOptions().SHOW_REFORMAT_DIALOG = myShowReformatCodeDialogCheckBox.isSelected();
editorSettings.getOptions().SHOW_OPIMIZE_IMPORTS_DIALOG = myShowOptimizeImportsDialogCheckBox.isSelected();
@@ -442,6 +445,7 @@ public class EditorOptionsPanel {
isModified |= isModified(myCommandsHistoryLimitField, UISettings.getInstance().CONSOLE_COMMAND_HISTORY_LIMIT);
isModified |= isModified(myCbRenameLocalVariablesInplace, editorSettings.isVariableInplaceRenameEnabled());
isModified |= isModified(myPreselectCheckBox, editorSettings.isPreselectRename());
+ isModified |= isModified(myShowInlineDialogForCheckBox, editorSettings.isShowInlineLocalDialog());
isModified |= isModified(myShowReformatCodeDialogCheckBox, editorSettings.getOptions().SHOW_REFORMAT_DIALOG);
isModified |= isModified(myShowOptimizeImportsDialogCheckBox, editorSettings.getOptions().SHOW_OPIMIZE_IMPORTS_DIALOG);
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form
index 9c73a83ed92a..f9cb5da0f632 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.editor.EditorSmartKeysConfigurable">
- <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="11" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="0">
+ <grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="12" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="0">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -10,7 +10,7 @@
<children>
<vspacer id="a9cd">
<constraints>
- <grid row="10" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="11" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="18e81" class="javax.swing.JCheckBox" binding="myCbSmartHome">
@@ -33,7 +33,7 @@
</component>
<component id="67fc" class="javax.swing.JCheckBox" binding="myCbInsertPairBracket">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
@@ -42,7 +42,7 @@
</component>
<component id="7263c" class="javax.swing.JCheckBox" binding="myCbInsertPairQuote">
<constraints>
- <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
@@ -51,7 +51,7 @@
</component>
<component id="278d0" class="javax.swing.JCheckBox" binding="myCbCamelWords">
<constraints>
- <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="checkbox.use.camelhumps.words"/>
@@ -60,7 +60,7 @@
<grid id="6ebf" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="5" right="5"/>
<constraints>
- <grid row="8" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="1" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="9" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="1" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -88,7 +88,7 @@
</grid>
<grid id="b08a8" binding="myAddonPanel" layout-manager="GridBagLayout">
<constraints>
- <grid row="9" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="10" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -97,7 +97,7 @@
<grid id="5344e" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
@@ -135,24 +135,33 @@
</grid>
<hspacer id="6cc57">
<constraints>
- <grid row="7" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="8" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
+ <component id="a64de" class="javax.swing.JCheckBox" binding="myCbReformatBlockOnTypingRBrace">
+ <constraints>
+ <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <selected value="true"/>
+ <text resource-bundle="messages/ApplicationBundle" key="checkbox.reformat.on.typing.rbrace"/>
+ </properties>
+ </component>
<component id="158ea" class="javax.swing.JCheckBox" binding="myCbSurroundSelectionOnTyping" default-binding="true">
<constraints>
- <grid row="6" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="7" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Surround selection on typing quote or brace"/>
</properties>
</component>
- <component id="a64de" class="javax.swing.JCheckBox" binding="myCbReformatBlockOnTypingRBrace">
+ <component id="87366" class="javax.swing.JCheckBox" binding="myCbIndentingBackspace">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
- <text resource-bundle="messages/ApplicationBundle" key="checkbox.reformat.on.typing.rbrace"/>
+ <text resource-bundle="messages/ApplicationBundle" key="checkbox.indenting.backspace"/>
</properties>
</component>
</children>
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.java
index daada36ed175..2cabcabf74ad 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -63,6 +63,7 @@ public class EditorSmartKeysConfigurable extends CompositeConfigurable<UnnamedCo
private JCheckBox myCbInsertJavadocStubOnEnter;
private JCheckBox myCbSurroundSelectionOnTyping;
private JCheckBox myCbReformatBlockOnTypingRBrace;
+ private JCheckBox myCbIndentingBackspace;
private boolean myAddonsInitialized = false;
private static final String NO_REFORMAT = ApplicationBundle.message("combobox.paste.reformat.none");
@@ -160,6 +161,8 @@ public class EditorSmartKeysConfigurable extends CompositeConfigurable<UnnamedCo
myCbSurroundSelectionOnTyping.setSelected(codeInsightSettings.SURROUND_SELECTION_ON_QUOTE_TYPED);
+ myCbIndentingBackspace.setSelected(codeInsightSettings.INDENTING_BACKSPACE);
+
super.reset();
}
@@ -179,6 +182,7 @@ public class EditorSmartKeysConfigurable extends CompositeConfigurable<UnnamedCo
codeInsightSettings.SURROUND_SELECTION_ON_QUOTE_TYPED = myCbSurroundSelectionOnTyping.isSelected();
editorSettings.setCamelWords(myCbCamelWords.isSelected());
codeInsightSettings.REFORMAT_ON_PASTE = getReformatPastedBlockValue();
+ codeInsightSettings.INDENTING_BACKSPACE = myCbIndentingBackspace.isSelected();
super.apply();
}
@@ -204,6 +208,8 @@ public class EditorSmartKeysConfigurable extends CompositeConfigurable<UnnamedCo
isModified |= isModified(myCbSurroundSelectionOnTyping, codeInsightSettings.SURROUND_SELECTION_ON_QUOTE_TYPED);
+ isModified |= isModified(myCbIndentingBackspace, codeInsightSettings.INDENTING_BACKSPACE);
+
return isModified;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java
index 6d13f27e8671..013b0808faca 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/CodeInsightSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -100,6 +100,8 @@ public class CodeInsightSettings implements PersistentStateComponent<Element>, C
public boolean SHOW_FULL_SIGNATURES_IN_PARAMETER_INFO = false;
+ public boolean INDENTING_BACKSPACE = true;
+
public boolean SMART_INDENT_ON_ENTER = true;
public boolean INSERT_BRACE_ON_ENTER = true;
public boolean INSERT_SCRIPTLET_END_ON_ENTER = true;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java
index e4d154bc5bb7..6dcc22637906 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtilBase.java
@@ -349,8 +349,8 @@ public class TargetElementUtilBase {
return navElement;
}
- public boolean includeSelfInGotoImplementation(final PsiElement element) {
- final TargetElementEvaluator elementEvaluator = element != null ? targetElementEvaluator.forLanguage(element.getLanguage()):null;
+ public boolean includeSelfInGotoImplementation(@NotNull final PsiElement element) {
+ final TargetElementEvaluator elementEvaluator = targetElementEvaluator.forLanguage(element.getLanguage());
return elementEvaluator == null || elementEvaluator.includeSelfInGotoImplementation(element);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java
index 1a682e77ca39..c67bc6a4f1b1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java
@@ -93,6 +93,7 @@ public abstract class AbstractLayoutCodeProcessor {
myProgressText = progressText;
myCommandName = commandName;
myPreviousCodeProcessor = previous;
+ myFilters = previous.myFilters;
}
protected AbstractLayoutCodeProcessor(Project project,
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java
index d0e990654f3d..d3cfedaf6a1a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java
@@ -1,5 +1,6 @@
package com.intellij.codeInsight.completion;
+import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -11,7 +12,14 @@ import com.intellij.psi.PsiDocumentManager;
* @author zolotov
*/
public class AddSpaceInsertHandler implements InsertHandler<LookupElement> {
- public final static InsertHandler<LookupElement> INSTANCE = new AddSpaceInsertHandler();
+ public final static InsertHandler<LookupElement> INSTANCE = new AddSpaceInsertHandler(false);
+ public final static InsertHandler<LookupElement> INSTANCE_WITH_AUTO_POPUP = new AddSpaceInsertHandler(true);
+
+ private final boolean myTriggerAutoPopup;
+
+ public AddSpaceInsertHandler(boolean triggerAutoPopup) {
+ myTriggerAutoPopup = triggerAutoPopup;
+ }
public void handleInsert(InsertionContext context, LookupElement item) {
Editor editor = context.getEditor();
@@ -25,6 +33,9 @@ public class AddSpaceInsertHandler implements InsertHandler<LookupElement> {
else {
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1);
}
+ if (myTriggerAutoPopup) {
+ AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null);
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
index 8b2acda41c48..e039cec3a424 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -135,19 +135,18 @@ public class CodeCompletionHandlerBase {
}
*/
- int newTime = phase.newCompletionStarted(time, repeated);
+ final int newTime = phase.newCompletionStarted(time, repeated);
if (invokedExplicitly) {
time = newTime;
}
+ final int invocationCount = time;
if (CompletionServiceImpl.isPhase(CompletionPhase.InsertedSingleItem.class)) {
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
}
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass(), CompletionPhase.CommittingDocuments.class);
- if (time > 1) {
- if (myCompletionType == CompletionType.BASIC) {
- FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
- }
+ if (invocationCount > 1 && myCompletionType == CompletionType.BASIC) {
+ FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
}
final CompletionInitializationContext[] initializationContext = {null};
@@ -168,7 +167,7 @@ public class CodeCompletionHandlerBase {
psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
CompletionAssertions.assertCommitSuccessful(editor, psiFile);
- initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile);
+ initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile, invocationCount);
}
};
ApplicationManager.getApplication().runWriteAction(runnable);
@@ -184,12 +183,12 @@ public class CodeCompletionHandlerBase {
CommandProcessor.getInstance().executeCommand(project, initCmd, null, null);
}
- insertDummyIdentifier(initializationContext[0], hasModifiers, time);
+ insertDummyIdentifier(initializationContext[0], hasModifiers, invocationCount);
}
- private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile) {
+ private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile, int invocationCount) {
final Ref<CompletionContributor> current = Ref.create(null);
- CompletionInitializationContext context = new CompletionInitializationContext(editor, psiFile, myCompletionType) {
+ CompletionInitializationContext context = new CompletionInitializationContext(editor, psiFile, myCompletionType, invocationCount) {
CompletionContributor dummyIdentifierChanger;
@Override
@@ -275,6 +274,7 @@ public class CodeCompletionHandlerBase {
CompletionAssertions.checkEditorValid(editor);
CompletionContext context = createCompletionContext(hostCopy, hostMap.getOffset(CompletionInitializationContext.START_OFFSET), hostMap, initContext.getFile());
+ LookupImpl lookup = obtainLookup(editor);
CompletionParameters parameters = createCompletionParameters(invocationCount, context, editor);
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
@@ -290,7 +290,7 @@ public class CodeCompletionHandlerBase {
final Semaphore freezeSemaphore = new Semaphore();
freezeSemaphore.down();
final CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, parameters, this, freezeSemaphore,
- initContext.getOffsetMap(), hasModifiers);
+ initContext.getOffsetMap(), hasModifiers, lookup);
Disposer.register(indicator, hostMap);
Disposer.register(indicator, context.getOffsetMap());
Disposer.register(indicator, translator);
@@ -323,13 +323,14 @@ public class CodeCompletionHandlerBase {
}
}
- private CompletionParameters createCompletionParameters(int invocationCount, final CompletionContext newContext, final Editor editor) {
+ private CompletionParameters createCompletionParameters(int invocationCount,
+ final CompletionContext newContext, Editor editor) {
final int offset = newContext.getStartOffset();
final PsiFile fileCopy = newContext.file;
PsiFile originalFile = fileCopy.getOriginalFile();
final PsiElement insertedElement = findCompletionPositionLeaf(newContext, offset, fileCopy, originalFile);
insertedElement.putUserData(CompletionContext.COMPLETION_CONTEXT_KEY, newContext);
- return new CompletionParameters(insertedElement, originalFile, myCompletionType, offset, invocationCount, obtainLookup(editor));
+ return new CompletionParameters(insertedElement, originalFile, myCompletionType, offset, invocationCount, editor);
}
@NotNull
@@ -418,15 +419,20 @@ public class CodeCompletionHandlerBase {
final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
- CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
- @Override
- public void run() {
- indicator.setMergeCommand();
- indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
- }
- }, "Autocompletion", null);
-
-
+ try {
+ CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
+ @Override
+ public void run() {
+ indicator.setMergeCommand();
+ indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
+ }
+ }, "Autocompletion", null);
+ }
+ catch (Throwable e) {
+ CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
+ LOG.error(e);
+ return;
+ }
// the insert handler may have started a live template with completion
if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
@@ -532,7 +538,7 @@ public class CodeCompletionHandlerBase {
CompletionContext context;
PsiFile injected = InjectedLanguageUtil.findInjectedPsiNoCommit(hostCopy, hostStartOffset);
if (injected != null) {
- if (injected instanceof PsiFileImpl && injectedLanguageManager.isInjectedFragment(originalFile)) {
+ if (injected instanceof PsiFileImpl) {
((PsiFileImpl)injected).setOriginalFile(originalFile);
}
DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injected);
@@ -564,7 +570,7 @@ public class CodeCompletionHandlerBase {
CompletionAssertions.WatchingInsertionContext context = null;
try {
- Lookup lookup = indicator.getParameters().getLookup();
+ Lookup lookup = indicator.getLookup();
CompletionLookupArranger.StatisticsUpdate update = CompletionLookupArranger.collectStatisticChanges(item, lookup);
context = insertItemHonorBlockSelection(indicator, item, completionChar, items, update);
CompletionLookupArranger.trackStatistics(context, update);
@@ -607,7 +613,8 @@ public class CodeCompletionHandlerBase {
for (RangeMarker marker : insertionPoints) {
if (marker.isValid()) {
int insertionPoint = marker.getStartOffset();
- context = insertItem(indicator, item, completionChar, items, update, editor, insertionPoint, idDelta + insertionPoint);
+ context = insertItem(indicator, item, completionChar, items, update, editor, indicator.getParameters().getOriginalFile(),
+ insertionPoint, idDelta + insertionPoint);
int offset = editor.getCaretModel().getOffset();
caretsAfter.add(document.createRangeMarker(offset, offset));
}
@@ -625,14 +632,20 @@ public class CodeCompletionHandlerBase {
} else if (editor.getCaretModel().supportsMultipleCarets()) {
final List<CompletionAssertions.WatchingInsertionContext> contexts = new ArrayList<CompletionAssertions.WatchingInsertionContext>();
- editor.getCaretModel().runForEachCaret(new CaretAction() {
+ final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
+ hostEditor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
public void perform(Caret caret) {
- CompletionAssertions.WatchingInsertionContext currentContext = insertItem(indicator, item, completionChar, items, update, editor,
- caret.getOffset(), caret.getOffset() + idEndOffsetDelta);
+ PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(indicator.getParameters().getOriginalFile());
+ PsiFile targetFile = InjectedLanguageUtil.findInjectedPsiNoCommit(hostFile, caret.getOffset());
+ Editor targetEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, targetFile);
+ int targetCaretOffset = targetEditor.getCaretModel().getOffset();
+ CompletionAssertions.WatchingInsertionContext currentContext = insertItem(indicator, item, completionChar, items, update,
+ targetEditor, targetFile == null ? hostFile : targetFile,
+ targetCaretOffset, targetCaretOffset + idEndOffsetDelta);
contexts.add(currentContext);
}
- });
+ }, true);
context = contexts.get(contexts.size() - 1);
if (context.shouldAddCompletionChar() && context.getCompletionChar() != Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -647,7 +660,8 @@ public class CodeCompletionHandlerBase {
insertionContext.stopWatching();
}
} else {
- context = insertItem(indicator, item, completionChar, items, update, editor, caretOffset, idEndOffset);
+ context = insertItem(indicator, item, completionChar, items, update, editor, indicator.getParameters().getOriginalFile(), caretOffset,
+ idEndOffset);
}
return context;
}
@@ -703,7 +717,9 @@ public class CodeCompletionHandlerBase {
final char completionChar,
List<LookupElement> items,
final CompletionLookupArranger.StatisticsUpdate update,
- final Editor editor, final int caretOffset, final int idEndOffset) {
+ final Editor editor,
+ final PsiFile psiFile,
+ final int caretOffset, final int idEndOffset) {
editor.getCaretModel().moveToOffset(caretOffset);
final int initialStartOffset = caretOffset - item.getLookupString().length();
assert initialStartOffset >= 0 : "negative startOffset: " + caretOffset + "; " + item.getLookupString();
@@ -713,7 +729,8 @@ public class CodeCompletionHandlerBase {
indicator.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEndOffset);
final CompletionAssertions.WatchingInsertionContext
- context = new CompletionAssertions.WatchingInsertionContext(indicator, completionChar, items, editor);
+ context = new CompletionAssertions.WatchingInsertionContext(indicator.getOffsetMap(), psiFile,
+ completionChar, items, editor);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -754,10 +771,12 @@ public class CodeCompletionHandlerBase {
}
if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
final Language language = PsiUtilBase.getLanguageInEditor(editor, project);
- final List<SmartEnterProcessor> processors = SmartEnterProcessors.INSTANCE.forKey(language);
- if (processors.size() > 0) {
- for (SmartEnterProcessor processor : processors) {
- processor.process(project, editor, indicator.getParameters().getOriginalFile());
+ if (language != null) {
+ final List<SmartEnterProcessor> processors = SmartEnterProcessors.INSTANCE.forKey(language);
+ if (processors.size() > 0) {
+ for (SmartEnterProcessor processor : processors) {
+ processor.process(project, editor, indicator.getParameters().getOriginalFile());
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java
index ac685230486b..59159a84a440 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.StringComboboxEditor;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -30,7 +31,7 @@ import javax.swing.*;
public class ComboEditorCompletionContributor extends CompletionContributor{
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getInvocationCount() == 0) {
return;
}
@@ -38,9 +39,13 @@ public class ComboEditorCompletionContributor extends CompletionContributor{
final PsiFile file = parameters.getOriginalFile();
final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document != null) {
- final JComboBox comboBox = document.getUserData(StringComboboxEditor.COMBO_BOX_KEY);
+ JComboBox comboBox = document.getUserData(StringComboboxEditor.COMBO_BOX_KEY);
if (comboBox != null) {
- final CompletionResultSet resultSet = result.withPrefixMatcher(document.getText().substring(0, parameters.getOffset()));
+ String substring = document.getText().substring(0, parameters.getOffset());
+ boolean plainPrefixMatcher = Boolean.TRUE.equals(document.getUserData(StringComboboxEditor.USE_PLAIN_PREFIX_MATCHER));
+ final CompletionResultSet resultSet = plainPrefixMatcher ?
+ result.withPrefixMatcher(new PlainPrefixMatcher(substring)) :
+ result.withPrefixMatcher(substring);
final int count = comboBox.getItemCount();
for (int i = 0; i < count; i++) {
final Object o = comboBox.getItemAt(i);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java
index d2b74e4bd293..4ad396c48f7a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionAssertions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -170,9 +170,9 @@ class CompletionAssertions {
DocumentEvent killer;
private RangeMarkerSpy spy;
- public WatchingInsertionContext(CompletionProgressIndicator indicator, char completionChar, List<LookupElement> items, Editor editor) {
- super(indicator.getOffsetMap(), completionChar, items.toArray(new LookupElement[items.size()]),
- indicator.getParameters().getOriginalFile(), editor,
+ public WatchingInsertionContext(OffsetMap offsetMap, PsiFile file, char completionChar, List<LookupElement> items, Editor editor) {
+ super(offsetMap, completionChar, items.toArray(new LookupElement[items.size()]),
+ file, editor,
completionChar != Lookup.AUTO_INSERT_SELECT_CHAR && completionChar != Lookup.REPLACE_SELECT_CHAR &&
completionChar != Lookup.NORMAL_SELECT_CHAR);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
index e5058a0249c4..1772ac77d451 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java
@@ -62,6 +62,7 @@ public class CompletionLookupArranger extends LookupArranger {
}
};
private static final int MAX_PREFERRED_COUNT = 5;
+ public static final Key<WeighingContext> WEIGHING_CONTEXT = Key.create("WEIGHING_CONTEXT");
public static final Key<Boolean> PURE_RELEVANCE = Key.create("PURE_RELEVANCE");
public static final Key<Integer> PREFIX_CHANGES = Key.create("PREFIX_CHANGES");
private static final UISettings ourUISettings = UISettings.getInstance();
@@ -140,9 +141,9 @@ public class CompletionLookupArranger extends LookupArranger {
CompletionSorterImpl sorter = obtainSorter(element);
Classifier<LookupElement> classifier = myClassifiers.get(sorter);
if (classifier == null) {
- myClassifiers.put(sorter, classifier = sorter.buildClassifier(new AlphaClassifier(lookup)));
+ myClassifiers.put(sorter, classifier = sorter.buildClassifier(new AlphaClassifier((LookupImpl)lookup)));
}
- classifier.addElement(element);
+ classifier.addElement(element, createContext(true));
super.addElement(lookup, element, presentation);
}
@@ -153,7 +154,7 @@ public class CompletionLookupArranger extends LookupArranger {
return tailText == null || tailText.isEmpty() ? " " : tailText;
}
- private static List<LookupElement> sortByPresentation(Iterable<LookupElement> source, Lookup lookup) {
+ private static List<LookupElement> sortByPresentation(Iterable<LookupElement> source, LookupImpl lookup) {
ArrayList<LookupElement> startMatches = ContainerUtil.newArrayList();
ArrayList<LookupElement> middleMatches = ContainerUtil.newArrayList();
for (LookupElement element : source) {
@@ -175,11 +176,12 @@ public class CompletionLookupArranger extends LookupArranger {
MultiMap<CompletionSorterImpl, LookupElement> itemsBySorter = groupItemsBySorter(items);
LookupElement relevantSelection = findMostRelevantItem(itemsBySorter);
+ LookupImpl lookupImpl = (LookupImpl)lookup;
List<LookupElement> listModel = isAlphaSorted() ?
- sortByPresentation(items, lookup) :
- fillModelByRelevance((LookupImpl)lookup, items, itemsBySorter, relevantSelection);
+ sortByPresentation(items, lookupImpl) :
+ fillModelByRelevance(lookupImpl, items, itemsBySorter, relevantSelection);
- int toSelect = getItemToSelect((LookupImpl)lookup, listModel, onExplicitAction, relevantSelection);
+ int toSelect = getItemToSelect(lookupImpl, listModel, onExplicitAction, relevantSelection);
LOG.assertTrue(toSelect >= 0);
addDummyItems(items.size() - listModel.size(), listModel);
@@ -295,6 +297,7 @@ public class CompletionLookupArranger extends LookupArranger {
private ProcessingContext createContext(boolean pureRelevance) {
ProcessingContext context = new ProcessingContext();
context.put(PREFIX_CHANGES, myPrefixChanges);
+ context.put(WEIGHING_CONTEXT, myProcess.getLookup());
if (pureRelevance) {
context.put(PURE_RELEVANCE, Boolean.TRUE);
}
@@ -505,14 +508,14 @@ public class CompletionLookupArranger extends LookupArranger {
}
private static class AlphaClassifier extends Classifier<LookupElement> {
- private final Lookup myLookup;
+ private final LookupImpl myLookup;
- private AlphaClassifier(Lookup lookup) {
+ private AlphaClassifier(LookupImpl lookup) {
myLookup = lookup;
}
@Override
- public void addElement(LookupElement element) {
+ public void addElement(LookupElement element, ProcessingContext context) {
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java
index d135e19f9e52..b997934523f6 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java
@@ -16,7 +16,6 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
-import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -29,14 +28,13 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandAdapter;
import com.intellij.openapi.command.CommandEvent;
import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.editor.*;
-import com.intellij.openapi.editor.actionSystem.TypedAction;
+import com.intellij.openapi.editor.CaretModel;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.FocusChangeListener;
-import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
-import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
-import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -44,12 +42,9 @@ import com.intellij.openapi.util.Expirable;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.HintListener;
import com.intellij.ui.LightweightHint;
-import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
import java.util.EventObject;
/**
@@ -315,87 +310,5 @@ public abstract class CompletionPhase implements Disposable {
}
}
- public static class EmptyAutoPopup extends CompletionPhase {
- public final Editor editor;
- private final Project project;
- private final EditorMouseAdapter mouseListener;
- private final CaretListener caretListener;
- private final SelectionListener selectionListener;
-
- public EmptyAutoPopup(CompletionProgressIndicator indicator) {
- super(indicator);
- editor = indicator.getEditor();
- project = indicator.getProject();
- MessageBusConnection connection = project.getMessageBus().connect(this);
- connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
- @Override
- public void selectionChanged(@NotNull FileEditorManagerEvent event) {
- stopAutoPopup();
- }
- });
-
- mouseListener = new EditorMouseAdapter() {
- @Override
- public void mouseClicked(EditorMouseEvent e) {
- stopAutoPopup();
- }
- };
-
- caretListener = new CaretAdapter() {
- @Override
- public void caretPositionChanged(CaretEvent e) {
- if (!TypedAction.isTypedActionInProgress()) {
- stopAutoPopup();
- }
- }
- };
- selectionListener = new SelectionListener() {
- @Override
- public void selectionChanged(SelectionEvent e) {
- stopAutoPopup();
- }
- };
-
- editor.addEditorMouseListener(mouseListener);
- editor.getCaretModel().addCaretListener(caretListener);
- editor.getDocument().addDocumentListener(new DocumentAdapter() {
- @Override
- public void documentChanged(DocumentEvent e) {
- if (!TypedAction.isTypedActionInProgress()) {
- stopAutoPopup();
- }
- }
- }, this);
- editor.getSelectionModel().addSelectionListener(selectionListener);
- LookupManager.getInstance(project).addPropertyChangeListener(new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- stopAutoPopup();
- }
- }, this);
- }
-
- @Override
- public void dispose() {
- editor.removeEditorMouseListener(mouseListener);
- editor.getCaretModel().removeCaretListener(caretListener);
- editor.getSelectionModel().removeSelectionListener(selectionListener);
- }
-
- private static void stopAutoPopup() {
- CompletionServiceImpl.setCompletionPhase(NoCompletion);
- }
-
- @Override
- public String toString() {
- return "EmptyAutoPopup,editor=" + editor;
- }
-
- @Override
- public int newCompletionStarted(int time, boolean repeated) {
- CompletionServiceImpl.setCompletionPhase(NoCompletion);
- return repeated ? time + 1 : time;
- }
- }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
index b98fe4a6b985..0143e55a4e98 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
@@ -135,13 +135,14 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
CodeCompletionHandlerBase handler,
Semaphore freezeSemaphore,
final OffsetMap offsetMap,
- boolean hasModifiers) {
+ boolean hasModifiers,
+ LookupImpl lookup) {
myEditor = editor;
myParameters = parameters;
myHandler = handler;
myFreezeSemaphore = freezeSemaphore;
myOffsetMap = offsetMap;
- myLookup = (LookupImpl)parameters.getLookup();
+ myLookup = lookup;
myStartCaret = myEditor.getCaretModel().getOffset();
myAdvertiserChanges.offer(new Runnable() {
@@ -528,7 +529,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
myLookup.hideLookup(false);
LOG.assertTrue(CompletionServiceImpl.getCompletionService().getCurrentCompletion() == null);
- CompletionServiceImpl.setCompletionPhase(new CompletionPhase.EmptyAutoPopup(this));
+ CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
return true;
}
return false;
@@ -759,8 +760,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
catch (ProcessCanceledException ignore) {
}
catch (Throwable t) {
- LOG.error(t);
cancel();
+ LOG.error(t);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java
index 19e1433f56b5..8871333ba197 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionUtil.java
@@ -211,6 +211,7 @@ public class CompletionUtil {
editor.getCaretModel().moveToOffset(context.getTailOffset());
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document);
item.handleInsert(context);
+ PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document);
}
private static void setOffsets(InsertionContext context, int offset, final int tailOffset) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java
index cc69a9aeb611..fe495d3e6f3a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java
@@ -66,7 +66,7 @@ public class DefaultCompletionContributor extends CompletionContributor {
}
@Override
- public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
+ public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final LookupElement[] items = context.getItems();
if (items.length == 1) {
final LookupElement item = items[0];
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java
index 1104bb83d826..b8b58bf5bd1f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.ReferenceRange;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
import com.intellij.util.PairConsumer;
+import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -38,7 +39,7 @@ public class LegacyCompletionContributor extends CompletionContributor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.LegacyCompletionContributor");
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet _result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet _result) {
if (parameters.getCompletionType() != CompletionType.BASIC) {
return;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java
index 4fee3f47ab08..5a93e653e056 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/StatisticsWeigher.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.lookup.Classifier;
import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.WeighingContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
@@ -59,13 +60,13 @@ public class StatisticsWeigher extends CompletionWeigher {
}
@Override
- public void addElement(LookupElement element) {
+ public void addElement(LookupElement element, ProcessingContext context) {
StatisticsInfo baseInfo = getBaseStatisticsInfo(element, myLocation);
- myWeights.put(element, weigh(element, baseInfo));
+ myWeights.put(element, weigh(element, baseInfo, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)));
if (baseInfo == StatisticsInfo.EMPTY) {
myNoStats.add(element);
}
- myNext.addElement(element);
+ myNext.addElement(element, context);
}
private void checkPrefixChanged(ProcessingContext context) {
@@ -80,7 +81,7 @@ public class StatisticsWeigher extends CompletionWeigher {
public Iterable<LookupElement> classify(Iterable<LookupElement> source, final ProcessingContext context) {
checkPrefixChanged(context);
- final Collection<List<LookupElement>> byWeight = buildMapByWeight(source).descendingMap().values();
+ final Collection<List<LookupElement>> byWeight = buildMapByWeight(source, context).descendingMap().values();
List<LookupElement> initialList = getInitialNoStatElements(source, context);
@@ -119,10 +120,10 @@ public class StatisticsWeigher extends CompletionWeigher {
return initialList;
}
- private TreeMap<Integer, List<LookupElement>> buildMapByWeight(Iterable<LookupElement> source) {
+ private TreeMap<Integer, List<LookupElement>> buildMapByWeight(Iterable<LookupElement> source, ProcessingContext context) {
TreeMap<Integer, List<LookupElement>> map = new TreeMap<Integer, List<LookupElement>>();
for (LookupElement element : source) {
- final int weight = getWeight(element);
+ final int weight = getWeight(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT));
List<LookupElement> list = map.get(weight);
if (list == null) {
map.put(weight, list = new SmartList<LookupElement>());
@@ -132,19 +133,19 @@ public class StatisticsWeigher extends CompletionWeigher {
return map;
}
- private int getWeight(LookupElement t) {
+ private int getWeight(LookupElement t, WeighingContext context) {
Integer w = myWeights.get(t);
if (w == null) {
- myWeights.put(t, w = weigh(t, getBaseStatisticsInfo(t, myLocation)));
+ myWeights.put(t, w = weigh(t, getBaseStatisticsInfo(t, myLocation), context));
}
return w;
}
- private int weigh(@NotNull LookupElement item, final StatisticsInfo baseInfo) {
+ private static int weigh(@NotNull LookupElement item, final StatisticsInfo baseInfo, WeighingContext context) {
if (baseInfo == StatisticsInfo.EMPTY) {
return 0;
}
- String prefix = myLocation.getCompletionParameters().getLookup().itemPattern(item);
+ String prefix = context.itemPattern(item);
StatisticsInfo composed = composeStatsWithPrefix(baseInfo, prefix, false);
int minRecency = composed.getLastUseRecency();
int useCount = composed.getUseCount();
@@ -159,7 +160,7 @@ public class StatisticsWeigher extends CompletionWeigher {
if (builder.length() > 0) {
builder.append(", ");
}
- builder.append("stats=").append(getWeight(element));
+ builder.append("stats=").append(getWeight(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)));
}
myNext.describeItems(map, context);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java
index 5d1ef95ffb4c..7dc1cd40dfad 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java
@@ -30,6 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.cache.impl.id.IdTableBuilding;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -45,7 +46,7 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
public class WordCompletionContributor extends CompletionContributor implements DumbAware {
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getCompletionType() == CompletionType.BASIC && shouldPerformWordCompletion(parameters)) {
addWordCompletionVariants(result, parameters, Collections.<String>emptySet());
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java
index ee3a195ae8fa..afb392845031 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CamelHumpMatcher.java
@@ -143,10 +143,10 @@ public class CamelHumpMatcher extends PrefixMatcher {
int matchStart = ranges.get(0).getStartOffset();
int underscoreEnd = skipUnderscores(string);
if (matchStart > 0 && matchStart <= underscoreEnd) {
- return myCaseInsensitiveMatcher.matchingDegree(string.substring(matchStart)) - 1;
+ return myCaseInsensitiveMatcher.matchingDegree(string.substring(matchStart), true) - 1;
}
}
- return myMatcher.matchingDegree(string);
+ return myMatcher.matchingDegree(string, true);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
index f916c293ddbc..b69231718a9d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
@@ -87,14 +87,9 @@ public class CompletionServiceImpl extends CompletionService{
final PsiElement position = parameters.getPosition();
final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset());
final int lengthOfTextBeforePosition = parameters.getOffset();
- ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
- if (!(indicator instanceof CompletionProgressIndicator)) {
- throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace);
- }
- CompletionProgressIndicator process = (CompletionProgressIndicator)indicator;
CamelHumpMatcher matcher = new CamelHumpMatcher(prefix);
CompletionSorterImpl sorter = defaultSorter(parameters, matcher);
- return new CompletionResultSetImpl(consumer, lengthOfTextBeforePosition, matcher, contributor,parameters, sorter, process, null);
+ return new CompletionResultSetImpl(consumer, lengthOfTextBeforePosition, matcher, contributor,parameters, sorter, null);
}
@Override
@@ -110,7 +105,6 @@ public class CompletionServiceImpl extends CompletionService{
private final int myLengthOfTextBeforePosition;
private final CompletionParameters myParameters;
private final CompletionSorterImpl mySorter;
- private final CompletionProgressIndicator myProcess;
@Nullable private final CompletionResultSetImpl myOriginal;
public CompletionResultSetImpl(final Consumer<CompletionResult> consumer, final int lengthOfTextBeforePosition,
@@ -118,13 +112,11 @@ public class CompletionServiceImpl extends CompletionService{
CompletionContributor contributor,
CompletionParameters parameters,
@NotNull CompletionSorterImpl sorter,
- @NotNull CompletionProgressIndicator process,
@Nullable CompletionResultSetImpl original) {
super(prefixMatcher, consumer, contributor);
myLengthOfTextBeforePosition = lengthOfTextBeforePosition;
myParameters = parameters;
mySorter = sorter;
- myProcess = process;
myOriginal = original;
}
@@ -144,7 +136,7 @@ public class CompletionServiceImpl extends CompletionService{
@Override
@NotNull
public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) {
- return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
+ return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, matcher, myContributor, myParameters, mySorter, this);
}
@Override
@@ -167,7 +159,8 @@ public class CompletionServiceImpl extends CompletionService{
@NotNull
@Override
public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) {
- return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
+ return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter,
+ this);
}
@Override
@@ -249,12 +242,12 @@ public class CompletionServiceImpl extends CompletionService{
CompletionSorterImpl sorter = emptySorter();
sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new DispreferLiveTemplates()));
- sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new PreferStartMatching(location)));
+ sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new PreferStartMatching()));
for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) {
final String id = weigher.toString();
if ("prefix".equals(id)) {
- sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new RealPrefixMatchingWeigher(location)));
+ sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new RealPrefixMatchingWeigher()));
}
else if ("stats".equals(id)) {
sorter = sorter.withClassifier(new ClassifierFactory<LookupElement>("stats") {
@@ -287,13 +280,13 @@ public class CompletionServiceImpl extends CompletionService{
return new CompletionSorterImpl(new ArrayList<ClassifierFactory<LookupElement>>());
}
- public static boolean isStartMatch(LookupElement element, Lookup lookup) {
- return getItemMatcher(element, lookup).isStartMatch(element);
+ public static boolean isStartMatch(LookupElement element, WeighingContext context) {
+ return getItemMatcher(element, context).isStartMatch(element);
}
- static PrefixMatcher getItemMatcher(LookupElement element, Lookup lookup) {
- PrefixMatcher itemMatcher = lookup.itemMatcher(element);
- String pattern = lookup.itemPattern(element);
+ static PrefixMatcher getItemMatcher(LookupElement element, WeighingContext context) {
+ PrefixMatcher itemMatcher = context.itemMatcher(element);
+ String pattern = context.itemPattern(element);
if (!pattern.equals(itemMatcher.getPrefix())) {
return itemMatcher.cloneWithPrefix(pattern);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
index 271397d4d6a3..821d16a7b52b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
@@ -51,7 +51,7 @@ public class LiftShorterItemsClassifier extends Classifier<LookupElement> {
}
@Override
- public void addElement(LookupElement added) {
+ public void addElement(LookupElement added, ProcessingContext context) {
myCount++;
final Set<String> strings = added.getAllLookupStrings();
@@ -70,7 +70,7 @@ public class LiftShorterItemsClassifier extends Classifier<LookupElement> {
}
}
}
- myNext.addElement(added);
+ myNext.addElement(added, context);
calculateToLift(added);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java
index 569806405562..eaafbd5d9c37 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java
@@ -1,23 +1,21 @@
package com.intellij.codeInsight.completion.impl;
-import com.intellij.codeInsight.completion.CompletionLocation;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
+import com.intellij.codeInsight.lookup.WeighingContext;
import org.jetbrains.annotations.NotNull;
/**
* @author Peter
*/
public class PreferStartMatching extends LookupElementWeigher {
- private final CompletionLocation myLocation;
- public PreferStartMatching(CompletionLocation location) {
+ public PreferStartMatching() {
super("middleMatching", false, true);
- myLocation = location;
}
@Override
- public Comparable weigh(@NotNull LookupElement element) {
- return !CompletionServiceImpl.isStartMatch(element, myLocation.getCompletionParameters().getLookup());
+ public Comparable weigh(@NotNull LookupElement element, @NotNull WeighingContext context) {
+ return !CompletionServiceImpl.isStartMatch(element, context);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java
index 9169142f5180..cc1eb388b78c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java
@@ -1,25 +1,23 @@
package com.intellij.codeInsight.completion.impl;
-import com.intellij.codeInsight.completion.CompletionLocation;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementWeigher;
+import com.intellij.codeInsight.lookup.WeighingContext;
import org.jetbrains.annotations.NotNull;
/**
* @author Peter
*/
public class RealPrefixMatchingWeigher extends LookupElementWeigher {
- private final CompletionLocation myLocation;
- public RealPrefixMatchingWeigher(CompletionLocation location) {
+ public RealPrefixMatchingWeigher() {
super("prefix", false, true);
- myLocation = location;
}
@Override
- public Comparable weigh(@NotNull LookupElement element) {
- return getBestMatchingDegree(element, CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup()));
+ public Comparable weigh(@NotNull LookupElement element, @NotNull WeighingContext context) {
+ return getBestMatchingDegree(element, CompletionServiceImpl.getItemMatcher(element, context));
}
public static int getBestMatchingDegree(LookupElement element, PrefixMatcher matcher) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
index 65d302e8ec21..d8fd3ab40508 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
@@ -30,9 +30,10 @@ import com.intellij.codeInsight.intention.impl.IntentionHintComponent;
import com.intellij.ide.PowerSaveMode;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.application.ex.ApplicationEx;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -55,6 +56,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.newvfs.RefreshQueueImpl;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiDocumentManager;
@@ -66,6 +68,7 @@ import com.intellij.util.Alarm;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
+import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -273,7 +276,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
@Nullable Runnable callbackWhileWaiting) throws ProcessCanceledException {
assert myInitialized;
assert !myDisposed;
- Application application = ApplicationManager.getApplication();
+ ApplicationEx application = ApplicationManagerEx.getApplicationEx();
application.assertIsDispatchThread();
if (application.isWriteAccessAllowed()) {
throw new AssertionError("Must not start highlighting from within write action, or deadlock is imminent");
@@ -282,14 +285,17 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
((FileTypeManagerImpl)FileTypeManager.getInstance()).drainReDetectQueue();
// pump first so that queued event do not interfere
UIUtil.dispatchAllInvocationEvents();
+
+ // refresh will fire write actions interfering with highlighting
+ while (RefreshQueueImpl.isRefreshInProgress() || HeavyProcessLatch.INSTANCE.isRunning()) {
+ UIUtil.dispatchAllInvocationEvents();
+ }
+
UIUtil.dispatchAllInvocationEvents();
Project project = file.getProject();
setUpdateByTimerEnabled(false);
FileStatusMap fileStatusMap = getFileStatusMap();
- for (int ignoreId : toIgnore) {
- fileStatusMap.markFileUpToDate(document, ignoreId);
- }
fileStatusMap.allowDirt(canChangeDocument);
Map<FileEditor, HighlightingPass[]> map = new HashMap<FileEditor, HighlightingPass[]>();
@@ -300,6 +306,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
assert array.length != 0 : "Highlighting is disabled for the file " + file;
map.put(textEditor, array);
}
+ for (int ignoreId : toIgnore) {
+ fileStatusMap.markFileUpToDate(document, ignoreId);
+ }
+
final DaemonProgressIndicator progress = createUpdateProgress();
myPassExecutorService.submitPasses(map, progress);
try {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
index 8c79df55ee7a..75a4fd410959 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
@@ -21,6 +21,7 @@ import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.codeInsight.hint.TooltipController;
+import com.intellij.ide.IdeTooltipManager;
import com.intellij.ide.PowerSaveMode;
import com.intellij.ide.todo.TodoConfiguration;
import com.intellij.openapi.Disposable;
@@ -599,6 +600,7 @@ public class DaemonListeners implements Disposable {
if (editor.offsetToLogicalPosition(offset).column != logical.column) return; // we are in virtual space
HighlightInfo info = myDaemonCodeAnalyzer.findHighlightByOffset(editor.getDocument(), offset, false);
if (info == null || info.getDescription() == null) return;
+ if (IdeTooltipManager.getInstance().hasCurrent()) return;
DaemonTooltipUtil.showInfoTooltip(info, editor, offset);
shown = true;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
index 3066c0e2f20b..8560129194f1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
@@ -220,6 +220,7 @@ public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass imp
Place places = InjectedLanguageUtil.getShreds(injectedPsi);
for (PsiLanguageInjectionHost.Shred place : places) {
PsiLanguageInjectionHost host = place.getHost();
+ if (host == null) continue;
TextRange textRange = place.getRangeInsideHost().shiftRight(host.getTextRange().getStartOffset());
if (textRange.isEmpty()) continue;
String desc = injectedPsi.getLanguage().getDisplayName() + ": " + injectedPsi.getText();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
index 12f04344aa09..44df90322011 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -48,7 +49,9 @@ import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
-import gnu.trove.*;
+import gnu.trove.THashMap;
+import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TIntObjectProcedure;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
@@ -127,7 +130,9 @@ public class PassExecutorService implements Disposable {
TextEditorHighlightingPass textEditorHighlightingPass = convertToTextHighlightingPass(pass, document, nextPassId, prevId);
document = textEditorHighlightingPass.getDocument();
documentBoundPasses.putValue(fileEditor, textEditorHighlightingPass);
- documentToEditors.putValue(document, fileEditor);
+ if (document != null) {
+ documentToEditors.putValue(document, fileEditor);
+ }
prevId = textEditorHighlightingPass.getId();
}
}
@@ -165,7 +170,7 @@ public class PassExecutorService implements Disposable {
}
}
- if (CHECK_CONSISTENCY) {
+ if (CHECK_CONSISTENCY && !ApplicationInfoImpl.isInPerformanceTest()) {
assertConsistency(freePasses, toBeSubmitted, threadsToStartCountdown);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java
index e0a88d1878f0..661e9bed82da 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java
@@ -35,10 +35,12 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiDocumentManagerBase;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.PsiDocumentTransactionListener;
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +72,7 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable
if (documentManager.getCachedPsiFile(document) == null) return;
if (document.getUserData(UPDATE_ON_COMMIT_ENGAGED) == null) {
document.putUserData(UPDATE_ON_COMMIT_ENGAGED, Boolean.TRUE);
- PsiDocumentManagerImpl.addRunOnCommit(document, new Runnable() {
+ PsiDocumentManagerBase.addRunOnCommit(document, new Runnable() {
@Override
public void run() {
updateChangesForDocument(document);
@@ -100,7 +102,17 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable
private void updateChangesForDocument(@NotNull final Document document) {
if (DaemonListeners.isUnderIgnoredAction(null)) return;
List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
- if (toUpdate == null) return;
+ if (toUpdate == null) {
+ // The document has been changed, but psi hasn't
+ // We may still need to rehighlight the file if there were changes inside highlighted ranges.
+ if (UpdateHighlightersUtil.isWhitespaceOptimizationAllowed(document)) return;
+
+ // don't create PSI for files in other projects
+ PsiElement file = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(document);
+ if (file == null) return;
+
+ toUpdate = ContainerUtil.newArrayList(Pair.create(file, true));
+ }
Application application = ApplicationManager.getApplication();
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
if (editor != null && !application.isUnitTestMode()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/EncodingReference.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/EncodingReference.java
new file mode 100644
index 000000000000..d3f0da5e5d0f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/EncodingReference.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon.impl.analysis.encoding;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author peter
+ */
+public class EncodingReference implements PsiReference {
+ private final PsiElement myElement;
+
+ private final String myCharsetName;
+ private final TextRange myRangeInElement;
+
+ public EncodingReference(PsiElement element, final String charsetName, final TextRange rangeInElement) {
+ myElement = element;
+ myCharsetName = charsetName;
+ myRangeInElement = rangeInElement;
+ }
+
+ @Override
+ public PsiElement getElement() {
+ return myElement;
+ }
+
+ @Override
+ public TextRange getRangeInElement() {
+ return myRangeInElement;
+ }
+
+ @Override
+ @Nullable
+ public PsiElement resolve() {
+ return CharsetToolkit.forName(myCharsetName) == null ? null : myElement;
+ //if (ApplicationManager.getApplication().isUnitTestMode()) return myValue; // tests do not have full JDK
+ //String fqn = charset.getClass().getName();
+ //return myValue.getManager().findClass(fqn, GlobalSearchScope.allScope(myValue.getProject()));
+ }
+
+ @Override
+ @NotNull
+ public String getCanonicalText() {
+ return myCharsetName;
+ }
+
+ @Override
+ public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
+ return null;
+ }
+
+ @Override
+ public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
+ return null;
+ }
+
+ @Override
+ public boolean isReferenceTo(PsiElement element) {
+ return false;
+ }
+
+ @Override
+ @NotNull
+ public Object[] getVariants() {
+ Charset[] charsets = CharsetToolkit.getAvailableCharsets();
+ List<LookupElement> suggestions = new ArrayList<LookupElement>(charsets.length);
+ for (Charset charset : charsets) {
+ suggestions.add(LookupElementBuilder.create(charset.name()).withCaseSensitivity(false));
+ }
+ return suggestions.toArray(new LookupElement[suggestions.size()]);
+ }
+
+ @Override
+ public boolean isSoft() {
+ return false;
+ }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
index 46ef6d1b1ab6..cf9b5ad22798 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
@@ -40,6 +40,7 @@ import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
@@ -65,6 +66,7 @@ import javax.swing.event.HyperlinkListener;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -98,6 +100,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final JComponent mySettingsPanel;
private final MyShowSettingsButton myShowSettingsButton;
private boolean myIgnoreFontSizeSliderChange;
+ private String myEffectiveExternalUrl;
private static class Context {
final SmartPsiElementPointer element;
@@ -461,7 +464,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myForwardStack.clear();
}
updateControlState();
- setData(element, text, clearHistory);
+ setData(element, text, clearHistory, null);
if (clean) {
myIsEmpty = false;
}
@@ -480,7 +483,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myBackStack.clear();
}
- public void setData(PsiElement _element, String text, final boolean clearHistory) {
+ public void setData(PsiElement _element, String text, final boolean clearHistory, String effectiveExternalUrl) {
+ myEffectiveExternalUrl = effectiveExternalUrl;
if (myElement != null) {
myBackStack.push(saveContext());
myForwardStack.clear();
@@ -641,8 +645,9 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
@Override
public void actionPerformed(AnActionEvent e) {
super.actionPerformed(e);
- if (myHint.isVisible()) {
- myHint.cancel();
+ final JBPopup hint = myHint;
+ if (hint != null && hint.isVisible()) {
+ hint.cancel();
}
}
@@ -682,10 +687,16 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
if (!processed) {
- final List<String> urls = provider.getUrlFor(element, originalElement);
- assert urls != null : provider;
- assert !urls.isEmpty() : provider;
- ExternalJavaDocAction.showExternalJavadoc(urls);
+ final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext());
+ final List<String> urls;
+ if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl)) {
+ urls = Collections.singletonList(myEffectiveExternalUrl);
+ } else {
+ urls = provider.getUrlFor(element, originalElement);
+ assert urls != null : provider;
+ assert !urls.isEmpty() : provider;
+ }
+ ExternalJavaDocAction.showExternalJavadoc(urls, component);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
index c81b505dec37..df55cbad9346 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
@@ -615,99 +615,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
private DocumentationCollector getDefaultCollector(@NotNull final PsiElement element, @Nullable final PsiElement originalElement) {
- return new DocumentationCollector() {
-
- @Override
- @Nullable
- public String getDocumentation() throws Exception {
- final DocumentationProvider provider = ApplicationManager.getApplication().runReadAction(
- new Computable<DocumentationProvider>() {
- @Override
- public DocumentationProvider compute() {
- return getProviderFromElement(element, originalElement);
- }
- }
- );
- if (myParameterInfoController != null) {
- final String doc = ApplicationManager.getApplication().runReadAction(
- new NullableComputable<String>() {
- @Override
- public String compute() {
- return generateParameterInfoDocumentation(provider);
- }
- }
- );
- if (doc != null) return doc;
- }
- if (provider instanceof ExternalDocumentationProvider) {
- final List<String> urls = ApplicationManager.getApplication().runReadAction(
- new NullableComputable<List<String>>() {
- @Override
- public List<String> compute() {
- final SmartPsiElementPointer originalElementPtr = element.getUserData(ORIGINAL_ELEMENT_KEY);
- final PsiElement originalElement = originalElementPtr != null ? originalElementPtr.getElement() : null;
- if (((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement)) {
- return provider.getUrlFor(element, originalElement);
- }
- return null;
- }
- }
- );
- if (urls != null) {
- final String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(myProject, element, urls);
- if (doc != null) return doc;
- }
- }
- return ApplicationManager.getApplication().runReadAction(
- new Computable<String>() {
- @Override
- @Nullable
- public String compute() {
- final SmartPsiElementPointer originalElement = element.getUserData(ORIGINAL_ELEMENT_KEY);
- return provider.generateDoc(element, originalElement != null ? originalElement.getElement() : null);
- }
- }
- );
- }
-
- @Nullable
- private String generateParameterInfoDocumentation(DocumentationProvider provider) {
- final Object[] objects = myParameterInfoController.getSelectedElements();
-
- if (objects.length > 0) {
- @NonNls StringBuffer sb = null;
-
- for (Object o : objects) {
- PsiElement parameter = null;
- if (o instanceof PsiElement) {
- parameter = (PsiElement)o;
- }
-
- if (parameter != null) {
- final SmartPsiElementPointer originalElement = parameter.getUserData(ORIGINAL_ELEMENT_KEY);
- final String str2 = provider.generateDoc(parameter, originalElement != null ? originalElement.getElement() : null);
- if (str2 == null) continue;
- if (sb == null) sb = new StringBuffer();
- sb.append(str2);
- sb.append("<br>");
- }
- else {
- sb = null;
- break;
- }
- }
-
- if (sb != null) return sb.toString();
- }
- return null;
- }
-
- @Override
- @Nullable
- public PsiElement getElement() {
- return element.isValid() ? element : null;
- }
- };
+ return new DefaultDocumentationCollector(element, originalElement);
}
@Nullable
@@ -813,7 +721,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
component.setText(component.getText(), element, true, clearHistory);
}
else {
- component.setData(element, documentationText, clearHistory);
+ component.setData(element, documentationText, clearHistory, provider.getEffectiveExternalUrl());
}
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
@@ -945,6 +853,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
public PsiElement getElement() {
return psiElement;
}
+
+ @Nullable
+ @Override
+ public String getEffectiveExternalUrl() {
+ return url;
+ }
}, component);
processed = true;
}
@@ -992,6 +906,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return psiElement;
}
+
+ @Nullable
+ @Override
+ public String getEffectiveExternalUrl() {
+ return url;
+ }
}, component);
}
}
@@ -1062,5 +982,122 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
String getDocumentation() throws Exception;
@Nullable
PsiElement getElement();
+ @Nullable
+ String getEffectiveExternalUrl();
+ }
+
+ private class DefaultDocumentationCollector implements DocumentationCollector {
+
+ private final PsiElement myElement;
+ private final PsiElement myOriginalElement;
+
+ private String myEffectiveUrl;
+
+ public DefaultDocumentationCollector(PsiElement element, PsiElement originalElement) {
+ myElement = element;
+ myOriginalElement = originalElement;
+ }
+
+ @Override
+ @Nullable
+ public String getDocumentation() throws Exception {
+ final DocumentationProvider provider = ApplicationManager.getApplication().runReadAction(
+ new Computable<DocumentationProvider>() {
+ @Override
+ public DocumentationProvider compute() {
+ return getProviderFromElement(myElement, myOriginalElement);
+ }
+ }
+ );
+ if (myParameterInfoController != null) {
+ final String doc = ApplicationManager.getApplication().runReadAction(
+ new NullableComputable<String>() {
+ @Override
+ public String compute() {
+ return generateParameterInfoDocumentation(provider);
+ }
+ }
+ );
+ if (doc != null) return doc;
+ }
+ if (provider instanceof ExternalDocumentationProvider) {
+ final List<String> urls = ApplicationManager.getApplication().runReadAction(
+ new NullableComputable<List<String>>() {
+ @Override
+ public List<String> compute() {
+ final SmartPsiElementPointer originalElementPtr = myElement.getUserData(ORIGINAL_ELEMENT_KEY);
+ final PsiElement originalElement = originalElementPtr != null ? originalElementPtr.getElement() : null;
+ if (((ExternalDocumentationProvider)provider).hasDocumentationFor(myElement, originalElement)) {
+ return provider.getUrlFor(myElement, originalElement);
+ }
+ return null;
+ }
+ }
+ );
+ if (urls != null) {
+ for (String url : urls) {
+ final String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(myProject, myElement, Collections.singletonList(url));
+ if (doc != null) {
+ myEffectiveUrl = url;
+ return doc;
+ }
+ }
+ }
+ }
+ return ApplicationManager.getApplication().runReadAction(
+ new Computable<String>() {
+ @Override
+ @Nullable
+ public String compute() {
+ final SmartPsiElementPointer originalElement = myElement.getUserData(ORIGINAL_ELEMENT_KEY);
+ return provider.generateDoc(myElement, originalElement != null ? originalElement.getElement() : null);
+ }
+ }
+ );
+ }
+
+ @Nullable
+ private String generateParameterInfoDocumentation(DocumentationProvider provider) {
+ final Object[] objects = myParameterInfoController.getSelectedElements();
+
+ if (objects.length > 0) {
+ @NonNls StringBuffer sb = null;
+
+ for (Object o : objects) {
+ PsiElement parameter = null;
+ if (o instanceof PsiElement) {
+ parameter = (PsiElement)o;
+ }
+
+ if (parameter != null) {
+ final SmartPsiElementPointer originalElement = parameter.getUserData(ORIGINAL_ELEMENT_KEY);
+ final String str2 = provider.generateDoc(parameter, originalElement != null ? originalElement.getElement() : null);
+ if (str2 == null) continue;
+ if (sb == null) sb = new StringBuffer();
+ sb.append(str2);
+ sb.append("<br>");
+ }
+ else {
+ sb = null;
+ break;
+ }
+ }
+
+ if (sb != null) return sb.toString();
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public PsiElement getElement() {
+ return myElement.isValid() ? myElement : null;
+ }
+
+ @Nullable
+ @Override
+ public String getEffectiveExternalUrl() {
+ return myEffectiveUrl;
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
index c743029fe6a7..eb163245d23b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
@@ -45,13 +45,8 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
@Override
public Result checkAutoPopup(char charTyped, final Project project, final Editor editor, final PsiFile file) {
CompletionPhase oldPhase = CompletionServiceImpl.getCompletionPhase();
- if (oldPhase instanceof CompletionPhase.EmptyAutoPopup && ((CompletionPhase.EmptyAutoPopup)oldPhase).editor != editor) {
- CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
- }
-
if (oldPhase instanceof CompletionPhase.CommittingDocuments && ((CompletionPhase.CommittingDocuments)oldPhase).isRestartingCompletion()) {
- oldPhase.indicator.scheduleRestart();
return Result.STOP;
}
@@ -73,7 +68,7 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.STOP;
}
- if (CompletionServiceImpl.isPhase(CompletionPhase.EmptyAutoPopup.class, CompletionPhase.CommittingDocuments.class)) {
+ if (CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
}
return Result.CONTINUE;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java
new file mode 100644
index 000000000000..634b8f5570a3
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.editorActions;
+
+import com.intellij.codeInsight.CodeInsightSettings;
+import com.intellij.codeStyle.CodeStyleFacade;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Makes Backspace action delete all whitespace till next valid indent position
+ */
+public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
+ private static final Logger LOG = Logger.getInstance(IndentingBackspaceHandler.class);
+
+ private boolean caretWasAtLineStart;
+
+ @Override
+ public void beforeCharDeleted(char c, PsiFile file, Editor editor) {
+ caretWasAtLineStart = editor.getCaretModel().getLogicalPosition().column == 0;
+ }
+
+ @Override
+ public boolean charDeleted(char c, PsiFile file, Editor editor) {
+ if (!CodeInsightSettings.getInstance().INDENTING_BACKSPACE || !StringUtil.isWhiteSpace(c)) {
+ return false;
+ }
+ LanguageCodeStyleSettingsProvider codeStyleSettingsProvider = LanguageCodeStyleSettingsProvider.forLanguage(file.getLanguage());
+ if (codeStyleSettingsProvider != null && codeStyleSettingsProvider.isIndentBasedLanguageSemantics()) {
+ return false;
+ }
+
+ Document document = editor.getDocument();
+
+ int caretOffset = editor.getCaretModel().getOffset();
+ int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), caretOffset, " \t");
+ int beforeWhitespaceOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), offset - 1, " \t") + 1;
+ LogicalPosition logicalPosition = caretOffset < offset ? editor.offsetToLogicalPosition(offset) : editor.getCaretModel().getLogicalPosition();
+ int lineStartOffset = document.getLineStartOffset(logicalPosition.line);
+ if (lineStartOffset < beforeWhitespaceOffset) {
+ if (caretWasAtLineStart && beforeWhitespaceOffset < offset) {
+ document.deleteString(beforeWhitespaceOffset, offset);
+ return true;
+ }
+ return false;
+ }
+
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(editor.getProject());
+ String indent = codeStyleFacade.getLineIndent(document, lineStartOffset);
+ if (indent == null) {
+ return false;
+ }
+
+ int tabSize = getTabSize(codeStyleFacade, document);
+ int targetColumn = getWidth(indent, tabSize);
+
+ if (logicalPosition.column == targetColumn) {
+ if (caretOffset < offset) {
+ editor.getCaretModel().moveToLogicalPosition(logicalPosition);
+ return true;
+ }
+ return false;
+ }
+
+ if (caretWasAtLineStart || logicalPosition.column > targetColumn) {
+ document.replaceString(lineStartOffset, offset, indent);
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line, targetColumn));
+ return true;
+ }
+
+ if (logicalPosition.line == 0) {
+ return false;
+ }
+
+ int prevLineStartOffset = document.getLineStartOffset(logicalPosition.line - 1);
+ int prevLineEndOffset = document.getLineEndOffset(logicalPosition.line - 1);
+ int targetOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), prevLineEndOffset - 1, " \t") + 1;
+
+ if (prevLineStartOffset < targetOffset) {
+ document.deleteString(targetOffset, offset);
+ editor.getCaretModel().moveToOffset(targetOffset);
+ }
+ else {
+ document.replaceString(prevLineStartOffset, offset, indent);
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line - 1, targetColumn));
+ }
+ return true;
+ }
+
+ private static int getTabSize(@NotNull CodeStyleFacade codeStyleFacade, @NotNull Document document) {
+ VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ FileType fileType = file == null ? null : file.getFileType();
+ return codeStyleFacade.getTabSize(fileType);
+ }
+
+ private static int getWidth(@NotNull String indent, int tabSize) {
+ int width = 0;
+ for (int i = 0; i < indent.length(); i++) {
+ char c = indent.charAt(i);
+ switch (c) {
+ case '\t':
+ width = tabSize * (width / tabSize + 1);
+ break;
+ default:
+ LOG.error("Unexpected whitespace character: " + ((int)c));
+ case ' ':
+ width++;
+ }
+ }
+ return width;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectionQuotingTypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectionQuotingTypedHandler.java
index 954b804561ce..76dc70fe7116 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectionQuotingTypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/SelectionQuotingTypedHandler.java
@@ -17,19 +17,16 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.injected.editor.EditorWindow;
-import com.intellij.openapi.editor.Caret;
-import com.intellij.openapi.editor.CaretAction;
+import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -40,63 +37,49 @@ import org.jetbrains.annotations.NotNull;
public class SelectionQuotingTypedHandler extends TypedHandlerDelegate {
public static final ExtensionPointName<DequotingFilter> EP_NAME =
ExtensionPointName.create("com.intellij.selectionDequotingFilter");
+ private TextRange myReplacedTextRange;
private boolean myRestoreStickySelection;
-
- private static final Key<String> REPLACEMENT_TEXT = Key.create("SelectionQuotingTypedHandler.replacementText");
- private static final Key<TextRange> REPLACED_TEXT_RANGE = Key.create("SelectionQuotingTypedHandler.replacedTextRange");
- private static final Key<Boolean> LTR_SELECTION = Key.create("SelectionQuotingTypedHandler.ltrSelection");
+ private boolean myLtrSelection;
@Override
- public Result checkAutoPopup(final char c, Project project, final Editor editor, final PsiFile psiFile) {
+ public Result checkAutoPopup(char c, Project project, Editor editor, PsiFile psiFile) {
// TODO[oleg] provide adequate API not to use this hack
// beforeCharTyped always works with removed selection
- if(CodeInsightSettings.getInstance().SURROUND_SELECTION_ON_QUOTE_TYPED && editor.getSelectionModel().hasSelection(true) && isDelimiter(c)) {
- myRestoreStickySelection = (editor instanceof EditorEx) && ((EditorEx)editor).isStickySelection();
-
- // first we determine replacement texts for each caret, then we apply all the changes
- // this is to make PSI consistent with document state for the calculation of replacement text for all carets
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- String replacementText = null;
- String selectedText = caret.getSelectedText();
- if (!StringUtil.isEmpty(selectedText)) {
- if (selectedText.length() > 1) {
- final char firstChar = selectedText.charAt(0);
- final char lastChar = selectedText.charAt(selectedText.length() - 1);
- if (isSimilarDelimiters(firstChar, c) && lastChar == getMatchingDelimiter(firstChar) &&
- (isQuote(firstChar) || firstChar != c) && !shouldSkipReplacementOfQuotesOrBraces(psiFile, editor, selectedText, c) &&
- selectedText.indexOf(lastChar, 1) == selectedText.length() - 1) {
- selectedText = selectedText.substring(1, selectedText.length() - 1);
- }
- }
- final char c2 = getMatchingDelimiter(c);
- replacementText = String.valueOf(c) + selectedText + c2;
- }
- caret.putUserData(REPLACEMENT_TEXT, replacementText);
- }
- });
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- String replacementText = caret.getUserData(REPLACEMENT_TEXT);
- caret.putUserData(REPLACEMENT_TEXT, null);
- if (replacementText == null) {
- caret.putUserData(LTR_SELECTION, null);
- caret.putUserData(REPLACED_TEXT_RANGE, null);
- }
- else {
- int selectionStart = caret.getSelectionStart();
- int selectionEnd = caret.getSelectionEnd();
- caret.putUserData(LTR_SELECTION, caret.getLeadSelectionOffset() != selectionEnd);
- caret.putUserData(REPLACED_TEXT_RANGE, Registry.is("editor.smarterSelectionQuoting")
- ? new TextRange(selectionStart + 1, selectionStart + replacementText.length() - 1)
- : new TextRange(selectionStart, selectionStart + replacementText.length()));
- caret.removeSelection();
- editor.getDocument().replaceString(selectionStart, selectionEnd, replacementText);
- }
+ SelectionModel selectionModel = editor.getSelectionModel();
+ if(CodeInsightSettings.getInstance().SURROUND_SELECTION_ON_QUOTE_TYPED && selectionModel.hasSelection() && isDelimiter(c)) {
+ String selectedText = selectionModel.getSelectedText();
+ if (selectedText.length() < 1) {
+ return super.checkAutoPopup(c, project, editor, psiFile);
+ }
+
+ final int selectionStart = selectionModel.getSelectionStart();
+ final int selectionEnd = selectionModel.getSelectionEnd();
+ if (selectedText.length() > 1) {
+ final char firstChar = selectedText.charAt(0);
+ final char lastChar = selectedText.charAt(selectedText.length() - 1);
+ if (isSimilarDelimiters(firstChar, c) && lastChar == getMatchingDelimiter(firstChar) &&
+ (isQuote(firstChar) || firstChar != c) && !shouldSkipReplacementOfQuotesOrBraces(psiFile, editor, selectedText, c) &&
+ selectedText.indexOf(lastChar, 1) == selectedText.length() - 1) {
+ selectedText = selectedText.substring(1, selectedText.length() - 1);
}
- });
+ }
+ final int caretOffset = selectionModel.getSelectionStart();
+ final char c2 = getMatchingDelimiter(c);
+ final String newText = String.valueOf(c) + selectedText + c2;
+ myLtrSelection = selectionModel.getLeadSelectionOffset() != selectionModel.getSelectionEnd();
+ if (editor instanceof EditorEx) {
+ myRestoreStickySelection = ((EditorEx)editor).isStickySelection();
+ }
+ else {
+ myRestoreStickySelection = false;
+ }
+ selectionModel.removeSelection();
+ editor.getDocument().replaceString(selectionStart, selectionEnd, newText);
+ if (Registry.is("editor.smarterSelectionQuoting")) {
+ myReplacedTextRange = new TextRange(caretOffset + 1, caretOffset + newText.length() - 1);
+ } else {
+ myReplacedTextRange = new TextRange(caretOffset, caretOffset + newText.length());
+ }
return Result.STOP;
}
return super.checkAutoPopup(c, project, editor, psiFile);
@@ -136,41 +119,31 @@ public class SelectionQuotingTypedHandler extends TypedHandlerDelegate {
@Override
public Result beforeCharTyped(final char charTyped, final Project project, final Editor editor, final PsiFile file, final FileType fileType) {
// TODO[oleg] remove this hack when API changes
- final Ref<Boolean> caretUpdated = new Ref<Boolean>(Boolean.FALSE);
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- TextRange replacedTextRange = caret.getUserData(REPLACED_TEXT_RANGE);
- caret.putUserData(REPLACED_TEXT_RANGE, null);
- if (replacedTextRange != null) {
- Boolean ltrSelectionBoxed = caret.getUserData(LTR_SELECTION);
- caret.putUserData(LTR_SELECTION, null);
- boolean ltrSelection = ltrSelectionBoxed == null ? false : ltrSelectionBoxed;
- if (replacedTextRange.getEndOffset() <= editor.getDocument().getTextLength()) {
- if (myRestoreStickySelection && editor instanceof EditorEx) {
- EditorEx editorEx = (EditorEx)editor;
- editorEx.setStickySelection(false);
- caret.moveToOffset(ltrSelection ? replacedTextRange.getStartOffset() : replacedTextRange.getEndOffset());
- editorEx.setStickySelection(true);
- caret.moveToOffset(ltrSelection ? replacedTextRange.getEndOffset() : replacedTextRange.getStartOffset());
- }
- else {
- if (ltrSelection || editor instanceof EditorWindow) {
- caret.setSelection(replacedTextRange.getStartOffset(), replacedTextRange.getEndOffset());
- }
- else {
- caret.setSelection(replacedTextRange.getEndOffset(), replacedTextRange.getStartOffset());
- }
- if (Registry.is("editor.smarterSelectionQuoting")) {
- caret.moveToOffset(ltrSelection ? replacedTextRange.getEndOffset() : replacedTextRange.getStartOffset());
- }
- }
+ if (myReplacedTextRange != null) {
+ if (myReplacedTextRange.getEndOffset() <= editor.getDocument().getTextLength()) {
+ if (myRestoreStickySelection && editor instanceof EditorEx) {
+ EditorEx editorEx = (EditorEx)editor;
+ CaretModel caretModel = editorEx.getCaretModel();
+ caretModel.moveToOffset(myLtrSelection ? myReplacedTextRange.getStartOffset() : myReplacedTextRange.getEndOffset());
+ editorEx.setStickySelection(true);
+ caretModel.moveToOffset(myLtrSelection ? myReplacedTextRange.getEndOffset() : myReplacedTextRange.getStartOffset());
+ }
+ else {
+ if (myLtrSelection || editor instanceof EditorWindow) {
+ editor.getSelectionModel().setSelection(myReplacedTextRange.getStartOffset(), myReplacedTextRange.getEndOffset());
+ }
+ else {
+ editor.getSelectionModel().setSelection(myReplacedTextRange.getEndOffset(), myReplacedTextRange.getStartOffset());
+ }
+ if (Registry.is("editor.smarterSelectionQuoting")) {
+ editor.getCaretModel().moveToOffset(myLtrSelection ? myReplacedTextRange.getEndOffset() : myReplacedTextRange.getStartOffset());
}
- caretUpdated.set(Boolean.TRUE);
}
}
- });
- return caretUpdated.get() ? Result.STOP : Result.CONTINUE;
+ myReplacedTextRange = null;
+ return Result.STOP;
+ }
+ return Result.CONTINUE;
}
public static abstract class DequotingFilter {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
index 5bda686334ee..bb21eac69ecd 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
@@ -32,6 +32,7 @@ import com.intellij.lang.ParserDefinition;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
@@ -131,110 +132,116 @@ public class TypedHandler extends TypedActionHandlerBase {
}
@Override
- public void execute(@NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) {
- Project project = CommonDataKeys.PROJECT.getData(dataContext);
- PsiFile file;
+ public void execute(@NotNull final Editor originalEditor, final char charTyped, @NotNull final DataContext dataContext) {
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ final PsiFile originalFile;
- if (project == null || editor.isColumnMode() || (file = PsiUtilBase.getPsiFileInEditor(editor, project)) == null) {
+ if (project == null || (originalFile = PsiUtilBase.getPsiFileInEditor(originalEditor, project)) == null) {
if (myOriginalHandler != null){
- myOriginalHandler.execute(editor, charTyped, dataContext);
+ myOriginalHandler.execute(originalEditor, charTyped, dataContext);
}
return;
}
- if (!CodeInsightUtilBase.prepareEditorForWrite(editor)) return;
- if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
+ if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor)) return;
+ if (!FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
return;
}
- Editor originalEditor = editor;
- Editor injectedEditor = injectedEditorIfCharTypedIsSignificant(charTyped, editor, file);
- if (injectedEditor != editor) {
- file = PsiDocumentManager.getInstance(project).getPsiFile(injectedEditor.getDocument());
- editor = injectedEditor;
- }
+ originalEditor.getCaretModel().runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ PsiDocumentManager.getInstance(project)
+ .doPostponedOperationsAndUnblockDocument(originalEditor.getDocument()); // to clean up after previous caret processing
- final TypedHandlerDelegate[] delegates = Extensions.getExtensions(TypedHandlerDelegate.EP_NAME);
+ Editor editor = injectedEditorIfCharTypedIsSignificant(charTyped, originalEditor, originalFile);
+ PsiFile file = editor == originalEditor ? originalFile : PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
- boolean handled = false;
- for(TypedHandlerDelegate delegate: delegates) {
- final TypedHandlerDelegate.Result result = delegate.checkAutoPopup(charTyped, project, editor, file);
- handled = result == TypedHandlerDelegate.Result.STOP;
- if (result != TypedHandlerDelegate.Result.CONTINUE) {
- break;
- }
- }
- if (!handled) {
- autoPopupCompletion(editor, charTyped, project, file);
- autoPopupParameterInfo(editor, charTyped, project, file);
- }
+ final TypedHandlerDelegate[] delegates = Extensions.getExtensions(TypedHandlerDelegate.EP_NAME);
- if (!editor.isInsertMode()){
- if (myOriginalHandler != null) {
- myOriginalHandler.execute(originalEditor, charTyped, dataContext);
- }
- return;
- }
+ boolean handled = false;
+ for (TypedHandlerDelegate delegate : delegates) {
+ final TypedHandlerDelegate.Result result = delegate.checkAutoPopup(charTyped, project, editor, file);
+ handled = result == TypedHandlerDelegate.Result.STOP;
+ if (result != TypedHandlerDelegate.Result.CONTINUE) {
+ break;
+ }
+ }
- EditorModificationUtil.deleteSelectedTextForAllCarets(editor);
+ if (!handled) {
+ autoPopupCompletion(editor, charTyped, project, file);
+ autoPopupParameterInfo(editor, charTyped, project, file);
+ }
- FileType fileType = getFileType(file, editor);
+ if (!editor.isInsertMode()) {
+ type(originalEditor, charTyped);
+ return;
+ }
- for(TypedHandlerDelegate delegate: delegates) {
- final TypedHandlerDelegate.Result result = delegate.beforeCharTyped(charTyped, project, editor, file, fileType);
- if (result == TypedHandlerDelegate.Result.STOP) {
- return;
- }
- if (result == TypedHandlerDelegate.Result.DEFAULT) {
- break;
- }
- }
+ EditorModificationUtil.deleteSelectedText(editor);
+
+ FileType fileType = getFileType(file, editor);
- if (!editor.getSelectionModel().hasBlockSelection()) {
- if (')' == charTyped || ']' == charTyped || '}' == charTyped) {
- if (FileTypes.PLAIN_TEXT != fileType) {
- if (handleRParen(editor, fileType, charTyped)) return;
+ for (TypedHandlerDelegate delegate : delegates) {
+ final TypedHandlerDelegate.Result result = delegate.beforeCharTyped(charTyped, project, editor, file, fileType);
+ if (result == TypedHandlerDelegate.Result.STOP) {
+ return;
+ }
+ if (result == TypedHandlerDelegate.Result.DEFAULT) {
+ break;
+ }
}
- }
- else if ('"' == charTyped || '\'' == charTyped || '`' == charTyped/* || '/' == charTyped*/) {
- if (handleQuote(editor, charTyped, dataContext, file)) return;
- }
- }
- long modificationStampBeforeTyping = editor.getDocument().getModificationStamp();
- if (myOriginalHandler != null) {
- myOriginalHandler.execute(originalEditor, charTyped, dataContext);
- }
- AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStampBeforeTyping);
+ if (!editor.getSelectionModel().hasBlockSelection()) {
+ if (')' == charTyped || ']' == charTyped || '}' == charTyped) {
+ if (FileTypes.PLAIN_TEXT != fileType) {
+ if (handleRParen(editor, fileType, charTyped)) return;
+ }
+ }
+ else if ('"' == charTyped || '\'' == charTyped || '`' == charTyped/* || '/' == charTyped*/) {
+ if (handleQuote(editor, charTyped, dataContext, file)) return;
+ }
+ }
- if (('(' == charTyped || '[' == charTyped || '{' == charTyped) &&
- CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
- !editor.getSelectionModel().hasBlockSelection() && fileType != FileTypes.PLAIN_TEXT) {
- handleAfterLParen(editor, fileType, charTyped);
- }
- else if ('}' == charTyped) {
- indentClosingBrace(project, editor);
- }
- else if (')' == charTyped) {
- indentClosingParenth(project, editor);
- }
+ long modificationStampBeforeTyping = editor.getDocument().getModificationStamp();
+ type(originalEditor, charTyped);
+ AutoHardWrapHandler.getInstance().wrapLineIfNecessary(editor, dataContext, modificationStampBeforeTyping);
- for(TypedHandlerDelegate delegate: delegates) {
- final TypedHandlerDelegate.Result result = delegate.charTyped(charTyped, project, editor, file);
- if (result == TypedHandlerDelegate.Result.STOP) {
- return;
- }
- if (result == TypedHandlerDelegate.Result.DEFAULT) {
- break;
+ if (('(' == charTyped || '[' == charTyped || '{' == charTyped) &&
+ CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET &&
+ !editor.getSelectionModel().hasBlockSelection() && fileType != FileTypes.PLAIN_TEXT) {
+ handleAfterLParen(editor, fileType, charTyped);
+ }
+ else if ('}' == charTyped) {
+ indentClosingBrace(project, editor);
+ }
+ else if (')' == charTyped) {
+ indentClosingParenth(project, editor);
+ }
+
+ for (TypedHandlerDelegate delegate : delegates) {
+ final TypedHandlerDelegate.Result result = delegate.charTyped(charTyped, project, editor, file);
+ if (result == TypedHandlerDelegate.Result.STOP) {
+ return;
+ }
+ if (result == TypedHandlerDelegate.Result.DEFAULT) {
+ break;
+ }
+ }
+ if ('{' == charTyped) {
+ indentOpenedBrace(project, editor);
+ }
+ else if ('(' == charTyped) {
+ indentOpenedParenth(project, editor);
+ }
}
- }
- if ('{' == charTyped) {
- indentOpenedBrace(project, editor);
- }
- else if ('(' == charTyped) {
- indentOpenedParenth(project, editor);
- }
+ }, true);
+ }
+
+ private static void type(Editor editor, char charTyped) {
+ CommandProcessor.getInstance().setCurrentCommandName(EditorBundle.message("typing.in.editor.command.name"));
+ EditorModificationUtil.typeInStringAtCaretHonorBlockSelection(editor, String.valueOf(charTyped), true);
}
private static void autoPopupParameterInfo(@NotNull Editor editor, char charTyped, @NotNull Project project, @NotNull PsiFile file) {
@@ -288,7 +295,7 @@ public class TypedHandler extends TypedActionHandlerBase {
}
@NotNull
- static Editor injectedEditorIfCharTypedIsSignificant(final char charTyped, @NotNull Editor editor, @NotNull PsiFile oldFile) {
+ public static Editor injectedEditorIfCharTypedIsSignificant(final char charTyped, @NotNull Editor editor, @NotNull PsiFile oldFile) {
int offset = editor.getCaretModel().getOffset();
// even for uncommitted document try to retrieve injected fragment that has been there recently
// we are assuming here that when user is (even furiously) typing, injected language would not change
@@ -361,12 +368,7 @@ public class TypedHandler extends TypedActionHandlerBase {
else {
throw new AssertionError("Unknown char "+lparenChar);
}
- if (editor.getCaretModel().supportsMultipleCarets()) {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, text, 0);
- }
- else {
- editor.getDocument().insertString(offset, text);
- }
+ editor.getDocument().insertString(offset, text);
}
}
@@ -422,7 +424,7 @@ public class TypedHandler extends TypedActionHandlerBase {
if (!matched) return false;
- EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
+ EditorModificationUtil.moveCaretRelatively(editor, 1);
return true;
}
@@ -440,7 +442,7 @@ public class TypedHandler extends TypedActionHandlerBase {
if (offset < length && chars.charAt(offset) == quote){
if (isClosingQuote(editor, quoteHandler, offset)){
- EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
+ EditorModificationUtil.moveCaretRelatively(editor, 1);
return true;
}
}
@@ -459,9 +461,7 @@ public class TypedHandler extends TypedActionHandlerBase {
}
}
- if (myOriginalHandler != null) {
- myOriginalHandler.execute(editor, quote, dataContext);
- }
+ type(editor, quote);
offset = editor.getCaretModel().getOffset();
if (quoteHandler instanceof MultiCharQuoteHandler) {
@@ -469,12 +469,7 @@ public class TypedHandler extends TypedActionHandlerBase {
if (closingQuote != null && hasNonClosedLiterals(editor, quoteHandler, offset - 1)) {
if (offset == document.getTextLength() ||
!Character.isUnicodeIdentifierPart(document.getCharsSequence().charAt(offset))) { //any better heuristic or an API?
- if (editor.getCaretModel().supportsMultipleCarets()) {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, closingQuote.toString(), 0);
- }
- else {
- document.insertString(offset, closingQuote);
- }
+ document.insertString(offset, closingQuote);
return true;
}
}
@@ -483,12 +478,7 @@ public class TypedHandler extends TypedActionHandlerBase {
if (isOpeningQuote(editor, quoteHandler, offset - 1) && hasNonClosedLiterals(editor, quoteHandler, offset - 1)) {
if (offset == document.getTextLength() ||
!Character.isUnicodeIdentifierPart(document.getCharsSequence().charAt(offset))) { //any better heuristic or an API?
- if (editor.getCaretModel().supportsMultipleCarets()) {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, String.valueOf(quote), 0);
- }
- else {
- document.insertString(offset, String.valueOf(quote));
- }
+ document.insertString(offset, String.valueOf(quote));
}
}
@@ -573,72 +563,67 @@ public class TypedHandler extends TypedActionHandlerBase {
}
private static void indentBrace(@NotNull final Project project, @NotNull final Editor editor, final char braceChar) {
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- final int offset = editor.getCaretModel().getOffset() - 1;
- final Document document = editor.getDocument();
- CharSequence chars = document.getCharsSequence();
- if (offset < 0 || chars.charAt(offset) != braceChar) return;
-
- int spaceStart = CharArrayUtil.shiftBackward(chars, offset - 1, " \t");
- if (spaceStart < 0 || chars.charAt(spaceStart) == '\n' || chars.charAt(spaceStart) == '\r'){
- PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
- documentManager.commitDocument(document);
-
- final PsiFile file = documentManager.getPsiFile(document);
- if (file == null || !file.isWritable()) return;
- PsiElement element = file.findElementAt(offset);
- if (element == null) return;
-
- EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter();
- HighlighterIterator iterator = highlighter.createIterator(offset);
-
- final FileType fileType = file.getFileType();
- BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator);
- boolean rBraceToken = braceMatcher.isRBraceToken(iterator, chars, fileType);
- final boolean isBrace = braceMatcher.isLBraceToken(iterator, chars, fileType) || rBraceToken;
- int lBraceOffset = -1;
-
- if (CodeInsightSettings.getInstance().REFORMAT_BLOCK_ON_RBRACE &&
- rBraceToken &&
- braceMatcher.isStructuralBrace(iterator, chars, fileType) && offset > 0) {
- lBraceOffset = BraceMatchingUtil.findLeftLParen(
- highlighter.createIterator(offset - 1),
- braceMatcher.getOppositeBraceTokenType(iterator.getTokenType()),
- editor.getDocument().getCharsSequence(),
- fileType
- );
- }
- if (element.getNode() != null && isBrace) {
- final int finalLBraceOffset = lBraceOffset;
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run(){
- try{
- int newOffset;
- if (finalLBraceOffset != -1) {
- RangeMarker marker = document.createRangeMarker(offset, offset + 1);
- CodeStyleManager.getInstance(project).reformatRange(file, finalLBraceOffset, offset, true);
- newOffset = marker.getStartOffset();
- marker.dispose();
- } else {
- newOffset = CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
- }
-
- editor.getCaretModel().moveToOffset(newOffset + 1);
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
- editor.getSelectionModel().removeSelection();
- }
- catch(IncorrectOperationException e){
- LOG.error(e);
- }
+ final int offset = editor.getCaretModel().getOffset() - 1;
+ final Document document = editor.getDocument();
+ CharSequence chars = document.getCharsSequence();
+ if (offset < 0 || chars.charAt(offset) != braceChar) return;
+
+ int spaceStart = CharArrayUtil.shiftBackward(chars, offset - 1, " \t");
+ if (spaceStart < 0 || chars.charAt(spaceStart) == '\n' || chars.charAt(spaceStart) == '\r'){
+ PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
+ documentManager.commitDocument(document);
+
+ final PsiFile file = documentManager.getPsiFile(document);
+ if (file == null || !file.isWritable()) return;
+ PsiElement element = file.findElementAt(offset);
+ if (element == null) return;
+
+ EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter();
+ HighlighterIterator iterator = highlighter.createIterator(offset);
+
+ final FileType fileType = file.getFileType();
+ BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator);
+ boolean rBraceToken = braceMatcher.isRBraceToken(iterator, chars, fileType);
+ final boolean isBrace = braceMatcher.isLBraceToken(iterator, chars, fileType) || rBraceToken;
+ int lBraceOffset = -1;
+
+ if (CodeInsightSettings.getInstance().REFORMAT_BLOCK_ON_RBRACE &&
+ rBraceToken &&
+ braceMatcher.isStructuralBrace(iterator, chars, fileType) && offset > 0) {
+ lBraceOffset = BraceMatchingUtil.findLeftLParen(
+ highlighter.createIterator(offset - 1),
+ braceMatcher.getOppositeBraceTokenType(iterator.getTokenType()),
+ editor.getDocument().getCharsSequence(),
+ fileType
+ );
+ }
+ if (element.getNode() != null && isBrace) {
+ final int finalLBraceOffset = lBraceOffset;
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run(){
+ try{
+ int newOffset;
+ if (finalLBraceOffset != -1) {
+ RangeMarker marker = document.createRangeMarker(offset, offset + 1);
+ CodeStyleManager.getInstance(project).reformatRange(file, finalLBraceOffset, offset, true);
+ newOffset = marker.getStartOffset();
+ marker.dispose();
+ } else {
+ newOffset = CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
}
- });
+
+ editor.getCaretModel().moveToOffset(newOffset + 1);
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ editor.getSelectionModel().removeSelection();
+ }
+ catch(IncorrectOperationException e){
+ LOG.error(e);
+ }
}
- }
+ });
}
- });
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java
index 4f7f3322a05b..7d0b4453c517 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java
@@ -159,17 +159,24 @@ public class FoldingUpdate {
final List<EditorWindow> injectedEditors = new ArrayList<EditorWindow>();
final List<PsiFile> injectedFiles = new ArrayList<PsiFile>();
final List<FoldingMap> maps = new ArrayList<FoldingMap>();
- for (DocumentWindow injectedDocument : injectedDocuments) {
- PsiFile injectedFile = PsiDocumentManager.getInstance(project).getPsiFile(injectedDocument);
- if (injectedFile == null || !injectedFile.isValid() || !injectedDocument.isValid()) continue;
- Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
- if (!(injectedEditor instanceof EditorWindow)) continue;
+ for (final DocumentWindow injectedDocument : injectedDocuments) {
+ if (!injectedDocument.isValid()) {
+ continue;
+ }
+ InjectedLanguageUtil.enumerate(injectedDocument, file, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ @Override
+ public void visit(@NotNull PsiFile injectedFile, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
+ if (!injectedFile.isValid()) return;
+ Editor injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(editor, injectedFile);
+ if (!(injectedEditor instanceof EditorWindow)) return;
- injectedEditors.add((EditorWindow)injectedEditor);
- injectedFiles.add(injectedFile);
- final FoldingMap map = new FoldingMap();
- maps.add(map);
- getFoldingsFor(injectedFile, injectedDocument, map, false);
+ injectedEditors.add((EditorWindow)injectedEditor);
+ injectedFiles.add(injectedFile);
+ final FoldingMap map = new FoldingMap();
+ maps.add(map);
+ getFoldingsFor(injectedFile, injectedDocument, map, false);
+ }
+ });
}
return new Runnable() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
index 1f6f1347f16d..4a7abe355380 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
@@ -295,7 +295,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
.setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
- final BackgroundUpdaterTask task = myTaskRef.get();
+ final BackgroundUpdaterTask task = SoftReference.dereference(myTaskRef);
if (task != null) {
task.setCanceled();
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java
index 6af5890fd4b9..f806287e8076 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java
@@ -26,12 +26,14 @@ import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.ui.ClickListener;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.LightColors;
+import com.intellij.ui.awt.RelativePoint;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -73,7 +75,7 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel {
}
myLabel.setText(description);
- myLabel.setIcon(SeverityRegistrar.getSeverityRegistrar(project).compare(severity, HighlightSeverity.ERROR) >= 0 ? AllIcons.Actions.QuickfixBulb : AllIcons.Actions.IntentionBulb);
+ myGearLabel.setIcon(AllIcons.General.Gear);
new ClickListener() {
@Override
@@ -86,10 +88,13 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel {
step = step.getSubStep(actionWithTextCaching, null);
}
}
- JBPopupFactory.getInstance().createListPopup(step).showUnderneathOf(myLabel);
+ ListPopup popup = JBPopupFactory.getInstance().createListPopup(step);
+ Dimension dimension = popup.getContent().getPreferredSize();
+ Point at = new Point(-dimension.width + myGearLabel.getWidth(), FileLevelIntentionComponent.this.getHeight());
+ popup.show(new RelativePoint(e.getComponent(), at));
return true;
}
- }.installOn(myLabel);
+ }.installOn(myGearLabel);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
index 655d1d44292a..222ddb6062b0 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.ForceableComparable;
import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.Nullable;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
@@ -40,11 +41,12 @@ public class CachingComparingClassifier extends ComparingClassifier<LookupElemen
myWeigher = weigher;
}
+ @Nullable
@Override
- public final Comparable getWeight(LookupElement t) {
- Comparable w = myWeights.get(t);
+ public final Comparable getWeight(LookupElement element, ProcessingContext context) {
+ Comparable w = myWeights.get(element);
if (w == null && myWeigher.isPrefixDependent()) {
- myWeights.put(t, w = myWeigher.weigh(t));
+ myWeights.put(element, w = myWeigher.weigh(element, context.get(CompletionLookupArranger.WEIGHING_CONTEXT)));
}
return w;
}
@@ -74,8 +76,8 @@ public class CachingComparingClassifier extends ComparingClassifier<LookupElemen
}
@Override
- public void addElement(LookupElement t) {
- Comparable weight = myWeigher.weigh(t);
+ public void addElement(LookupElement t, ProcessingContext context) {
+ Comparable weight = myWeigher.weigh(t, context.get(CompletionLookupArranger.WEIGHING_CONTEXT));
if (weight instanceof ForceableComparable) {
((ForceableComparable)weight).force();
}
@@ -87,7 +89,7 @@ public class CachingComparingClassifier extends ComparingClassifier<LookupElemen
}
}
myWeights.put(t, weight);
- super.addElement(t);
+ super.addElement(t, context);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java
index bf5d9169eb41..639b21ee1861 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/Classifier.java
@@ -23,7 +23,7 @@ import java.util.LinkedHashMap;
* @author peter
*/
public abstract class Classifier<T> {
- public abstract void addElement(T t);
+ public abstract void addElement(T t, ProcessingContext context);
public abstract Iterable<T> classify(Iterable<T> source, ProcessingContext context);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ClassifierFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ClassifierFactory.java
index ff78f6474270..125ba79a6561 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ClassifierFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ClassifierFactory.java
@@ -15,10 +15,6 @@
*/
package com.intellij.codeInsight.lookup;
-import com.intellij.util.ProcessingContext;
-
-import java.util.*;
-
/**
* @author peter
*/
@@ -35,23 +31,6 @@ public abstract class ClassifierFactory<T> {
public abstract Classifier<T> createClassifier(Classifier<T> next);
- public static <T> Classifier<T> listClassifier() {
- return new Classifier<T>() {
- @Override
- public void addElement(T t) {
- }
-
- @Override
- public Iterable<T> classify(Iterable<T> source, ProcessingContext context) {
- return source;
- }
-
- @Override
- public void describeItems(LinkedHashMap<T, StringBuilder> map, ProcessingContext context) {
- }
- };
- }
-
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java
index 6715ca6653aa..fc55e2d33637 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java
@@ -43,11 +43,11 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
}
@Nullable
- public abstract Comparable getWeight(T t);
+ public abstract Comparable getWeight(T t, ProcessingContext context);
@Override
- public void addElement(T t) {
- myNext.addElement(t);
+ public void addElement(T t, ProcessingContext context) {
+ myNext.addElement(t, context);
}
@Override
@@ -55,7 +55,7 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
List<T> nulls = null;
TreeMap<Comparable, List<T>> map = new TreeMap<Comparable, List<T>>();
for (T t : source) {
- final Comparable weight = getWeight(t);
+ final Comparable weight = getWeight(t, context);
if (weight == null) {
if (nulls == null) nulls = new SmartList<T>();
nulls.add(t);
@@ -89,7 +89,7 @@ public abstract class ComparingClassifier<T> extends Classifier<T> {
public void describeItems(LinkedHashMap<T, StringBuilder> map, ProcessingContext context) {
Map<T, String> weights = new IdentityHashMap<T, String>();
for (T t : map.keySet()) {
- weights.put(t, String.valueOf(getWeight(t)));
+ weights.put(t, String.valueOf(getWeight(t, context)));
}
if (new HashSet<String>(weights.values()).size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) {
for (T t : map.keySet()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java
index 9f02c20b388d..082d68bc68d1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/LookupArranger.java
@@ -118,7 +118,7 @@ public abstract class LookupArranger {
List<LookupElement> items = getMatchingItems();
for (LookupElement item : items) {
- if (CompletionServiceImpl.isStartMatch(item, lookup)) {
+ if (CompletionServiceImpl.isStartMatch(item, (LookupImpl)lookup)) {
result.add(item);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
index e776b30b7f98..284a8ecb85bf 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
@@ -19,6 +19,7 @@ package com.intellij.codeInsight.lookup.impl;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.codeInsight.lookup.*;
@@ -45,6 +46,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.DebugUtil;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
@@ -70,7 +72,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public class LookupImpl extends LightweightHint implements LookupEx, Disposable {
+public class LookupImpl extends LightweightHint implements LookupEx, Disposable, WeighingContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupImpl");
private final LookupOffsets myOffsets;
@@ -78,7 +80,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private final Editor myEditor;
private final JBList myList = new JBList(new CollectionListModel<LookupElement>()) {
@Override
- protected void processKeyEvent(final KeyEvent e) {
+ protected void processKeyEvent(@NotNull final KeyEvent e) {
final char keyChar = e.getKeyChar();
if (keyChar == KeyEvent.VK_ENTER || keyChar == KeyEvent.VK_TAB) {
IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), true).doWhenDone(new Runnable() {
@@ -224,12 +226,12 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
public boolean addItem(LookupElement item, PrefixMatcher matcher) {
LookupElementPresentation presentation = renderItemApproximately(item);
- if (containsDummyIdentifier(presentation.getItemText()) ||
- containsDummyIdentifier(presentation.getTailText()) ||
+ if (containsDummyIdentifier(presentation.getItemText()) ||
+ containsDummyIdentifier(presentation.getTailText()) ||
containsDummyIdentifier(presentation.getTypeText())) {
return false;
}
-
+
myMatchers.put(item, matcher);
updateLookupWidth(item, presentation);
synchronized (myList) {
@@ -326,17 +328,17 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
return;
}
- // selected item should be at the top of the visible list
+ // selected item should be at the top of the visible list
int top = myList.getSelectedIndex();
if (top > 0) {
top--; // show one element above the selected one to give the hint that there are more available via scrolling
}
-
+
int firstVisibleIndex = myList.getFirstVisibleIndex();
if (firstVisibleIndex == top) {
return;
}
-
+
ListScrollingUtil.ensureRangeIsVisible(myList, top, top + myList.getLastVisibleIndex() - firstVisibleIndex);
}
@@ -558,23 +560,24 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
myEditor.getSelectionModel().setBlockSelection(start, end);
myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine, end.column));
} else {
- myEditor.getCaretModel().runForEachCaret(new CaretAction() {
+ final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor);
+ hostEditor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
public void perform(Caret caret) {
- EditorModificationUtil.deleteSelectedText(myEditor);
- final int caretOffset = myEditor.getCaretModel().getOffset();
+ EditorModificationUtil.deleteSelectedText(hostEditor);
+ final int caretOffset = hostEditor.getCaretModel().getOffset();
int lookupStart = caretOffset - prefix;
- int len = document.getTextLength();
+ int len = hostEditor.getDocument().getTextLength();
LOG.assertTrue(lookupStart >= 0 && lookupStart <= len,
"ls: " + lookupStart + " caret: " + caretOffset + " prefix:" + prefix + " doc: " + len);
LOG.assertTrue(caretOffset >= 0 && caretOffset <= len, "co: " + caretOffset + " doc: " + len);
- document.replaceString(lookupStart, caretOffset, lookupString);
+ hostEditor.getDocument().replaceString(lookupStart, caretOffset, lookupString);
int offset = lookupStart + lookupString.length();
- myEditor.getCaretModel().moveToOffset(offset);
- myEditor.getSelectionModel().removeSelection();
+ hostEditor.getCaretModel().moveToOffset(offset);
+ hostEditor.getSelectionModel().removeSelection();
}
});
}
@@ -590,7 +593,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
final String prefix = itemPattern(item);
final int length = prefix.length();
- if (length == 0 || !StringUtil.startsWithIgnoreCase(lookupString, prefix)) return lookupString;
+ if (length == 0 || !itemMatcher(item).prefixMatches(prefix)) return lookupString;
boolean isAllLower = true;
boolean isAllUpper = true;
boolean sameCase = true;
@@ -694,6 +697,8 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
return false;
}
+ DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(this);
+
LOG.assertTrue(myList.isShowing(), "!showing, disposed=" + myDisposed);
return true;
@@ -771,7 +776,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private LookupElement oldItem = null;
@Override
- public void valueChanged(ListSelectionEvent e){
+ public void valueChanged(@NotNull ListSelectionEvent e){
final LookupElement item = getCurrentItem();
if (oldItem != item && !myList.isEmpty()) { // do not update on temporary model wipe
fireCurrentItemChanged(item);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java
index 098b7e14474b..98f09a71f940 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupManagerImpl.java
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.CompletionProcess;
import com.intellij.codeInsight.completion.CompletionService;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
-import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.codeInsight.hint.EditorHintListener;
import com.intellij.codeInsight.hint.HintManager;
@@ -134,7 +133,6 @@ public class LookupManagerImpl extends LookupManager {
final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
final LookupImpl lookup = new LookupImpl(myProject, editor, arranger);
- DaemonCodeAnalyzer.getInstance(myProject).disableUpdateByTimer(lookup);
final Alarm alarm = new Alarm();
final Runnable request = new Runnable() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupOffsets.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupOffsets.java
index 28d3aff18665..fe53f1796dbd 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupOffsets.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupOffsets.java
@@ -51,10 +51,7 @@ public class LookupOffsets {
private void updateLookupStart(int minPrefixLength) {
int offset = getPivotOffset();
int start = offset - minPrefixLength - myAdditionalPrefix.length() + myRemovedPrefix;
- if (start < 0) {
- LOG.error("Invalid start offset: o=" + offset + ", mpl=" + minPrefixLength + ", ap=" + myAdditionalPrefix + ", rp=" + myRemovedPrefix);
- return;
- }
+ start = Math.max(Math.min(start, myEditor.getDocument().getTextLength()), 0);
if (myLookupStartMarker != null) {
if (myLookupStartMarker.isValid() && myLookupStartMarker.getStartOffset() == start && myLookupStartMarker.getEndOffset() == start) {
return;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
index 9d8c67938907..b13bbb4be33e 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupTypedHandler.java
@@ -17,62 +17,99 @@
package com.intellij.codeInsight.lookup.impl;
import com.intellij.codeInsight.AutoPopupController;
+import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.completion.CodeCompletionFeatures;
+import com.intellij.codeInsight.completion.CompletionPhase;
import com.intellij.codeInsight.completion.CompletionProgressIndicator;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
import com.intellij.codeInsight.editorActions.AutoHardWrapHandler;
import com.intellij.codeInsight.editorActions.TypedHandler;
-import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
import com.intellij.codeInsight.lookup.CharFilter;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.actions.ChooseItemAction;
import com.intellij.codeInsight.template.impl.TemplateSettings;
+import com.intellij.codeInsight.template.impl.editorActions.TypedActionHandlerBase;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
+import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilBase;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
-public class LookupTypedHandler extends TypedHandlerDelegate {
+public class LookupTypedHandler extends TypedActionHandlerBase {
+
+ public LookupTypedHandler(@Nullable TypedActionHandler originalHandler) {
+ super(originalHandler);
+ }
- @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
@Override
- public Result beforeCharTyped(final char charTyped,
+ public void execute(@NotNull Editor originalEditor, char charTyped, @NotNull DataContext dataContext) {
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ PsiFile file;
+
+ if (project == null
+ || (file = PsiUtilBase.getPsiFileInEditor(originalEditor, project)) == null
+ || !CodeInsightUtilBase.prepareEditorForWrite(originalEditor)
+ || !FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
+ if (myOriginalHandler != null){
+ myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ }
+ return;
+ }
+
+ CompletionPhase oldPhase = CompletionServiceImpl.getCompletionPhase();
+ if (oldPhase instanceof CompletionPhase.CommittingDocuments && ((CompletionPhase.CommittingDocuments)oldPhase).isRestartingCompletion()) {
+ assert oldPhase.indicator != null;
+ oldPhase.indicator.scheduleRestart();
+ }
+
+ Editor editor = TypedHandler.injectedEditorIfCharTypedIsSignificant(charTyped, originalEditor, file);
+ if (editor != originalEditor) {
+ file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+ }
+
+ if (originalEditor.isInsertMode() && beforeCharTyped(charTyped, project, originalEditor, editor, file)) {
+ return;
+ }
+
+ if (myOriginalHandler != null) {
+ myOriginalHandler.execute(originalEditor, charTyped, dataContext);
+ }
+ }
+
+ private static boolean beforeCharTyped(final char charTyped,
Project project,
+ final Editor originalEditor,
final Editor editor,
- PsiFile file,
- FileType fileType) {
- final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
+ PsiFile file) {
+ final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(originalEditor);
if (lookup == null){
- return Result.CONTINUE;
+ return false;
}
if (charTyped == ' ' && ChooseItemAction.hasTemplatePrefix(lookup, TemplateSettings.SPACE_CHAR)) {
- return Result.CONTINUE;
+ return false;
}
final CharFilter.Result result = getLookupAction(charTyped, lookup);
if (lookup.isLookupDisposed()) {
- return Result.CONTINUE;
+ return false;
}
- if (!lookup.performGuardedChange(new Runnable() {
- @Override
- public void run() {
- EditorModificationUtil.deleteSelectedText(editor);
- }
- })) {
- return Result.STOP;
- }
if (result == CharFilter.Result.ADD_TO_PREFIX) {
Document document = editor.getDocument();
long modificationStamp = document.getModificationStamp();
@@ -80,10 +117,10 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
if (!lookup.performGuardedChange(new Runnable() {
@Override
public void run() {
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, String.valueOf(charTyped), true);
+ EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(originalEditor, String.valueOf(charTyped), true);
}
})) {
- return Result.STOP;
+ return true;
}
lookup.appendPrefix(charTyped);
if (lookup.isStartCompletionWhenNothingMatches() && lookup.getItems().isEmpty()) {
@@ -101,25 +138,25 @@ public class LookupTypedHandler extends TypedHandlerDelegate {
if (completion != null) {
completion.prefixUpdated();
}
- return Result.STOP;
+ return true;
}
if (result == CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP && lookup.isFocused()) {
LookupElement item = lookup.getCurrentItem();
if (item != null) {
if (completeTillTypedCharOccurrence(charTyped, lookup, item)) {
- return Result.STOP;
+ return true;
}
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_DOT_ETC);
lookup.finishLookup(charTyped);
- return Result.STOP;
+ return true;
}
}
lookup.hide();
TypedHandler.autoPopupCompletion(editor, charTyped, project, file);
- return Result.CONTINUE;
+ return false;
}
private static boolean completeTillTypedCharOccurrence(char charTyped, LookupImpl lookup, LookupElement item) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java
index c1f2c6a89ab1..b1b0c8434ebb 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java
@@ -377,18 +377,18 @@ class LookupUi {
myScrollBarIncreaseButton.setPreferredSize(buttonSize);
myScrollBarIncreaseButton.setMinimumSize(buttonSize);
myScrollBarIncreaseButton.setMaximumSize(buttonSize);
- JScrollBar scrollBar = myScrollPane.getVerticalScrollBar();
- scrollBar.revalidate();
- scrollBar.repaint();
-
+ JScrollBar vScrollBar = myScrollPane.getVerticalScrollBar();
+ vScrollBar.revalidate();
+ vScrollBar.repaint();
+
final Dimension iconSize = myProcessIcon.getPreferredSize();
- myIconPanel.setBounds(getWidth() - iconSize.width - (scrollBar.isVisible() ? scrollBar.getWidth() : 0), 0, iconSize.width, iconSize.height);
+ myIconPanel.setBounds(getWidth() - iconSize.width - (vScrollBar.isVisible() ? vScrollBar.getWidth() : 0), 0, iconSize.width,
+ iconSize.height);
final Dimension sortSize = mySortingLabel.getPreferredSize();
- final Point sbLocation = SwingUtilities.convertPoint(scrollBar, 0, 0, myLayeredPane);
-
- final int sortHeight = Math.max(adHeight, mySortingLabel.getPreferredSize().height);
- mySortingLabel.setBounds(sbLocation.x, getHeight() - sortHeight, sortSize.width, sortHeight);
+ final int sortWidth = vScrollBar.isVisible() ? vScrollBar.getWidth() : sortSize.width;
+ final int sortHeight = Math.max(sortSize.height, adHeight);
+ mySortingLabel.setBounds(getWidth() - sortWidth, getHeight() - sortHeight, sortSize.width, sortHeight);
}
void layoutHint() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
index e31d6266759f..3666b4642efd 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
@@ -909,7 +909,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
TextAttributes attributes = myEditorColorsManager.getGlobalScheme().getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR);
for (TextRange range : info.getRanges()) {
- TextAttributes attr = patchAttributesColor(attributes, range, editor);
+ TextAttributes attr = NavigationUtil.patchAttributesColor(attributes, range, editor);
final RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getEndOffset(),
HighlighterLayer.SELECTION + 1,
attr,
@@ -921,32 +921,6 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
}
- /**
- * Patches attributes to be visible under debugger active line
- */
- @SuppressWarnings("UseJBColor")
- private static TextAttributes patchAttributesColor(TextAttributes attributes, TextRange range, Editor editor) {
- int line = editor.offsetToLogicalPosition(range.getStartOffset()).line;
- for (RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) {
- if (!highlighter.isValid()) continue;
- if (highlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE &&
- editor.offsetToLogicalPosition(highlighter.getStartOffset()).line == line) {
- TextAttributes textAttributes = highlighter.getTextAttributes();
- if (textAttributes != null) {
- Color color = textAttributes.getBackgroundColor();
- if (color != null && color.getBlue() > 128 && color.getRed() < 128 && color.getGreen() < 128) {
- TextAttributes clone = attributes.clone();
- clone.setForegroundColor(Color.orange);
- clone.setEffectColor(Color.orange);
- return clone;
- }
- }
- }
- }
- return attributes;
- }
-
-
private class HighlightersSet {
private final List<RangeHighlighter> myHighlighters;
private final Editor myHighlighterView;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoImplementationHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoImplementationHandler.java
index 5dab573a1dd1..570d672daad4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoImplementationHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoImplementationHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -44,7 +44,7 @@ public class GotoImplementationHandler extends GotoTargetHandler {
@Override
@Nullable
- public GotoData getSourceAndTargetElements(Editor editor, PsiFile file) {
+ public GotoData getSourceAndTargetElements(@NotNull Editor editor, PsiFile file) {
int offset = editor.getCaretModel().getOffset();
PsiElement source = TargetElementUtilBase.getInstance().findTargetElement(editor, ImplementationSearcher.getFlags(), offset);
if (source == null) return null;
@@ -83,18 +83,21 @@ public class GotoImplementationHandler extends GotoTargetHandler {
return gotoData;
}
+ @NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
return CodeInsightBundle.message("goto.implementation.chooserTitle", name, length);
}
+ @NotNull
@Override
protected String getFindUsagesTitle(PsiElement sourceElement, String name, int length) {
return CodeInsightBundle.message("goto.implementation.findUsages.title", name, length);
}
+ @NotNull
@Override
- protected String getNotFoundMessage(Project project, Editor editor, PsiFile file) {
+ protected String getNotFoundMessage(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
return CodeInsightBundle.message("goto.implementation.notFound");
}
@@ -105,7 +108,7 @@ public class GotoImplementationHandler extends GotoTargetHandler {
private final Map<Object, PsiElementListCellRenderer> renderers = new HashMap<Object, PsiElementListCellRenderer>();
private final PsiReference myReference;
- public ImplementationsUpdaterTask(GotoData gotoData, Editor editor, int offset, final PsiReference reference) {
+ public ImplementationsUpdaterTask(@NotNull GotoData gotoData, @NotNull Editor editor, int offset, final PsiReference reference) {
super(gotoData.source.getProject(), ImplementationSearcher.SEARCHING_FOR_IMPLEMENTATIONS);
myEditor = editor;
myOffset = offset;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
index ca970d93e49e..6ef571f62a03 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -86,10 +86,10 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
@Nullable
protected abstract GotoData getSourceAndTargetElements(Editor editor, PsiFile file);
- private void show(final Project project,
- Editor editor,
- final PsiFile file,
- final GotoData gotoData) {
+ private void show(@NotNull final Project project,
+ @NotNull Editor editor,
+ @NotNull PsiFile file,
+ @NotNull final GotoData gotoData) {
final PsiElement[] targets = gotoData.targets;
final List<AdditionalAction> additionalActions = gotoData.additionalActions;
@@ -250,18 +250,23 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
return true;
}
+ @NotNull
protected abstract String getChooserTitle(PsiElement sourceElement, String name, int length);
+ @NotNull
protected String getFindUsagesTitle(PsiElement sourceElement, String name, int length) {
return getChooserTitle(sourceElement, name, length);
}
- protected abstract String getNotFoundMessage(Project project, Editor editor, PsiFile file);
+ @NotNull
+ protected abstract String getNotFoundMessage(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file);
+
@Nullable
protected String getAdText(PsiElement source, int length) {
return null;
}
public interface AdditionalAction {
+ @NotNull
String getText();
Icon getIcon();
@@ -270,7 +275,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
}
public static class GotoData {
- public final PsiElement source;
+ @NotNull public final PsiElement source;
public PsiElement[] targets;
public final List<AdditionalAction> additionalActions;
@@ -279,7 +284,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
protected final Set<String> myNames;
public Map<Object, PsiElementListCellRenderer> renderers = new HashMap<Object, PsiElementListCellRenderer>();
- public GotoData(PsiElement source, PsiElement[] targets, List<AdditionalAction> additionalActions) {
+ public GotoData(@NotNull PsiElement source, @NotNull PsiElement[] targets, @NotNull List<AdditionalAction> additionalActions) {
this.source = source;
this.targets = targets;
this.additionalActions = additionalActions;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
index 0e49f28ec76e..504ec1b13c41 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -38,6 +38,7 @@ public class ImplementationSearcher {
public static final String SEARCHING_FOR_IMPLEMENTATIONS = CodeInsightBundle.message("searching.for.implementations");
+ @NotNull
public PsiElement[] searchImplementations(final Editor editor, final PsiElement element, final int offset) {
final TargetElementUtilBase targetElementUtil = TargetElementUtilBase.getInstance();
boolean onRef = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@@ -49,7 +50,7 @@ public class ImplementationSearcher {
return searchImplementations(element, editor, offset, onRef && ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return targetElementUtil.includeSelfInGotoImplementation(element);
+ return element == null || targetElementUtil.includeSelfInGotoImplementation(element);
}
}), onRef);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
index ea6f81066a7a..3c0e84a11656 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
@@ -21,6 +21,9 @@ import com.intellij.ide.util.EditSourceUtil;
import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
@@ -39,6 +42,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
/**
* @author ven
@@ -188,4 +192,32 @@ public final class NavigationUtil {
return false;
}
+
+ /**
+ * Patches attributes to be visible under debugger active line
+ */
+ @SuppressWarnings("UseJBColor")
+ public static TextAttributes patchAttributesColor(TextAttributes attributes, @NotNull TextRange range, @NotNull Editor editor) {
+ int lineStart = editor.offsetToLogicalPosition(range.getStartOffset()).line;
+ int lineEnd = editor.offsetToLogicalPosition(range.getEndOffset()).line;
+ for (RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) {
+ if (!highlighter.isValid()) continue;
+ if (highlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) {
+ int line = editor.offsetToLogicalPosition(highlighter.getStartOffset()).line;
+ if (line >= lineStart && line <= lineEnd) {
+ TextAttributes textAttributes = highlighter.getTextAttributes();
+ if (textAttributes != null) {
+ Color color = textAttributes.getBackgroundColor();
+ if (color != null && color.getBlue() > 128 && color.getRed() < 128 && color.getGreen() < 128) {
+ TextAttributes clone = attributes.clone();
+ clone.setForegroundColor(Color.orange);
+ clone.setEffectColor(Color.orange);
+ return clone;
+ }
+ }
+ }
+ }
+ }
+ return attributes;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java
index 3fd5638e6598..8c63b980019c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
@@ -69,7 +70,7 @@ public class CustomTemplateCallback {
@NotNull
public PsiElement getContext() {
- return getContext(myFile, myOffset);
+ return getContext(myFile, getOffset(), myInInjectedFragment);
}
public int getOffset() {
@@ -140,13 +141,22 @@ public class CustomTemplateCallback {
public void deleteTemplateKey(@NotNull String key) {
int caretAt = myEditor.getCaretModel().getOffset();
- myEditor.getDocument().deleteString(caretAt - key.length(), caretAt);
+ int templateStart = caretAt - key.length();
+ myEditor.getDocument().deleteString(templateStart, caretAt);
+ myEditor.getCaretModel().moveToOffset(templateStart);
+ myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ myEditor.getSelectionModel().removeSelection();
}
@NotNull
public static PsiElement getContext(@NotNull PsiFile file, int offset) {
+ return getContext(file, offset, true);
+ }
+
+ @NotNull
+ public static PsiElement getContext(@NotNull PsiFile file, int offset, boolean searchInInjectedFragment) {
PsiElement element = null;
- if (!InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) {
+ if (searchInInjectedFragment && !InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) {
element = InjectedLanguageUtil.findInjectedElementNoCommit(file, offset);
}
if (element == null) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java
index 15c60f5e4e3f..512bfa1b27fb 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java
@@ -100,7 +100,7 @@ public class LiveTemplateBuilder {
int endOffset = -1;
Iterator<VarOccurence> it = myVariableOccurrences.iterator();
while (it.hasNext()) {
- VarOccurence occurence = it.next();
+ VarOccurence occurence = it.next();
if (occurence.myName.equals(myLastEndVarName)) {
endOffset = occurence.myOffset;
break;
@@ -126,7 +126,7 @@ public class LiveTemplateBuilder {
List<VarOccurence> variableOccurrences = getListWithLimit(myVariableOccurrences);
Collections.sort(variableOccurrences, new Comparator<VarOccurence>() {
@Override
- public int compare(VarOccurence o1, VarOccurence o2) {
+ public int compare(@NotNull VarOccurence o1, @NotNull VarOccurence o2) {
if (o1.myOffset < o2.myOffset) {
return -1;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
index 1031e0a42fc0..e0b89d73fae0 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
@@ -296,8 +296,16 @@ public class TemplateManagerImpl extends TemplateManager implements Disposable {
return !(customLiveTemplate instanceof CustomLiveTemplateBase) || ((CustomLiveTemplateBase)customLiveTemplate).supportsMultiCaret();
}
- public static boolean isApplicable(@NotNull CustomLiveTemplate customLiveTemplate, @NotNull Editor editor, @NotNull PsiFile file) {
- return customLiveTemplate.isApplicable(file, CustomTemplateCallback.getOffset(editor), false);
+ public static boolean isApplicable(@NotNull CustomLiveTemplate customLiveTemplate,
+ @NotNull Editor editor,
+ @NotNull PsiFile file) {
+ return isApplicable(customLiveTemplate, editor, file, false);
+ }
+
+ public static boolean isApplicable(@NotNull CustomLiveTemplate customLiveTemplate,
+ @NotNull Editor editor,
+ @NotNull PsiFile file, boolean wrapping) {
+ return customLiveTemplate.isApplicable(file, CustomTemplateCallback.getOffset(editor), wrapping);
}
private static int getArgumentOffset(int caretOffset, String argument, CharSequence text) {
@@ -566,7 +574,7 @@ public class TemplateManagerImpl extends TemplateManager implements Disposable {
public static List<CustomLiveTemplate> listApplicableCustomTemplates(@NotNull Editor editor, @NotNull PsiFile file, boolean selectionOnly) {
List<CustomLiveTemplate> result = new ArrayList<CustomLiveTemplate>();
for (CustomLiveTemplate template : CustomLiveTemplate.EP_NAME.getExtensions()) {
- if ((!selectionOnly || template.supportsWrapping()) && isApplicable(template, editor, file)) {
+ if ((!selectionOnly || template.supportsWrapping()) && isApplicable(template, editor, file, selectionOnly)) {
result.add(template);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSegments.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSegments.java
index 183ca778ced7..0225350d2504 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSegments.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSegments.java
@@ -126,18 +126,6 @@ public class TemplateSegments {
}
}
- public int getSegmentWithTheSameStart(int segmentNumber, int start) {
- for (int i = segmentNumber + 1; i < mySegments.size(); i++) {
- final RangeMarker segment = mySegments.get(i);
- final int startOffset2 = segment.getStartOffset();
- if (start == startOffset2) {
- return i;
- }
- }
-
- return -1;
- }
-
public int getSegmentsCount() {
return mySegments.size();
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
index ef35a213346d..516ed9118c8c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
@@ -291,12 +291,11 @@ public class TemplateState implements Disposable {
LOG.assertTrue(!myStarted, "Already started");
myStarted = true;
myTemplate = template;
- PsiDocumentManager.getInstance(myProject).commitAllDocuments();
-
myProcessor = processor;
- DocumentReference[] refs =
- myDocument == null ? null : new DocumentReference[]{DocumentReferenceManager.getInstance().create(myDocument)};
+ DocumentReference[] refs = myDocument != null
+ ? new DocumentReference[]{DocumentReferenceManager.getInstance().create(myDocument)}
+ : null;
UndoManager.getInstance(myProject).undoableActionPerformed(new BasicUndoableAction(refs) {
@Override
public void undo() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java
index 5aaf314aa369..ecc1eb72bce8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/macro/BaseCompleteMacro.java
@@ -80,6 +80,9 @@ public abstract class BaseCompleteMacro extends Macro {
public void run() {
if (project.isDisposed() || editor.isDisposed() || psiFile == null || !psiFile.isValid()) return;
+ // it's invokeLater, so another completion could have started
+ if (CompletionServiceImpl.getCompletionService().getCurrentCompletion() != null) return;
+
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
index 17aaee57d8f5..2c934d76bbd5 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
@@ -90,16 +90,13 @@ public class InspectionManagerEx extends InspectionManagerBase {
if (tool instanceof CustomSuppressableInspectionTool) {
return ((CustomSuppressableInspectionTool)tool).getSuppressActions(null);
}
- if (tool instanceof BatchSuppressableTool) {
- LocalQuickFix[] actions = ((BatchSuppressableTool)tool).getBatchSuppressActions(null);
- return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, new Function<LocalQuickFix, SuppressIntentionAction>() {
- @Override
- public SuppressIntentionAction fun(final LocalQuickFix fix) {
- return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction((SuppressQuickFix)fix);
- }
- });
- }
- return null;
+ LocalQuickFix[] actions = tool.getBatchSuppressActions(null);
+ return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, new Function<LocalQuickFix, SuppressIntentionAction>() {
+ @Override
+ public SuppressIntentionAction fun(final LocalQuickFix fix) {
+ return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction((SuppressQuickFix)fix);
+ }
+ });
}
diff --git a/platform/lang-impl/src/com/intellij/execution/TerminateRemoteProcessDialog.java b/platform/lang-impl/src/com/intellij/execution/TerminateRemoteProcessDialog.java
index 288922aad1ef..64c60c29620b 100644
--- a/platform/lang-impl/src/com/intellij/execution/TerminateRemoteProcessDialog.java
+++ b/platform/lang-impl/src/com/intellij/execution/TerminateRemoteProcessDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -24,6 +24,7 @@ import com.intellij.CommonBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
+import org.jetbrains.annotations.NotNull;
public class TerminateRemoteProcessDialog {
public static int show(final Project project,
@@ -70,6 +71,7 @@ public class TerminateRemoteProcessDialog {
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return ExecutionBundle.message("terminate.after.disconnect.checkbox");
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java
index b9e504642e5e..fcec06644765 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleExecuteAction.java
@@ -133,7 +133,7 @@ public class ConsoleExecuteAction extends DumbAwareAction {
myExecuteActionHandler.addToCommandHistoryAndExecute(myConsole, myConsoleView, text);
}
- static abstract class ConsoleExecuteActionHandler {
+ public static abstract class ConsoleExecuteActionHandler {
private final ConsoleHistoryModel myCommandHistoryModel;
private boolean myAddToHistory = true;
@@ -156,10 +156,14 @@ public class ConsoleExecuteAction extends DumbAwareAction {
myAddToHistory = addCurrentToHistory;
}
+ /**
+ * @deprecated
+ */
protected void beforeExecution(@NotNull LanguageConsoleImpl console) {
}
- final void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) {
+ protected void runExecuteAction(@NotNull LanguageConsoleImpl console, @Nullable LanguageConsoleView consoleView) {
+ //noinspection deprecation
beforeExecution(console);
String text = console.prepareExecuteAction(myAddToHistory, myPreserveMarkup, true);
diff --git a/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java b/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
new file mode 100644
index 000000000000..c760310cd391
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
@@ -0,0 +1,258 @@
+package com.intellij.execution.console;
+
+import com.google.common.collect.Lists;
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.execution.filters.Filter;
+import com.intellij.execution.filters.HyperlinkInfo;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.execution.ui.ObservableConsoleView;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.ToggleAction;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.List;
+
+public class DuplexConsoleView<S extends ConsoleView, T extends ConsoleView> extends JPanel implements ConsoleView, ObservableConsoleView {
+ private final static String PRIMARY_CONSOLE_PANEL = "PRIMARY_CONSOLE_PANEL";
+ private final static String SECONDARY_CONSOLE_PANEL = "SECONDARY_CONSOLE_PANEL";
+
+ @NotNull
+ private final S myPrimaryConsoleView;
+ @NotNull
+ private final T mySecondaryConsoleView;
+
+ private boolean myPrimary;
+ @Nullable
+ private ProcessHandler myProcessHandler;
+ @NotNull
+ private final SwitchDuplexConsoleViewAction mySwitchConsoleAction;
+
+ public DuplexConsoleView(@NotNull S primaryConsoleView, @NotNull T secondaryConsoleView) {
+ super(new CardLayout());
+ myPrimaryConsoleView = primaryConsoleView;
+ mySecondaryConsoleView = secondaryConsoleView;
+
+ add(myPrimaryConsoleView.getComponent(), PRIMARY_CONSOLE_PANEL);
+ add(mySecondaryConsoleView.getComponent(), SECONDARY_CONSOLE_PANEL);
+
+ mySwitchConsoleAction = new SwitchDuplexConsoleViewAction(this);
+
+ myPrimary = true;
+ enableConsole(false);
+
+ Disposer.register(this, myPrimaryConsoleView);
+ Disposer.register(this, mySecondaryConsoleView);
+ }
+
+ public static <S extends ConsoleView, T extends ConsoleView> DuplexConsoleView<S, T> create(S primary, T secondary) {
+ return new DuplexConsoleView<S, T>(primary, secondary);
+ }
+
+ public void enableConsole(boolean primary) {
+ if (primary == myPrimary) {
+ // nothing to do
+ return;
+ }
+
+ CardLayout cl = (CardLayout)(getLayout());
+ cl.show(this, primary ? PRIMARY_CONSOLE_PANEL : SECONDARY_CONSOLE_PANEL);
+
+ getSubConsoleView(primary).getComponent().requestFocus();
+
+ myPrimary = primary;
+ }
+
+ public boolean isPrimaryConsoleEnabled() {
+ return myPrimary;
+ }
+
+ @NotNull
+ public S getPrimaryConsoleView() {
+ return myPrimaryConsoleView;
+ }
+
+ @NotNull
+ public T getSecondaryConsoleView() {
+ return mySecondaryConsoleView;
+ }
+
+ public ConsoleView getSubConsoleView(boolean primary) {
+ return primary ? getPrimaryConsoleView() : getSecondaryConsoleView();
+ }
+
+ @Override
+ public void print(@NotNull String s, @NotNull ConsoleViewContentType contentType) {
+ myPrimaryConsoleView.print(s, contentType);
+ mySecondaryConsoleView.print(s, contentType);
+ }
+
+ @Override
+ public void clear() {
+ myPrimaryConsoleView.clear();
+ mySecondaryConsoleView.clear();
+ }
+
+ @Override
+ public void scrollTo(int offset) {
+ myPrimaryConsoleView.scrollTo(offset);
+ mySecondaryConsoleView.scrollTo(offset);
+ }
+
+ @Override
+ public void attachToProcess(ProcessHandler processHandler) {
+ myProcessHandler = processHandler;
+
+ myPrimaryConsoleView.attachToProcess(processHandler);
+ mySecondaryConsoleView.attachToProcess(processHandler);
+ }
+
+ @Override
+ public void setOutputPaused(boolean value) {
+ myPrimaryConsoleView.setOutputPaused(value);
+ mySecondaryConsoleView.setOutputPaused(value);
+ }
+
+ @Override
+ public boolean isOutputPaused() {
+ return false;
+ }
+
+ @Override
+ public boolean hasDeferredOutput() {
+ return myPrimaryConsoleView.hasDeferredOutput() && mySecondaryConsoleView.hasDeferredOutput();
+ }
+
+ @Override
+ public void performWhenNoDeferredOutput(Runnable runnable) {
+ }
+
+ @Override
+ public void setHelpId(String helpId) {
+ myPrimaryConsoleView.setHelpId(helpId);
+ mySecondaryConsoleView.setHelpId(helpId);
+ }
+
+ @Override
+ public void addMessageFilter(Filter filter) {
+ myPrimaryConsoleView.addMessageFilter(filter);
+ mySecondaryConsoleView.addMessageFilter(filter);
+ }
+
+ @Override
+ public void printHyperlink(String hyperlinkText, HyperlinkInfo info) {
+ myPrimaryConsoleView.printHyperlink(hyperlinkText, info);
+ mySecondaryConsoleView.printHyperlink(hyperlinkText, info);
+ }
+
+ @Override
+ public int getContentSize() {
+ return myPrimaryConsoleView.getContentSize();
+ }
+
+ @Override
+ public boolean canPause() {
+ return false;
+ }
+
+
+ @NotNull
+ @Override
+ public AnAction[] createConsoleActions() {
+ List<AnAction> actions = Lists.newArrayList();
+ actions.addAll(Arrays.asList(myPrimaryConsoleView.createConsoleActions()));
+
+ actions.add(mySwitchConsoleAction);
+
+ return ArrayUtil.toObjectArray(actions, AnAction.class);
+ }
+
+ @Override
+ public void allowHeavyFilters() {
+ myPrimaryConsoleView.allowHeavyFilters();
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return this;
+ }
+
+ @Override
+ public JComponent getPreferredFocusableComponent() {
+ return this;
+ }
+
+ @Override
+ public void dispose() {
+ // registered children in constructor
+ }
+
+ @Override
+ public void addChangeListener(@NotNull ChangeListener listener, @NotNull Disposable parent) {
+ if (myPrimaryConsoleView instanceof ObservableConsoleView) {
+ ((ObservableConsoleView)myPrimaryConsoleView).addChangeListener(listener, parent);
+ }
+ if (mySecondaryConsoleView instanceof ObservableConsoleView) {
+ ((ObservableConsoleView)mySecondaryConsoleView).addChangeListener(listener, parent);
+ }
+ }
+
+ @NotNull
+ public Presentation getSwitchConsoleActionPresentation() {
+ return mySwitchConsoleAction.getTemplatePresentation();
+ }
+
+ private static class SwitchDuplexConsoleViewAction extends ToggleAction implements DumbAware {
+ private final DuplexConsoleView myConsole;
+
+ public SwitchDuplexConsoleViewAction(final DuplexConsoleView console) {
+ super(ExecutionBundle.message("run.configuration.show.command.line.action.name"), null,
+ AllIcons.Debugger.ToolConsole);
+ myConsole = console;
+ }
+
+ @Override
+ public boolean isSelected(final AnActionEvent event) {
+ return !myConsole.isPrimaryConsoleEnabled();
+ }
+
+ @Override
+ public void setSelected(final AnActionEvent event, final boolean flag) {
+ myConsole.enableConsole(!flag);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ update(event);
+ }
+ });
+ }
+
+ @Override
+ public void update(final AnActionEvent event) {
+ super.update(event);
+ final Presentation presentation = event.getPresentation();
+ final boolean isRunning = myConsole.myProcessHandler != null && !myConsole.myProcessHandler.isProcessTerminated();
+ if (isRunning) {
+ presentation.setEnabled(true);
+ }
+ else {
+ myConsole.enableConsole(true);
+ presentation.putClientProperty(SELECTED_PROPERTY, false);
+ presentation.setEnabled(false);
+ }
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java
index 99766cab33e0..c017284f8e11 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -434,6 +434,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
@@ -476,6 +477,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java
index 930fc2868359..4c58ab7029b3 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java
@@ -109,7 +109,7 @@ public final class SingleConfigurationConfigurable<Config extends RunConfigurati
settings.setSingleton(mySingleton);
settings.setFolderName(myFolderName);
super.apply();
- RunManagerImpl.getInstanceImpl(getConfiguration().getProject()).fireRunConfigurationChanged(settings);
+ runManager.addConfiguration(settings, myStoreProjectConfiguration, runManager.getBeforeRunTasks(settings.getConfiguration()), false);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
index fa3b64c3d0b6..897d169e1845 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
@@ -1482,7 +1482,10 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
final LayoutAttractionPolicy policy = getOrCreatePolicyFor(contentId, policyMap, defaultPolicy);
if (activate) {
- myAttractionCount++;
+ // See IDEA-93683, bounce attraction should not disable further focus attraction
+ if (!(policy instanceof LayoutAttractionPolicy.Bounce)) {
+ myAttractionCount++;
+ }
policy.attract(content, myRunnerUi);
}
else {
diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
index 42d0583dd9c0..93315c57cc49 100644
--- a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java
@@ -132,11 +132,11 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
@Override
@NotNull
- public <F extends Facet, C extends FacetConfiguration> F createFacet(@NotNull final FacetType<F, C> type, @NotNull final String name, @NotNull final C cofiguration,
+ public <F extends Facet, C extends FacetConfiguration> F createFacet(@NotNull final FacetType<F, C> type, @NotNull final String name, @NotNull final C configuration,
@Nullable final Facet underlying) {
- final F facet = type.createFacet(myModule, name, cofiguration, underlying);
+ final F facet = type.createFacet(myModule, name, configuration, underlying);
assertTrue(facet.getModule() == myModule, facet, "module");
- assertTrue(facet.getConfiguration() == cofiguration, facet, "configuration");
+ assertTrue(facet.getConfiguration() == configuration, facet, "configuration");
assertTrue(Comparing.equal(facet.getName(), name), facet, "name");
assertTrue(facet.getUnderlyingFacet() == underlying, facet, "underlyingFacet");
return facet;
@@ -212,7 +212,7 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
}
catch (InvalidDataException e) {
LOG.info(e);
- addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.load.facet.condiguration.0", e.getMessage()));
+ addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.load.facet.configuration.0", e.getMessage()));
}
}
}
@@ -413,7 +413,7 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
}
else {
final Facet underlyingFacet = facet.getUnderlyingFacet();
- LOG.assertTrue(underlyingFacet != null, "Underlying facet is not specifed for '" + facet.getName() + "'");
+ LOG.assertTrue(underlyingFacet != null, "Underlying facet is not specified for '" + facet.getName() + "'");
final Collection<?> facets = getFacetsByType(underlyingFacet, type.getId());
if (facets.size() > 1) {
LOG.error("Only one '" + type.getPresentableName() + "' facet per parent facet allowed, but " + facets.size() + " sub-facets found in facet " + underlyingFacet.getName());
diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetFinderImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetFinderImpl.java
index ed158c94a35a..f87c1fe3a23f 100644
--- a/platform/lang-impl/src/com/intellij/facet/impl/FacetFinderImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetFinderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@
package com.intellij.facet.impl;
import com.intellij.facet.*;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Disposer;
@@ -123,36 +124,43 @@ public class FacetFinderImpl extends FacetFinder {
return Collections.<F>emptyList();
}
- private static class AllFacetsOfTypeModificationTracker<F extends Facet> extends ProjectWideFacetAdapter<F>
- implements ModificationTracker, Disposable {
- private long myModificationCount;
-
+ private static class AllFacetsOfTypeModificationTracker<F extends Facet> extends SimpleModificationTracker implements Disposable, ProjectWideFacetListener<F> {
public AllFacetsOfTypeModificationTracker(final Project project, final FacetTypeId<F> type) {
ProjectWideFacetListenersRegistry.getInstance(project).registerListener(type, this, this);
}
@Override
public void facetAdded(final F facet) {
- myModificationCount++;
+ incModificationCount();
}
@Override
public void facetRemoved(final F facet) {
- myModificationCount++;
+ incModificationCount();
}
@Override
public void facetConfigurationChanged(final F facet) {
- myModificationCount++;
+ incModificationCount();
}
@Override
- public void dispose() {
+ public void firstFacetAdded() {
+
+ }
+
+ @Override
+ public void beforeFacetRemoved(F facet) {
+
+ }
+
+ @Override
+ public void allFacetsRemoved() {
+
}
@Override
- public long getModificationCount() {
- return myModificationCount;
+ public void dispose() {
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetModificationTrackingServiceImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetModificationTrackingServiceImpl.java
index 6edc17b1ce9f..deb5cc516e6c 100644
--- a/platform/lang-impl/src/com/intellij/facet/impl/FacetModificationTrackingServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetModificationTrackingServiceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +25,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.ModificationTrackerListener;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.util.EventDispatcher;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
@@ -35,8 +36,8 @@ import java.util.Map;
* @author nik
*/
public class FacetModificationTrackingServiceImpl extends FacetModificationTrackingService {
- private final Map<Facet, Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>>> myModificationsTrackers =
- new THashMap<Facet, Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>>>();
+ private final Map<Facet, Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>>> myModificationsTrackers =
+ new THashMap<Facet, Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>>>();
public FacetModificationTrackingServiceImpl(final Module module) {
module.getMessageBus().connect().subscribe(FacetManager.FACETS_TOPIC, new FacetModificationTrackingListener());
@@ -44,14 +45,14 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
@Override
@NotNull
- public FacetModificationTracker getFacetModificationTracker(@NotNull final Facet facet) {
+ public ModificationTracker getFacetModificationTracker(@NotNull final Facet facet) {
return getFacetInfo(facet).first;
}
- private Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> getFacetInfo(final Facet facet) {
- Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
+ private Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> getFacetInfo(final Facet facet) {
+ Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
if (pair == null) {
- pair = Pair.create(new FacetModificationTracker(), EventDispatcher.create(ModificationTrackerListener.class));
+ pair = Pair.create(new SimpleModificationTracker(), EventDispatcher.create(ModificationTrackerListener.class));
myModificationsTrackers.put(facet, pair);
}
return pair;
@@ -59,8 +60,8 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
@Override
public void incFacetModificationTracker(@NotNull final Facet facet) {
- final Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = getFacetInfo(facet);
- pair.first.myModificationCount ++;
+ final Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = getFacetInfo(facet);
+ pair.first.incModificationCount();
pair.second.getMulticaster().modificationCountChanged(facet);
}
@@ -74,21 +75,12 @@ public class FacetModificationTrackingServiceImpl extends FacetModificationTrack
getFacetInfo(facet).second.removeListener(listener);
}
- private static class FacetModificationTracker implements ModificationTracker {
- private long myModificationCount;
-
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
- }
-
private class FacetModificationTrackingListener extends FacetManagerAdapter {
@Override
public void facetConfigurationChanged(@NotNull final Facet facet) {
- final Pair<FacetModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
+ final Pair<SimpleModificationTracker, EventDispatcher<ModificationTrackerListener>> pair = myModificationsTrackers.get(facet);
if (pair != null) {
- pair.first.myModificationCount++;
+ pair.first.incModificationCount();
pair.second.getMulticaster().modificationCountChanged(facet);
}
}
diff --git a/platform/lang-impl/src/com/intellij/facet/impl/ProjectFacetManagerImpl.java b/platform/lang-impl/src/com/intellij/facet/impl/ProjectFacetManagerImpl.java
index 5b2c8c5535c7..83888001d1d9 100644
--- a/platform/lang-impl/src/com/intellij/facet/impl/ProjectFacetManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/facet/impl/ProjectFacetManagerImpl.java
@@ -27,7 +27,10 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.psi.util.*;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.ParameterizedCachedValue;
+import com.intellij.psi.util.ParameterizedCachedValueProvider;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Tag;
@@ -92,6 +95,18 @@ public class ProjectFacetManagerImpl extends ProjectFacetManagerEx implements Pe
return getFacets(typeId, ModuleManager.getInstance(myProject).getModules());
}
+ @NotNull
+ @Override
+ public List<Module> getModulesWithFacet(@NotNull FacetTypeId<?> typeId) {
+ List<Module> result = new ArrayList<Module>();
+ for (Module module : ModuleManager.getInstance(myProject).getModules()) {
+ if (!FacetManager.getInstance(module).getFacetsByType(typeId).isEmpty()) {
+ result.add(module);
+ }
+ }
+ return result;
+ }
+
@Override
public boolean hasFacets(@NotNull FacetTypeId<?> typeId) {
ParameterizedCachedValue<Boolean, FacetTypeId<?>> value = myCachedHasFacets.get(typeId);
diff --git a/platform/lang-impl/src/com/intellij/find/FindProgressIndicator.java b/platform/lang-impl/src/com/intellij/find/FindProgressIndicator.java
index a145c27a3aba..d0448217cee1 100644
--- a/platform/lang-impl/src/com/intellij/find/FindProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/find/FindProgressIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,12 +18,13 @@ package com.intellij.find;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
+import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
public class FindProgressIndicator extends BackgroundableProcessIndicator {
- public FindProgressIndicator(Project project, String scopeString) {
+ public FindProgressIndicator(@NotNull Project project, String scopeString) {
super(project,
FindBundle.message("find.progress.searching.message", scopeString),
new SearchInBackgroundOption(),
diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java
index 5c931bb26a5b..0728ea07e2b3 100644
--- a/platform/lang-impl/src/com/intellij/find/FindUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java
@@ -923,7 +923,7 @@ public class FindUtil {
}
@Nullable
- public static UsageView showInUsageView(PsiElement sourceElement, @NotNull final PsiElement[] targets, String title, Project project) {
+ public static UsageView showInUsageView(PsiElement sourceElement, @NotNull final PsiElement[] targets, @NotNull String title, @NotNull Project project) {
if (targets.length == 0) return null;
final UsageViewPresentation presentation = new UsageViewPresentation();
presentation.setCodeUsagesString(title);
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
index f84fed5a05d9..84776f4bf7ff 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
@@ -37,6 +37,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
@@ -50,7 +51,6 @@ import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.*;
@@ -84,14 +84,17 @@ import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public class ShowUsagesAction extends AnAction implements PopupAction {
private final boolean showSettingsDialogBefore;
private static final int USAGES_PAGE_SIZE = 100;
- static final NullUsage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE;
+ static final Usage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE;
private static final UsageNode MORE_USAGES_SEPARATOR_NODE = UsageViewImpl.NULL_NODE;
+ static final Usage USAGES_OUTSIDE_SCOPE_SEPARATOR = new UsageAdapter();
+ private static final UsageNode USAGES_OUTSIDE_SCOPE_NODE = new UsageNode(USAGES_OUTSIDE_SCOPE_SEPARATOR, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
private static final Comparator<UsageNode> USAGE_NODE_COMPARATOR = new Comparator<UsageNode>() {
@Override
@@ -100,8 +103,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (c2 instanceof StringNode) return -1;
Usage o1 = c1.getUsage();
Usage o2 = c2.getUsage();
- if (o1 == MORE_USAGES_SEPARATOR) return 1;
- if (o2 == MORE_USAGES_SEPARATOR) return -1;
+ int weight1 = o1 == USAGES_OUTSIDE_SCOPE_SEPARATOR ? 2 : o1 == MORE_USAGES_SEPARATOR ? 1 : 0;
+ int weight2 = o2 == USAGES_OUTSIDE_SCOPE_SEPARATOR ? 2 : o2 == MORE_USAGES_SEPARATOR ? 1 : 0;
+ if (weight1 != weight2) return weight1 - weight2;
VirtualFile v1 = UsageListCellRenderer.getVirtualFile(o1);
VirtualFile v2 = UsageListCellRenderer.getVirtualFile(o2);
@@ -193,26 +197,18 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
private void startFindUsages(@NotNull PsiElement element, @NotNull RelativePoint popupPosition, Editor editor, int maxUsages) {
Project project = element.getProject();
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
- FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false);
+ FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false);
if (handler == null) return;
if (showSettingsDialogBefore) {
showDialogAndFindUsages(handler, popupPosition, editor, maxUsages);
return;
}
- showElementUsages(handler, editor, popupPosition, maxUsages, getDefaultOptions(handler));
+ showElementUsages(editor, popupPosition, handler, maxUsages, handler.getFindUsagesOptions(DataManager.getInstance().getDataContext()));
}
- @NotNull
- private static FindUsagesOptions getDefaultOptions(@NotNull FindUsagesHandler handler) {
- FindUsagesOptions options = handler.getFindUsagesOptions(DataManager.getInstance().getDataContext());
- // by default, scope in FindUsagesOptions is copied from the FindSettings, but we need a default one
- options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
- return options;
- }
-
- private void showElementUsages(@NotNull final FindUsagesHandler handler,
- final Editor editor,
+ private void showElementUsages(final Editor editor,
@NotNull final RelativePoint popupPosition,
+ @NotNull final FindUsagesHandler handler,
final int maxUsages,
@NotNull final FindUsagesOptions options) {
ApplicationManager.getApplication().assertIsDispatchThread();
@@ -236,30 +232,26 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
usageViewSettings.loadState(savedGlobalSettings);
}
});
+ final AtomicInteger outOfScopeUsages = new AtomicInteger();
final List<Usage> usages = new ArrayList<Usage>();
final Set<UsageNode> visibleNodes = new LinkedHashSet<UsageNode>();
final MyTable table = new MyTable();
final AsyncProcessIcon processIcon = new AsyncProcessIcon("xxx");
- boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE);
- if (hadMoreSeparator) {
- usages.add(MORE_USAGES_SEPARATOR);
- visibleNodes.add(MORE_USAGES_SEPARATOR_NODE);
- }
addUsageNodes(usageView.getRoot(), usageView, new ArrayList<UsageNode>());
TableScrollingUtil.installActions(table);
final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
- setTableModel(table, usageView, data);
+ setTableModel(table, usageView, data, outOfScopeUsages, options.searchScope);
SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
speedSearch.setComparator(new SpeedSearchComparator(false));
final JBPopup popup = createUsagePopup(usages, visibleNodes, handler, editor, popupPosition,
- maxUsages, usageView, options, table, presentation, processIcon, hadMoreSeparator);
+ maxUsages, usageView, options, table, presentation, processIcon);
Disposer.register(popup, usageView);
@@ -293,7 +285,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
copy = new ArrayList<Usage>(usages);
}
- rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed());
+ rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition, !processIcon.isDisposed(), outOfScopeUsages,
+ options.searchScope);
}
});
@@ -305,11 +298,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
});
-
+ final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())};
Processor<Usage> collect = new Processor<Usage>() {
- private final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())};
@Override
public boolean process(@NotNull final Usage usage) {
+ if (!UsageViewManagerImpl.isInScope(usage, options.searchScope)) {
+ if (outOfScopeUsages.getAndIncrement() == 0) {
+ visibleNodes.add(USAGES_OUTSIDE_SCOPE_NODE);
+ usages.add(USAGES_OUTSIDE_SCOPE_SEPARATOR);
+ }
+ return true;
+ }
synchronized (usages) {
if (visibleNodes.size() >= maxUsages) return false;
if(UsageViewManager.isSelfUsage(usage, myUsageTarget)) return true;
@@ -352,8 +351,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
synchronized (usages) {
if (visibleNodes.isEmpty()) {
if (usages.isEmpty()) {
- String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options, project));
- showHint(text, editor, popupPosition, handler, maxUsages, options);
+ String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options));
+ hint(editor, text, handler, popupPosition, maxUsages, options, false);
popup.cancel();
}
else {
@@ -364,8 +363,13 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (usages.size() == 1) {
//the only usage
Usage usage = visibleNodes.iterator().next().getUsage();
- String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options, project));
- navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
+ if (usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) {
+ hint(editor, UsageViewManagerImpl.outOfScopeMessage(outOfScopeUsages.get(), options.searchScope), handler, popupPosition, maxUsages, options, true);
+ }
+ else {
+ String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options));
+ navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
+ }
popup.cancel();
}
else {
@@ -373,7 +377,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
// usage view can filter usages down to one
Usage visibleUsage = visibleNodes.iterator().next().getUsage();
if (areAllUsagesInOneLine(visibleUsage, usages)) {
- String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options, project));
+ String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options));
navigateAndHint(visibleUsage, hint, handler, popupPosition, maxUsages, options);
popup.cancel();
}
@@ -451,21 +455,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
}
- private void showHint(@NotNull String text,
- @Nullable final Editor editor,
- @NotNull final RelativePoint popupPosition,
- @NotNull FindUsagesHandler handler,
- int maxUsages,
- @NotNull FindUsagesOptions options) {
- JComponent label = createHintComponent(text, handler, popupPosition, editor, HIDE_HINTS_ACTION, maxUsages, options);
- if (editor == null || editor.isDisposed() || !editor.getComponent().isShowing()) {
- HintManager.getInstance().showHint(label, popupPosition, HintManager.HIDE_BY_ANY_KEY |
- HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0);
- }
- else {
- HintManager.getInstance().showInformationHint(editor, label);
- }
- }
@NotNull
private JComponent createHintComponent(@NotNull String text,
@@ -474,8 +463,12 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
final Editor editor,
@NotNull final Runnable cancelAction,
final int maxUsages,
- @NotNull final FindUsagesOptions options) {
+ @NotNull final FindUsagesOptions options,
+ boolean isWarning) {
JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text + "&nbsp;"));
+ if (isWarning) {
+ label.setBackground(MessageType.WARNING.getPopupBackground());
+ }
InplaceButton button = createSettingsButton(handler, popupPosition, editor, maxUsages, cancelAction);
JPanel panel = new JPanel(new BorderLayout()) {
@@ -540,19 +533,13 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (dialog.isOK()) {
dialog.calcFindUsagesOptions();
FindUsagesOptions options = handler.getFindUsagesOptions(DataManager.getInstance().getDataContext());
- showElementUsages(handler, editor, popupPosition, maxUsages, options);
+ showElementUsages(editor, popupPosition, handler, maxUsages, options);
}
}
- private static String searchScopePresentableName(@NotNull FindUsagesOptions options, @NotNull Project project) {
- return notNullizeScope(options, project).getDisplayName();
- }
-
@NotNull
- private static SearchScope notNullizeScope(@NotNull FindUsagesOptions options, @NotNull Project project) {
- SearchScope scope = options.searchScope;
- if (scope == null) return ProjectScope.getAllScope(project);
- return scope;
+ private static String searchScopePresentableName(@NotNull FindUsagesOptions options) {
+ return options.searchScope.getDisplayName();
}
@NotNull
@@ -566,8 +553,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull final FindUsagesOptions options,
@NotNull final JTable table,
@NotNull final UsageViewPresentation presentation,
- @NotNull final AsyncProcessIcon processIcon,
- boolean hadMoreSeparator) {
+ @NotNull final AsyncProcessIcon processIcon) {
table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2);
table.setShowGrid(false);
table.setShowVerticalLines(false);
@@ -579,14 +565,15 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
PopupChooserBuilder builder = new PopupChooserBuilder(table);
final String title = presentation.getTabText();
if (title != null) {
- String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true);
+ String result = getFullTitle(usages, title, false, visibleNodes.size() - 1, true);
builder.setTitle(result);
builder.setAdText(getSecondInvocationTitle(options, handler));
}
builder.setMovable(true).setResizable(true);
final AtomicReference<Object> selectedUsage = new AtomicReference<Object>();
- final AtomicBoolean moreUsages = new AtomicBoolean();
+ final AtomicBoolean moreUsagesSelected = new AtomicBoolean();
+ final AtomicBoolean outsideScopeUsagesSelected = new AtomicBoolean();
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
@@ -596,12 +583,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
Object value = table.getValueAt(i, 0);
if (value instanceof UsageNode) {
Usage usage = ((UsageNode)value).getUsage();
- if (usage == MORE_USAGES_SEPARATOR) {
- moreUsages.set(true);
+ outsideScopeUsagesSelected.set(false);
+ moreUsagesSelected.set(false);
+ if (usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) {
+ outsideScopeUsagesSelected.set(true);
+ selectedUsage.set(null);
+ }
+ else if (usage == MORE_USAGES_SEPARATOR) {
+ moreUsagesSelected.set(true);
selectedUsage.set(null);
}
else {
- moreUsages.set(false);
selectedUsage.set(usage instanceof UsageInfo2UsageAdapter ? ((UsageInfo2UsageAdapter)usage).getUsageInfo().copy() : usage);
}
break;
@@ -613,10 +605,15 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
builder.setItemChoosenCallback(new Runnable() {
@Override
public void run() {
- if (moreUsages.get()) {
+ if (moreUsagesSelected.get()) {
appendMoreUsages(editor, popupPosition, handler, maxUsages, options);
return;
}
+ if (outsideScopeUsagesSelected.get()) {
+ options.searchScope = GlobalSearchScope.projectScope(handler.getProject());
+ showElementUsages(editor, popupPosition, handler, maxUsages, options);
+ return;
+ }
Object usage = selectedUsage.get();
if (usage instanceof UsageInfo) {
UsageViewUtil.navigateTo((UsageInfo)usage, true);
@@ -684,7 +681,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
JComponent content = popup[0].getContent();
myWidth = (int)(toolBar.getPreferredSize().getWidth()
- + new JLabel(getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1, true)).getPreferredSize().getWidth()
+ + new JLabel(getFullTitle(usages, title, false, visibleNodes.size() - 1, true)).getPreferredSize().getWidth()
+ settingsButton.getPreferredSize().getWidth());
myWidth = -1;
for (AnAction action : toolbar.getChildren(null)) {
@@ -770,7 +767,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
private static String getSecondInvocationTitle(@NotNull FindUsagesOptions options, @NotNull FindUsagesHandler handler) {
if (getShowUsagesShortcut() != null) {
GlobalSearchScope maximalScope = FindUsagesManager.getMaximalScope(handler);
- if (!notNullizeScope(options, handler.getProject()).equals(maximalScope)) {
+ if (!options.searchScope.equals(maximalScope)) {
return "Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) + " again to search in " + maximalScope.getDisplayName();
}
}
@@ -784,7 +781,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
int maxUsages) {
FindUsagesOptions cloned = options.clone();
cloned.searchScope = FindUsagesManager.getMaximalScope(handler);
- showElementUsages(handler, editor, popupPosition, maxUsages, cloned);
+ showElementUsages(editor, popupPosition, handler, maxUsages, cloned);
}
@Nullable
@@ -827,7 +824,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull
private static MyModel setTableModel(@NotNull JTable table,
@NotNull UsageViewImpl usageView,
- @NotNull final List<UsageNode> data) {
+ @NotNull final List<UsageNode> data,
+ @NotNull AtomicInteger outOfScopeUsages,
+ @NotNull SearchScope searchScope) {
ApplicationManager.getApplication().assertIsDispatchThread();
final int columnCount = calcColumnCount(data);
MyModel model = table.getModel() instanceof MyModel ? (MyModel)table.getModel() : null;
@@ -835,7 +834,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
model = new MyModel(data, columnCount);
table.setModel(model);
- ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView);
+ ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView, outOfScopeUsages, searchScope);
for (int i=0;i<table.getColumnModel().getColumnCount();i++) {
TableColumn column = table.getColumnModel().getColumn(i);
column.setCellRenderer(renderer);
@@ -908,21 +907,27 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull final JBPopup popup,
@NotNull final UsageViewPresentation presentation,
@NotNull final RelativePoint popupPosition,
- boolean findUsagesInProgress) {
+ boolean findUsagesInProgress,
+ @NotNull AtomicInteger outOfScopeUsages,
+ @NotNull SearchScope searchScope) {
ApplicationManager.getApplication().assertIsDispatchThread();
boolean shouldShowMoreSeparator = usages.contains(MORE_USAGES_SEPARATOR);
if (shouldShowMoreSeparator) {
nodes.add(MORE_USAGES_SEPARATOR_NODE);
}
+ boolean hasOutsideScopeUsages = usages.contains(USAGES_OUTSIDE_SCOPE_SEPARATOR);
+ if (hasOutsideScopeUsages && !shouldShowMoreSeparator) {
+ nodes.add(USAGES_OUTSIDE_SCOPE_NODE);
+ }
String title = presentation.getTabText();
- String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator, nodes.size() - (shouldShowMoreSeparator ? 1 : 0), findUsagesInProgress);
+ String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator || hasOutsideScopeUsages, nodes.size() - (shouldShowMoreSeparator || hasOutsideScopeUsages ? 1 : 0), findUsagesInProgress);
((AbstractPopup)popup).setCaption(fullTitle);
List<UsageNode> data = collectData(usages, nodes, usageView, presentation);
- MyModel tableModel = setTableModel(table, usageView, data);
+ MyModel tableModel = setTableModel(table, usageView, data, outOfScopeUsages, searchScope);
List<UsageNode> existingData = tableModel.getItems();
int row = table.getSelectedRow();
@@ -1021,8 +1026,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
private void appendMoreUsages(Editor editor,
@NotNull RelativePoint popupPosition,
@NotNull FindUsagesHandler handler,
- int maxUsages, final FindUsagesOptions options) {
- showElementUsages(handler, editor, popupPosition, maxUsages+USAGES_PAGE_SIZE, options);
+ int maxUsages,
+ @NotNull FindUsagesOptions options) {
+ showElementUsages(editor, popupPosition, handler, maxUsages+USAGES_PAGE_SIZE, options);
}
private static void addUsageNodes(@NotNull GroupNode root, @NotNull final UsageViewImpl usageView, @NotNull List<UsageNode> outNodes) {
@@ -1054,25 +1060,51 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (hint == null) return;
final Editor newEditor = getEditorFor(usage);
if (newEditor == null) return;
+ hint(newEditor, hint, handler, popupPosition, maxUsages, options, false);
+ }
+
+ private void showHint(@Nullable final Editor editor,
+ @NotNull String hint,
+ @NotNull FindUsagesHandler handler,
+ @NotNull final RelativePoint popupPosition,
+ int maxUsages,
+ @NotNull FindUsagesOptions options,
+ boolean isWarning) {
+ JComponent label = createHintComponent(hint, handler, popupPosition, editor, HIDE_HINTS_ACTION, maxUsages, options, isWarning);
+ if (editor == null || editor.isDisposed() || !editor.getComponent().isShowing()) {
+ HintManager.getInstance().showHint(label, popupPosition, HintManager.HIDE_BY_ANY_KEY |
+ HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0);
+ }
+ else {
+ HintManager.getInstance().showInformationHint(editor, label);
+ }
+ }
+
+ private void hint(@Nullable final Editor editor,
+ @NotNull final String hint,
+ @NotNull final FindUsagesHandler handler,
+ @NotNull final RelativePoint popupPosition,
+ final int maxUsages,
+ @NotNull final FindUsagesOptions options,
+ final boolean isWarning) {
final Project project = handler.getProject();
//opening editor is performing in invokeLater
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
@Override
public void run() {
- newEditor.getScrollingModel().runActionOnScrollingFinished(new Runnable() {
+ Runnable runnable = new Runnable() {
@Override
public void run() {
// after new editor created, some editor resizing events are still bubbling. To prevent hiding hint, invokeLater this
IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
@Override
public void run() {
- if (newEditor.getComponent().isShowing()) {
- showHint(hint, newEditor, popupPosition, handler, maxUsages, options);
- }
+ showHint(editor, hint, handler, popupPosition, maxUsages, options, isWarning);
}
});
}
- });
+ };
+ if (editor == null) runnable.run(); else editor.getScrollingModel().runActionOnScrollingFinished(runnable);
}
});
}
@@ -1119,9 +1151,9 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
static class StringNode extends UsageNode {
- private final Object myString;
+ @NotNull private final Object myString;
- public StringNode(Object string) {
+ public StringNode(@NotNull Object string) {
super(NullUsage.INSTANCE, new UsageViewTreeModelBuilder(new UsageViewPresentation(), UsageTarget.EMPTY_ARRAY));
myString = string;
}
@@ -1159,7 +1191,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
UsageNode node = (UsageNode)element;
if (node instanceof StringNode) return "";
Usage usage = node.getUsage();
- if (usage == MORE_USAGES_SEPARATOR) return "";
+ if (usage == MORE_USAGES_SEPARATOR || usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) return "";
GroupNode group = (GroupNode)node.getParent();
return usage.getPresentation().getPlainText() + group;
}
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java
index 7603bab35b7b..d9848fdec4b0 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesTableCellRenderer.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.psi.search.SearchScope;
import com.intellij.ui.FileColorManager;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
@@ -30,24 +31,30 @@ import com.intellij.usages.UsagePresentation;
import com.intellij.usages.impl.GroupNode;
import com.intellij.usages.impl.UsageNode;
import com.intellij.usages.impl.UsageViewImpl;
+import com.intellij.usages.impl.UsageViewManagerImpl;
import com.intellij.usages.rules.UsageInFile;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
-import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
import java.awt.*;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* @author cdr
*/
class ShowUsagesTableCellRenderer implements TableCellRenderer {
private final UsageViewImpl myUsageView;
+ @NotNull private final AtomicInteger myOutOfScopeUsages;
+ @NotNull private final SearchScope mySearchScope;
- ShowUsagesTableCellRenderer(@NotNull UsageViewImpl usageView) {
+ ShowUsagesTableCellRenderer(@NotNull UsageViewImpl usageView, @NotNull AtomicInteger outOfScopeUsages, @NotNull SearchScope searchScope) {
myUsageView = usageView;
+ myOutOfScopeUsages = outOfScopeUsages;
+ mySearchScope = searchScope;
}
@Override
@@ -60,32 +67,37 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer {
Color fileBgColor = getBackgroundColor(isSelected, usage);
final Color bg = UIUtil.getListSelectionBackground();
final Color fg = UIUtil.getListSelectionForeground();
- panel.setBackground(isSelected ? bg : fileBgColor == null ? list.getBackground() : fileBgColor);
- panel.setForeground(isSelected ? fg : list.getForeground());
-
- if (usage == null || usageNode instanceof ShowUsagesAction.StringNode) {
- panel.setLayout(new BorderLayout());
- if (column == 0) {
- panel.add(new JLabel(XmlStringUtil.wrapInHtml("<b>" + value + "</b>"), SwingConstants.CENTER));
- }
- return panel;
- }
-
+ Color panelBackground = isSelected ? bg : fileBgColor == null ? list.getBackground() : fileBgColor;
+ Color panelForeground = isSelected ? fg : list.getForeground();
+ panel.setBackground(panelBackground);
+ panel.setForeground(panelForeground);
SimpleColoredComponent textChunks = new SimpleColoredComponent();
- textChunks.setIpad(new Insets(0,0,0,0));
+ textChunks.setIpad(new Insets(0, 0, 0, 0));
textChunks.setBorder(null);
+ if (usage == null || usageNode instanceof ShowUsagesAction.StringNode) {
+ textChunks.append(value.toString(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
+ return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
+ }
+ if (usage == ShowUsagesAction.MORE_USAGES_SEPARATOR) {
+ textChunks.append("...<");
+ textChunks.append("more usages", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
+ textChunks.append(">...");
+ return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
+ }
+ else if (usage == ShowUsagesAction.USAGES_OUTSIDE_SCOPE_SEPARATOR) {
+ textChunks.append("...<");
+ textChunks.append(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
+ textChunks.append(">...");
+ return textComponentSpanningWholeRow(textChunks, panelBackground, panelForeground, column, list, row);
+ }
+
if (column == 0) {
GroupNode parent = (GroupNode)usageNode.getParent();
appendGroupText(parent, panel, fileBgColor);
- if (usage == ShowUsagesAction.MORE_USAGES_SEPARATOR) {
- textChunks.append("...<");
- textChunks.append("more usages", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
- textChunks.append(">...");
- }
}
- else if (usage != ShowUsagesAction.MORE_USAGES_SEPARATOR) {
+ else if (usage != ShowUsagesAction.MORE_USAGES_SEPARATOR && usage != ShowUsagesAction.USAGES_OUTSIDE_SCOPE_SEPARATOR) {
UsagePresentation presentation = usage.getPresentation();
TextChunk[] text = presentation.getText();
@@ -116,6 +128,59 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer {
return panel;
}
+ @NotNull
+ private static Component textComponentSpanningWholeRow(@NotNull SimpleColoredComponent chunks,
+ Color panelBackground,
+ Color panelForeground,
+ final int column,
+ @NotNull final JTable table, int row) {
+ final SimpleColoredComponent component = new SimpleColoredComponent() {
+ @Override
+ protected void doPaint(Graphics2D g) {
+ int offset = 0;
+ int i = 0;
+ final TableColumnModel columnModel = table.getColumnModel();
+ while (i < column) {
+ offset += columnModel.getColumn(i).getWidth();
+ i++;
+ }
+ g.translate(-offset, 0);
+
+ //if (column == columnModel.getColumnCount()-1) {
+ //}
+ setSize(getWidth()+offset, getHeight()); // should increase the column width so that selection background will be visible even after offset translation
+
+ super.doPaint(g);
+
+ g.translate(+offset, 0);
+ }
+
+ @NotNull
+ @Override
+ public Dimension getPreferredSize() {
+ //return super.getPreferredSize();
+ return column == table.getColumnModel().getColumnCount()-1 ? super.getPreferredSize() : new Dimension(0,0);
+ // it should span the whole row, so we can't return any specific value here,
+ // because otherwise it would be used in the "max width" calculation in com.intellij.find.actions.ShowUsagesAction.calcMaxWidth
+ }
+ };
+
+ component.setIpad(new Insets(0,0,0,0));
+ component.setBorder(null);
+ component.setBackground(panelBackground);
+ component.setForeground(panelForeground);
+
+ for (SimpleColoredComponent.ColoredIterator iterator = chunks.iterator(); iterator.hasNext(); ) {
+ iterator.next();
+ String fragment = iterator.getFragment();
+ SimpleTextAttributes attributes = iterator.getTextAttributes();
+ attributes = attributes.derive(attributes.getStyle(), panelForeground, panelBackground, attributes.getWaveColor());
+ component.append(fragment, attributes);
+ }
+
+ return component;
+ }
+
private static SimpleTextAttributes deriveAttributesWithColor(SimpleTextAttributes attributes, Color fileBgColor) {
if (fileBgColor != null) {
attributes = attributes.derive(-1,null, fileBgColor,null);
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java
index d1bae2c48f57..ee76d0ee4cc2 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -143,6 +143,7 @@ public abstract class AbstractFindUsagesDialog extends DialogWrapper {
return panel;
}
+ @NotNull
public final FindUsagesOptions calcFindUsagesOptions() {
calcFindUsagesOptions(myFindUsagesOptions);
return myFindUsagesOptions;
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
index a38dcced6135..fe47fb8558a6 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,14 +42,14 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog {
boolean toShowInNewTab,
boolean mustOpenInNewTab,
boolean isSingleFile,
- FindUsagesHandler handler) {
+ @NotNull FindUsagesHandler handler) {
super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler),
!isSingleFile && !element.getManager().isInProject(element));
myPsiElement = element;
init();
}
- private static boolean isTextSearch(PsiElement element, boolean isSingleFile, FindUsagesHandler handler) {
+ private static boolean isTextSearch(@NotNull PsiElement element, boolean isSingleFile, @NotNull FindUsagesHandler handler) {
return FindUsagesUtil.isSearchForTextOccurrencesAvailable(element, isSingleFile, handler);
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
index 5152fa8f863b..a9291cf612ba 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,8 +47,10 @@ import java.util.Collections;
*/
public abstract class FindUsagesHandler {
// return this handler if you want to cancel the search
+ @NotNull
public static final FindUsagesHandler NULL_HANDLER = new FindUsagesHandler(PsiUtilCore.NULL_PSI_ELEMENT){};
+ @NotNull
private final PsiElement myPsiElement;
protected FindUsagesHandler(@NotNull PsiElement psiElement) {
@@ -81,7 +83,8 @@ public abstract class FindUsagesHandler {
return PsiElement.EMPTY_ARRAY;
}
- public static FindUsagesOptions createFindUsagesOptions(final Project project, @Nullable final DataContext dataContext) {
+ @NotNull
+ public static FindUsagesOptions createFindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) {
FindUsagesOptions findUsagesOptions = new FindUsagesOptions(project, dataContext);
findUsagesOptions.isUsages = true;
findUsagesOptions.isSearchForTextOccurrences = true;
@@ -92,6 +95,7 @@ public abstract class FindUsagesHandler {
public FindUsagesOptions getFindUsagesOptions() {
return getFindUsagesOptions(null);
}
+
@NotNull
public FindUsagesOptions getFindUsagesOptions(@Nullable final DataContext dataContext) {
FindUsagesOptions options = createFindUsagesOptions(getProject(), dataContext);
@@ -185,7 +189,7 @@ public abstract class FindUsagesHandler {
}
@Nullable
- protected Collection<String> getStringsToSearch(final PsiElement element) {
+ protected Collection<String> getStringsToSearch(@NotNull final PsiElement element) {
if (element instanceof PsiNamedElement) {
return ApplicationManager.getApplication().runReadAction(new Computable<Collection<String>>() {
@Override
@@ -202,6 +206,7 @@ public abstract class FindUsagesHandler {
return false;
}
+ @NotNull
public Collection<PsiReference> findReferencesToHighlight(@NotNull PsiElement target, @NotNull SearchScope searchScope) {
return ReferencesSearch.search(target, searchScope, false).findAll();
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
index 6fe9d9799cba..d3978780e535 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
@@ -91,8 +91,7 @@ public class FindUsagesManager implements JDOMExternalizable {
private final com.intellij.usages.UsageViewManager myAnotherManager;
private boolean myToOpenInNewTab = true;
-
- private PsiElement2UsageTargetComposite myLastSearchInFileData;
+ private PsiElement2UsageTargetComposite myLastSearchInFileData; // EDT only
private final UsageHistory myHistory = new UsageHistory();
public FindUsagesManager(@NotNull Project project, @NotNull com.intellij.usages.UsageViewManager anotherManager) {
@@ -118,6 +117,7 @@ public class FindUsagesManager implements JDOMExternalizable {
}
public void clearFindingNextUsageInFile() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
myLastSearchInFileData = null;
}
@@ -140,6 +140,8 @@ public class FindUsagesManager implements JDOMExternalizable {
}
private boolean findUsageInFile(@NotNull FileEditor editor, @NotNull FileSearchScope direction) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
if (myLastSearchInFileData == null) return false;
PsiElement[] primaryElements = myLastSearchInFileData.getPrimaryElements();
PsiElement[] secondaryElements = myLastSearchInFileData.getSecondaryElements();
@@ -164,7 +166,11 @@ public class FindUsagesManager implements JDOMExternalizable {
}
- private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions, @NotNull PsiElement[] primaryElements,@NotNull PsiElement[] secondaryElements) {
+ private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions,
+ @NotNull PsiElement[] primaryElements,
+ @NotNull PsiElement[] secondaryElements) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+
myLastSearchInFileData = new PsiElement2UsageTargetComposite(primaryElements, secondaryElements, findUsagesOptions);
}
@@ -199,8 +205,8 @@ public class FindUsagesManager implements JDOMExternalizable {
return null;
}
- public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog) {
- FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
+ public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog, @Nullable("null means default (stored in options)") SearchScope searchScope) {
+ FindUsagesHandler handler = getFindUsagesHandler(psiElement, false);
if (handler == null) return;
boolean singleFile = scopeFile != null;
@@ -216,8 +222,8 @@ public class FindUsagesManager implements JDOMExternalizable {
setOpenInNewTab(dialog.isShowInSeparateWindow());
FindUsagesOptions findUsagesOptions = dialog.calcFindUsagesOptions();
- if (!showDialog) {
- findUsagesOptions.searchScope = GlobalSearchScope.projectScope(myProject);
+ if (searchScope != null) {
+ findUsagesOptions.searchScope = searchScope;
}
clearFindingNextUsageInFile();
@@ -229,15 +235,15 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull FindUsagesOptions findUsagesOptions,
PsiFile scopeFile,
FileEditor editor) {
- FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
+ FindUsagesHandler handler = getFindUsagesHandler(psiElement, false);
if (handler == null) return;
startFindUsages(findUsagesOptions, handler, scopeFile, editor);
}
- void startFindUsages(@NotNull FindUsagesOptions findUsagesOptions,
- @NotNull FindUsagesHandler handler,
- PsiFile scopeFile,
- FileEditor editor) {
+ private void startFindUsages(@NotNull FindUsagesOptions findUsagesOptions,
+ @NotNull FindUsagesHandler handler,
+ PsiFile scopeFile,
+ FileEditor editor) {
boolean singleFile = scopeFile != null;
clearFindingNextUsageInFile();
@@ -247,9 +253,8 @@ public class FindUsagesManager implements JDOMExternalizable {
PsiElement[] secondaryElements = handler.getSecondaryElements();
checkNotNull(secondaryElements, handler, "getSecondaryElements()");
if (singleFile) {
- findUsagesOptions = findUsagesOptions.clone();
editor.putUserData(KEY_START_USAGE_AGAIN, null);
- findUsagesInEditor(primaryElements, secondaryElements, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions, editor);
+ findUsagesInEditor(primaryElements, secondaryElements, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions.clone(), editor);
}
else {
boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage();
@@ -257,7 +262,7 @@ public class FindUsagesManager implements JDOMExternalizable {
}
}
- public void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
+ public static void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
if (targets.length == 0) return;
NavigationItem target = targets[0];
if (!(target instanceof ConfigurableUsageTarget)) return;
@@ -276,16 +281,13 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull
- public static ProgressIndicator startProcessUsages(@NotNull FindUsagesHandler handler,
+ public static ProgressIndicator startProcessUsages(@NotNull final FindUsagesHandler handler,
@NotNull final PsiElement[] primaryElements,
@NotNull final PsiElement[] secondaryElements,
@NotNull final Processor<Usage> processor,
- @NotNull FindUsagesOptions findUsagesOptions,
+ @NotNull final FindUsagesOptions findUsagesOptions,
@NotNull final Runnable onComplete) {
- final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
-
final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
- dropResolveCacheRegularly(indicator, handler.getProject());
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
@@ -293,6 +295,7 @@ public class FindUsagesManager implements JDOMExternalizable {
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
+ final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
usageSearcher.generate(processor);
}
}, indicator);
@@ -339,6 +342,14 @@ public class FindUsagesManager implements JDOMExternalizable {
return new UsageSearcher() {
@Override
public void generate(@NotNull final Processor<Usage> processor) {
+ Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
+ @Override
+ public Project compute() {
+ return scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject();
+ }
+ });
+ dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), project);
+
if (scopeFile != null) {
optionsClone.searchScope = new LocalSearchScope(scopeFile);
}
@@ -357,7 +368,10 @@ public class FindUsagesManager implements JDOMExternalizable {
final Iterable<PsiElement> elements = ContainerUtil.concat(primaryElements, secondaryElements);
optionsClone.fastTrack = new SearchRequestCollector(new SearchSession());
-
+ if (optionsClone.searchScope instanceof GlobalSearchScope) {
+ // we will search in project scope always but warn if some usage is out of scope
+ optionsClone.searchScope = optionsClone.searchScope.union(GlobalSearchScope.projectScope(project));
+ }
try {
for (final PsiElement element : elements) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -380,12 +394,6 @@ public class FindUsagesManager implements JDOMExternalizable {
}
}
- Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
- @Override
- public Project compute() {
- return scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject();
- }
- });
PsiSearchHelper.SERVICE.getInstance(project)
.processRequests(optionsClone.fastTrack, new Processor<PsiReference>() {
@Override
@@ -426,24 +434,21 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull final FindUsagesHandler handler,
@NotNull final FindUsagesOptions findUsagesOptions,
final boolean toSkipUsagePanelWhenOneUsage) {
-
if (primaryElements.length == 0) {
throw new AssertionError(handler + " " + findUsagesOptions);
}
Iterable<PsiElement> allElements = ContainerUtil.concat(primaryElements, secondaryElements);
- final UsageTarget[] targets = convertToUsageTargets(allElements, findUsagesOptions);
+ final PsiElement2UsageTargetAdapter[] targets = convertToUsageTargets(allElements, findUsagesOptions);
myAnotherManager.searchAndShowUsages(targets, new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
- dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), myProject);
return createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
}
}, !toSkipUsagePanelWhenOneUsage, true, createPresentation(primaryElements[0], findUsagesOptions, shouldOpenInNewTab()), null);
- myHistory.add((ConfigurableUsageTarget)targets[0]);
- //addToHistory(allElements, findUsagesOptions);
+ myHistory.add(targets[0]);
}
- private static void dropResolveCacheRegularly(ProgressIndicator indicator, final Project project) {
+ private static void dropResolveCacheRegularly(ProgressIndicator indicator, @NotNull final Project project) {
if (indicator instanceof ProgressIndicatorEx) {
((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
volatile long lastCleared = System.currentTimeMillis();
@@ -468,14 +473,12 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull FindUsagesOptions options,
boolean toOpenInNewTab) {
UsageViewPresentation presentation = new UsageViewPresentation();
- String scopeString = options.searchScope == null ? null : options.searchScope.getDisplayName();
+ String scopeString = options.searchScope.getDisplayName();
presentation.setScopeText(scopeString);
String usagesString = generateUsagesString(options);
presentation.setUsagesString(usagesString);
- String title = scopeString == null
- ? FindBundle.message("find.usages.of.element.panel.title", usagesString, UsageViewUtil.getLongName(psiElement))
- : FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement),
- scopeString);
+ String title = FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement),
+ scopeString);
presentation.setTabText(title);
presentation.setTabName(FindBundle.message("find.usages.of.element.tab.name", usagesString, UsageViewUtil.getShortName(psiElement)));
presentation.setTargetsNodeText(StringUtil.capitalize(UsageViewUtil.getType(psiElement)));
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
index 39727af430e1..38d3d161fc91 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
@@ -21,7 +21,6 @@ import com.intellij.find.FindSettings;
import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
@@ -31,7 +30,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
-public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
+public class FindUsagesOptions implements Cloneable {
+ @NotNull
public SearchScope searchScope;
public boolean isSearchForTextOccurrences = true;
@@ -46,15 +46,17 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
public FindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) {
String defaultScopeName = FindSettings.getInstance().getDefaultScopeName();
List<SearchScope> predefined = ScopeChooserCombo.getPredefinedScopes(project, dataContext, true, false, false, false);
+ SearchScope resultScope = null;
for (SearchScope scope : predefined) {
if (scope.getDisplayName().equals(defaultScopeName)) {
- searchScope = scope;
+ resultScope = scope;
break;
}
}
- if (searchScope == null) {
- searchScope = ProjectScope.getProjectScope(project);
+ if (resultScope == null) {
+ resultScope = ProjectScope.getProjectScope(project);
}
+ searchScope = resultScope;
}
public FindUsagesOptions(@NotNull SearchScope searchScope) {
@@ -63,9 +65,15 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
@Override
public FindUsagesOptions clone() {
- return (FindUsagesOptions)super.clone();
+ try {
+ return (FindUsagesOptions)super.clone();
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -74,13 +82,12 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
if (isSearchForTextOccurrences != that.isSearchForTextOccurrences) return false;
if (isUsages != that.isUsages) return false;
- if (searchScope != null ? !searchScope.equals(that.searchScope) : that.searchScope != null) return false;
-
- return true;
+ return searchScope.equals(that.searchScope);
}
+ @Override
public int hashCode() {
- int result = searchScope == null ? 0 : searchScope.hashCode();
+ int result = searchScope.hashCode();
result = 31 * result + (isSearchForTextOccurrences ? 1 : 0);
result = 31 * result + (isUsages ? 1 : 0);
return result;
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java
index 02c98d83a82c..1521f72e0d61 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,12 +18,13 @@ package com.intellij.find.findUsages;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class FindUsagesUtil {
private FindUsagesUtil() {
}
- public static boolean isSearchForTextOccurrencesAvailable(@NotNull PsiElement element, boolean isSingleFile, FindUsagesHandler handler) {
+ public static boolean isSearchForTextOccurrencesAvailable(@NotNull PsiElement element, boolean isSingleFile, @Nullable FindUsagesHandler handler) {
return !isSingleFile && handler != null && handler.isSearchForTextOccurencesAvailable(element, isSingleFile);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java
index e5119f26d088..5e4c59dfd572 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetAdapter.java
@@ -40,7 +40,6 @@ import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.meta.PsiPresentableMetaData;
import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.ui.ComputableIcon;
@@ -116,6 +115,7 @@ public class PsiElement2UsageTargetAdapter
return getElement();
}
+ @Override
public String toString() {
return getPresentableText();
}
@@ -198,6 +198,9 @@ public class PsiElement2UsageTargetAdapter
sink.put(UsageView.USAGE_INFO_KEY, new UsageInfo(element));
}
}
+ else if (key == UsageView.USAGE_SCOPE) {
+ sink.put(UsageView.USAGE_SCOPE, myOptions.searchScope);
+ }
}
@Override
@@ -209,24 +212,22 @@ public class PsiElement2UsageTargetAdapter
@Override
public String getLongDescriptiveName() {
SearchScope searchScope = myOptions.searchScope;
- String scopeString = searchScope == null ? null : searchScope.getDisplayName();
+ String scopeString = searchScope.getDisplayName();
PsiElement psiElement = getElement();
return psiElement == null ? UsageViewBundle.message("node.invalid") :
FindBundle.message("recent.find.usages.action.popup", StringUtil.capitalize(UsageViewUtil.getType(psiElement)),
DescriptiveNameUtil.getDescriptiveName(psiElement),
- scopeString == null
- ? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName()
- : scopeString
+ scopeString
);
}
@Override
public void showSettings() {
- FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager();
PsiElement element = getElement();
if (element != null) {
- findUsagesManager.findUsages(element, null, null, true);
+ FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager();
+ findUsagesManager.findUsages(element, null, null, true, null);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java
index a16050a08b07..a44208095e02 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/PsiElement2UsageTargetComposite.java
@@ -43,7 +43,7 @@ public class PsiElement2UsageTargetComposite extends PsiElement2UsageTargetAdapt
PsiElement element = getElement();
if (element == null) return;
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(element.getProject())).getFindUsagesManager();
- FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false);
+ FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(element, false);
boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage();
findUsagesManager.findUsages(myDescriptor.getPrimaryElements(), myDescriptor.getAdditionalElements(), handler, myOptions, skipResultsWithOneUsage);
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
index aa344c44be47..59adf1e62bd0 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
@@ -290,6 +290,10 @@ class FindInProjectTask {
for (VirtualFile file : getLocalScopeFiles((LocalSearchScope)customScope)) {
iterator.processFile(file);
}
+ } else if (customScope instanceof Iterable) { // GlobalSearchScope can span files out of project roots e.g. FileScope / FilesScope
+ for (VirtualFile file : (Iterable<VirtualFile>)customScope) {
+ iterator.processFile(file);
+ }
}
else if (myPsiDirectory != null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
index 801209900ed5..23f14c5eb0b4 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
@@ -306,7 +306,7 @@ public class FindInProjectUtil {
}
@NotNull
- public static FindUsagesProcessPresentation setupProcessPresentation(final Project project,
+ public static FindUsagesProcessPresentation setupProcessPresentation(@NotNull final Project project,
final boolean showPanelIfOnlyOneUsage,
@NotNull final UsageViewPresentation presentation) {
FindUsagesProcessPresentation processPresentation = new FindUsagesProcessPresentation(presentation);
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index 6400db8c43db..e327ec79c227 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -59,6 +59,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.LexerEditorHighlighterLexer;
+import com.intellij.psi.search.SearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.ui.LightweightHint;
@@ -860,13 +861,18 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
}
@Override
+ public void findUsagesInScope(@NotNull PsiElement element, @NotNull SearchScope searchScope) {
+ myFindUsagesManager.findUsages(element, null, null, false, searchScope);
+ }
+
+ @Override
public void findUsages(@NotNull PsiElement element, boolean showDialog) {
- myFindUsagesManager.findUsages(element, null, null, showDialog);
+ myFindUsagesManager.findUsages(element, null, null, showDialog, null);
}
@Override
public void showSettingsAndFindUsages(@NotNull NavigationItem[] targets) {
- myFindUsagesManager.showSettingsAndFindUsages(targets);
+ FindUsagesManager.showSettingsAndFindUsages(targets);
}
@Override
@@ -882,7 +888,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
Document document = editor.getDocument();
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
- myFindUsagesManager.findUsages(element, psiFile, fileEditor, false);
+ myFindUsagesManager.findUsages(element, psiFile, fileEditor, false, null);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java
index 5a6606be1c77..5b9e9a663b3f 100644
--- a/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -33,6 +34,7 @@ public class GeneratedFileEditingNotificationProvider extends EditorNotification
myChangeTracker = changeTracker;
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
@@ -40,7 +42,7 @@ public class GeneratedFileEditingNotificationProvider extends EditorNotification
@Nullable
@Override
- public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (!myChangeTracker.isEditedGeneratedFile(file)) return null;
EditorNotificationPanel panel = new EditorNotificationPanel();
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CloneElementAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CloneElementAction.java
deleted file mode 100644
index c0e5a45eed54..000000000000
--- a/platform/lang-impl/src/com/intellij/ide/actions/CloneElementAction.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.ide.actions;
-
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiElement;
-import com.intellij.refactoring.copy.CopyHandler;
-
-public class CloneElementAction extends CopyElementAction {
- private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CloneElementAction");
-
- @Override
- protected void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) {
- LOG.assertTrue(elements.length == 1);
- CopyHandler.doClone(elements[0]);
- }
-
- @Override
- protected void updateForEditor(DataContext dataContext, Presentation presentation) {
- super.updateForEditor(dataContext, presentation);
- presentation.setVisible(false);
- }
-
- @Override
- protected void updateForToolWindow(String id, DataContext dataContext,Presentation presentation) {
- // work only with single selection
- PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
- presentation.setEnabled(elements != null && elements.length == 1 && CopyHandler.canClone(elements));
- presentation.setVisible(true);
- if (!ToolWindowId.COMMANDER.equals(id)) {
- presentation.setVisible(false);
- }
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
index a83d51b7867a..3ad8cb12c2ec 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
@@ -36,15 +36,14 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.StatusBarEx;
import com.intellij.psi.*;
-import com.intellij.util.ArrayUtilRt;
-import com.intellij.util.LogicalRoot;
-import com.intellij.util.LogicalRootsManager;
-import com.intellij.util.ObjectUtils;
+import com.intellij.util.*;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,6 +52,8 @@ import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
/**
* @author Alexey
@@ -68,10 +69,20 @@ public class CopyReferenceAction extends DumbAwareAction {
@Override
public void update(AnActionEvent e) {
+ boolean plural = false;
+ boolean enabled;
+
DataContext dataContext = e.getDataContext();
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
- boolean enabled = (editor != null && FileDocumentManager.getInstance().getFile(editor.getDocument()) != null) ||
- getElementToCopy(editor, dataContext) != null;
+ if (editor != null && FileDocumentManager.getInstance().getFile(editor.getDocument()) != null) {
+ enabled = true;
+ }
+ else {
+ List<PsiElement> elements = getElementsToCopy(editor, dataContext);
+ enabled = !elements.isEmpty();
+ plural = elements.size() > 1;
+ }
+
e.getPresentation().setEnabled(enabled);
if (ActionPlaces.isPopupPlace(e.getPlace())) {
e.getPresentation().setVisible(enabled);
@@ -79,6 +90,7 @@ public class CopyReferenceAction extends DumbAwareAction {
else {
e.getPresentation().setVisible(true);
}
+ e.getPresentation().setText(plural ? "Cop&y References" : "Cop&y Reference");
}
@Override
@@ -86,9 +98,9 @@ public class CopyReferenceAction extends DumbAwareAction {
DataContext dataContext = e.getDataContext();
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
Project project = CommonDataKeys.PROJECT.getData(dataContext);
- PsiElement element = getElementToCopy(editor, dataContext);
+ List<PsiElement> elements = getElementsToCopy(editor, dataContext);
- if (!doCopy(element, project, editor) && editor != null && project != null) {
+ if (!doCopy(elements, project, editor) && editor != null && project != null) {
Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
if (file != null) {
@@ -102,45 +114,54 @@ public class CopyReferenceAction extends DumbAwareAction {
HighlightManager highlightManager = HighlightManager.getInstance(project);
EditorColorsManager manager = EditorColorsManager.getInstance();
TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
- if (element != null && editor != null && project != null) {
- PsiElement nameIdentifier = IdentifierUtil.getNameIdentifier(element);
+ if (elements.size() == 1 && editor != null && project != null) {
+ PsiElement nameIdentifier = IdentifierUtil.getNameIdentifier(elements.get(0));
if (nameIdentifier != null) {
highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{nameIdentifier}, attributes, true, null);
} else {
PsiReference reference = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
if (reference != null) {
highlightManager.addOccurrenceHighlights(editor, new PsiReference[]{reference}, attributes, true, null);
- } else if (element != PsiDocumentManager.getInstance(project).getCachedPsiFile(editor.getDocument())) {
- highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{element}, attributes, true, null);
+ } else if (elements != PsiDocumentManager.getInstance(project).getCachedPsiFile(editor.getDocument())) {
+ highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{elements.get(0)}, attributes, true, null);
}
}
}
}
- @Nullable
- private static PsiElement getElementToCopy(@Nullable final Editor editor, final DataContext dataContext) {
- PsiElement element = null;
+ @NotNull
+ private static List<PsiElement> getElementsToCopy(@Nullable final Editor editor, final DataContext dataContext) {
+ List<PsiElement> elements = ContainerUtil.newArrayList();
if (editor != null) {
PsiReference reference = TargetElementUtilBase.findReference(editor);
if (reference != null) {
- element = reference.getElement();
+ ContainerUtil.addIfNotNull(elements, reference.getElement());
}
}
- if (element == null) {
- element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
+ if (elements.isEmpty()) {
+ ContainerUtil.addIfNotNull(elements, CommonDataKeys.PSI_ELEMENT.getData(dataContext));
}
- if (element == null && editor == null) {
- VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
- Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (virtualFile != null && project != null) {
- element = PsiManager.getInstance(project).findFile(virtualFile);
+
+ if (elements.isEmpty() && editor == null) {
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
+ if (project != null && files != null) {
+ for (VirtualFile file : files) {
+ ContainerUtil.addIfNotNull(elements, PsiManager.getInstance(project).findFile(file));
+ }
}
}
- if (element instanceof PsiFile && !((PsiFile)element).getViewProvider().isPhysical()) {
- return null;
- }
+ return ContainerUtil.mapNotNull(elements, new Function<PsiElement, PsiElement>() {
+ @Override
+ public PsiElement fun(PsiElement element) {
+ return element instanceof PsiFile && !((PsiFile)element).getViewProvider().isPhysical() ? null : adjustElement(element);
+ }
+ });
+ }
+
+ private static PsiElement adjustElement(PsiElement element) {
for (QualifiedNameProvider provider : Extensions.getExtensions(QualifiedNameProvider.EP_NAME)) {
PsiElement adjustedElement = provider.adjustElementToCopy(element);
if (adjustedElement != null) return adjustedElement;
@@ -149,16 +170,25 @@ public class CopyReferenceAction extends DumbAwareAction {
}
public static boolean doCopy(final PsiElement element, final Project project) {
- return doCopy(element, project, null);
+ return doCopy(Arrays.asList(element), project, null);
}
- private static boolean doCopy(final PsiElement element, @Nullable final Project project, @Nullable Editor editor) {
- String fqn = elementToFqn(element, editor);
- if (fqn == null) return false;
+ private static boolean doCopy(List<PsiElement> elements, @Nullable final Project project, @Nullable Editor editor) {
+ if (elements.isEmpty()) return false;
+
+ List<String> fqns = ContainerUtil.newArrayList();
+ for (PsiElement element : elements) {
+ String fqn = elementToFqn(element, editor);
+ if (fqn == null) return false;
+
+ fqns.add(fqn);
+ }
+
+ String toCopy = StringUtil.join(fqns, "\n");
- CopyPasteManager.getInstance().setContents(new MyTransferable(fqn));
+ CopyPasteManager.getInstance().setContents(new MyTransferable(toCopy));
- setStatusBarText(project, IdeBundle.message("message.reference.to.fqn.has.been.copied", fqn));
+ setStatusBarText(project, IdeBundle.message("message.reference.to.fqn.has.been.copied", toCopy));
return true;
}
@@ -199,12 +229,12 @@ public class CopyReferenceAction extends DumbAwareAction {
}
@Nullable
- public static String elementToFqn(final PsiElement element) {
+ public static String elementToFqn(@Nullable final PsiElement element) {
return elementToFqn(element, null);
}
@Nullable
- public static String elementToFqn(final PsiElement element, @Nullable Editor editor) {
+ private static String elementToFqn(@Nullable final PsiElement element, @Nullable Editor editor) {
String result = getQualifiedNameFromProviders(element);
if (result != null) return result;
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
index 156e3a1e5d08..71b02f867d8a 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/ExternalJavaDocAction.java
@@ -37,6 +37,7 @@ import com.intellij.psi.PsiReference;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
+import java.awt.*;
import java.util.HashSet;
import java.util.List;
@@ -79,7 +80,7 @@ public class ExternalJavaDocAction extends AnAction {
final List<String> urls = provider.getUrlFor(element, originalElement);
if (urls != null && !urls.isEmpty()) {
- showExternalJavadoc(urls);
+ showExternalJavadoc(urls, PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext));
}
else if (provider instanceof ExternalDocumentationProvider) {
final ExternalDocumentationProvider externalDocumentationProvider = (ExternalDocumentationProvider)provider;
@@ -89,7 +90,7 @@ public class ExternalJavaDocAction extends AnAction {
}
}
- public static void showExternalJavadoc(List<String> urls) {
+ public static void showExternalJavadoc(List<String> urls, Component component) {
final HashSet<String> set = new HashSet<String>(urls);
if (set.size() > 1) {
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<String>("Choose external documentation root", ArrayUtil.toStringArray(set)) {
@@ -98,7 +99,7 @@ public class ExternalJavaDocAction extends AnAction {
BrowserUtil.browse(selectedValue);
return FINAL_CHOICE;
}
- }).showInBestPositionFor(DataManager.getInstance().getDataContext());
+ }).showInBestPositionFor(DataManager.getInstance().getDataContext(component));
}
else if (set.size() == 1) {
BrowserUtil.browse(urls.get(0));
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionAction.java
index 91f5d2af767b..c939787fb632 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -44,7 +44,7 @@ import java.util.List;
public class GotoActionAction extends GotoActionBase implements DumbAware {
public static final Comparator<MatchResult> ELEMENTS_COMPARATOR = new Comparator<MatchResult>() {
@Override
- public int compare(MatchResult o1, MatchResult o2) {
+ public int compare(@NotNull MatchResult o1, @NotNull MatchResult o2) {
if (o1.elementName.equals(GotoActionModel.INTENTIONS_KEY)) return -1;
if (o2.elementName.equals(GotoActionModel.INTENTIONS_KEY)) return 1;
@@ -106,7 +106,7 @@ public class GotoActionAction extends GotoActionBase implements DumbAware {
}
else {
//element could be AnAction (SearchEverywhere)
- final AnAction action = element instanceof AnAction ? ((AnAction)element) : ((GotoActionModel.ActionWrapper)element).getAction();
+ final AnAction action = element instanceof AnAction ? (AnAction)element : ((GotoActionModel.ActionWrapper)element).getAction();
if (action != null) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java
index 83c42610be3d..f333c0f35db8 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java
@@ -52,7 +52,7 @@ import java.util.List;
/**
* @author Dmitry Avdeev
*/
-public class GotoRelatedFileAction extends AnAction {
+public class GotoRelatedSymbolAction extends AnAction {
@Override
public void update(AnActionEvent e) {
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/PowerSaveModeNotifier.java b/platform/lang-impl/src/com/intellij/ide/actions/PowerSaveModeNotifier.java
new file mode 100644
index 000000000000..91805bf32123
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/actions/PowerSaveModeNotifier.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.actions;
+
+import com.intellij.ide.PowerSaveMode;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationGroup;
+import com.intellij.notification.NotificationListener;
+import com.intellij.notification.NotificationType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.startup.StartupActivity;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.event.HyperlinkEvent;
+
+/**
+ * @author peter
+ */
+public class PowerSaveModeNotifier implements StartupActivity {
+ private static final NotificationGroup POWER_SAVE_MODE = NotificationGroup.balloonGroup("Power Save Mode");
+ private static final String IGNORE_POWER_SAVE_MODE = "ignore.power.save.mode";
+
+ @Override
+ public void runActivity(@NotNull Project project) {
+ if (PowerSaveMode.isEnabled()) {
+ notifyOnPowerSaveMode(project);
+ }
+ }
+
+ static void notifyOnPowerSaveMode(Project project) {
+ if (PropertiesComponent.getInstance().getBoolean(IGNORE_POWER_SAVE_MODE, false)) {
+ return;
+ }
+
+ String message = "Code insight and other background tasks are disabled." +
+ "<br/><a href=\"ignore\">Do not show again</a>" +
+ "<br/><a href=\"turnOff\">Disable Power Save Mode</a>";
+ POWER_SAVE_MODE.createNotification("Power save mode is on", message, NotificationType.WARNING, new NotificationListener() {
+ @Override
+ public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
+ final String description = event.getDescription();
+ if ("ignore".equals(description)) {
+ PropertiesComponent.getInstance().setValue(IGNORE_POWER_SAVE_MODE, "true");
+ notification.expire();
+ }
+ else if ("turnOff".equals(description)) {
+ PowerSaveMode.setEnabled(false);
+ notification.expire();
+ }
+ }
+ }).notify(project);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java
index 01edc2485778..62be241074b6 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.ide.actions;
import com.intellij.ide.IdeBundle;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -32,58 +32,48 @@ import com.intellij.psi.PsiManager;
public class ReloadFromDiskAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
- DataContext dataContext = e.getDataContext();
- final Project project = CommonDataKeys.PROJECT.getData(dataContext);
- final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
- if (editor == null) return;
- final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
- if (psiFile == null) return;
+ final Project project = e.getProject();
+ final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
+ if (project == null || editor == null) return;
+ final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+ if (file == null) return;
- int res = Messages.showOkCancelDialog(
- project,
- IdeBundle.message("prompt.reload.file.from.disk", psiFile.getVirtualFile().getPresentableUrl()),
- IdeBundle.message("title.reload.file"),
- Messages.getWarningIcon()
- );
+ String message = IdeBundle.message("prompt.reload.file.from.disk", file.getVirtualFile().getPresentableUrl());
+ int res = Messages.showOkCancelDialog(project, message, IdeBundle.message("title.reload.file"), Messages.getWarningIcon());
if (res != Messages.OK) return;
- CommandProcessor.getInstance().executeCommand(
- project, new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().runWriteAction(
- new Runnable() {
- @Override
- public void run() {
- PsiManager.getInstance(project).reloadFromDisk(psiFile);
+ Runnable command = new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(
+ new Runnable() {
+ @Override
+ public void run() {
+ if (!project.isDisposed()) {
+ file.getVirtualFile().refresh(false, false);
+ PsiManager.getInstance(project).reloadFromDisk(file);
}
}
- );
- }
- },
- IdeBundle.message("command.reload.from.disk"),
- null
- );
+ }
+ );
+ }
+ };
+ CommandProcessor.getInstance().executeCommand(project, command, IdeBundle.message("command.reload.from.disk"), null);
}
@Override
- public void update(AnActionEvent event){
- Presentation presentation = event.getPresentation();
- DataContext dataContext = event.getDataContext();
- Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (project == null){
- presentation.setEnabled(false);
- return;
- }
- Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
- if (editor == null){
- presentation.setEnabled(false);
- return;
- }
- Document document = editor.getDocument();
- PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
- if (psiFile == null || psiFile.getVirtualFile() == null){
- presentation.setEnabled(false);
+ public void update(AnActionEvent event) {
+ boolean enabled = false;
+
+ Project project = event.getProject();
+ Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext());
+ if (project != null && editor != null) {
+ PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+ if (file != null && file.getVirtualFile() != null) {
+ enabled = true;
+ }
}
+
+ event.getPresentation().setEnabled(enabled);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index 87ff26ca619e..996601065278 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -41,11 +41,13 @@ import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.TextComponentEditorAction;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -58,6 +60,7 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.IdeConfigurablesGroup;
import com.intellij.openapi.options.ex.ProjectConfigurablesGroup;
+import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.DumbAware;
@@ -114,6 +117,7 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* @author Konstantin Bulenkov
*/
+@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
public class SearchEverywhereAction extends AnAction implements CustomComponentAction, DumbAware{
public static final String SE_HISTORY_KEY = "SearchEverywhereHistoryKey";
public static final int SEARCH_FIELD_COLUMNS = 25;
@@ -125,24 +129,20 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private static final int MAX_SETTINGS = 5;
private static final int MAX_ACTIONS = 5;
private static final int MAX_RECENT_FILES = 10;
+ private static final int DEFAULT_MORE_STEP_COUNT = 15;
public static final int MAX_SEARCH_EVERYWHERE_HISTORY = 50;
private static final int POPUP_MAX_WIDTH = 600;
+ private static final Logger LOG = Logger.getInstance("#" + SearchEverywhereAction.class.getName());
private SearchEverywhereAction.MyListRenderer myRenderer;
MySearchTextField myPopupField;
- private GotoClassModel2 myClassModel;
- private GotoFileModel myFileModel;
- private GotoActionModel myActionModel;
- private GotoSymbolModel2 mySymbolsModel;
- private String[] myActions;
+ private volatile GotoClassModel2 myClassModel;
+ private volatile GotoFileModel myFileModel;
+ private volatile GotoActionModel myActionModel;
+ private volatile GotoSymbolModel2 mySymbolsModel;
+ private volatile String[] myActions;
private Component myFocusComponent;
private JBPopup myPopup;
- private int myMoreClassesIndex = -1;
- private int myMoreFilesIndex = -1;
- private int myMoreActionsIndex = -1;
- private int myMoreSettingsIndex = -1;
- private int myMoreSymbolsIndex = -1;
- private TitleIndexes myTitleIndexes;
private Map<String, String> myConfigurables = new HashMap<String, String>();
private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, ApplicationManager.getApplication());
@@ -158,8 +158,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private static AtomicBoolean ourOtherKeyWasPressed = new AtomicBoolean(false);
private static AtomicLong ourLastTimePressed = new AtomicLong(0);
private static AtomicBoolean showAll = new AtomicBoolean(false);
- private ArrayList<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
- private ArrayList<AnAction> myAlreadyAddedActions = new ArrayList<AnAction>();
private volatile ActionCallback myCurrentWorker = ActionCallback.DONE;
private int myHistoryIndex = 0;
boolean mySkipFocusGain = false;
@@ -258,7 +256,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}, null);
}
- private JBPopup myBalloon;
+ private volatile JBPopup myBalloon;
private int myPopupActualWidth;
private Component myFocusOwner;
private ChooseByNamePopup myFileChooseByName;
@@ -439,7 +437,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
search.setText("");
search.getTextEditor().setForeground(UIUtil.getLabelForeground());
- myTitleIndexes = new TitleIndexes();
+ //titleIndex = new TitleIndexes();
editor.setColumns(SEARCH_FIELD_COLUMNS);
myFocusComponent = e.getOppositeComponent();
//noinspection SSBasedInspection
@@ -476,10 +474,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private void jumpNextGroup(boolean forward) {
final int index = myList.getSelectedIndex();
+ final SearchListModel model = getModel();
if (index >= 0) {
- final int newIndex = forward ? myTitleIndexes.next(index) : myTitleIndexes.prev(index);
+ final int newIndex = forward ? model.next(index) : model.prev(index);
myList.setSelectedIndex(newIndex);
- int more = myTitleIndexes.next(newIndex) - 1;
+ int more = model.next(newIndex) - 1;
if (more < newIndex) {
more = myList.getItemsCount() - 1;
}
@@ -488,70 +487,73 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
- private void onFocusLost() {
+ private SearchListModel getModel() {
+ return (SearchListModel)myList.getModel();
+ }
+
+ private ActionCallback onFocusLost() {
+ final ActionCallback result = new ActionCallback();
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (myCalcThread != null) {
- myCalcThread.cancel();
- myCalcThread = null;
- }
- myAlarm.cancelAllRequests();
- clearModel();
- if (myBalloon != null && !myBalloon.isDisposed() && myPopup != null && !myPopup.isDisposed()) {
- myBalloon.cancel();
- myPopup.cancel();
- }
-
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- ActionToolbarImpl.updateAllToolbarsImmediately();
+ try {
+ if (myCalcThread != null) {
+ myCalcThread.cancel();
+ //myCalcThread = null;
}
- });
+ myAlarm.cancelAllRequests();
+ if (myBalloon != null && !myBalloon.isDisposed() && myPopup != null && !myPopup.isDisposed()) {
+ myBalloon.cancel();
+ myPopup.cancel();
+ }
+
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ActionToolbarImpl.updateAllToolbarsImmediately();
+ }
+ });
+ } finally {
+ result.setDone();
+ }
}
});
- }
-
- private void clearModel() {
- myMoreClassesIndex = -1;
- myMoreFilesIndex = -1;
- myMoreActionsIndex = -1;
- myMoreSettingsIndex = -1;
+ return result;
}
private SearchTextField getField() {
return myPopupField;
}
- private void doNavigate(int index) {
+ private void doNavigate(final int index) {
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
final Executor executor = ourShiftIsPressed.get()
? DefaultRunExecutor.getRunExecutorInstance()
: ExecutorRegistry.getInstance().getExecutorById(ToolWindowId.DEBUG);
assert project != null;
-
+ final SearchListModel model = getModel();
if (isMoreItem(index)) {
- String actionId = null;
- if (index == myMoreClassesIndex) actionId = "GotoClass";
- else if (index == myMoreFilesIndex) actionId = "GotoFile";
- else if (index == myMoreSettingsIndex) actionId = "ShowSettings";
- else if (index == myMoreActionsIndex) actionId = "GotoAction";
- else if (index == myMoreSymbolsIndex) actionId = "GotoSymbol";
- if (actionId != null) {
- final AnAction action = ActionManager.getInstance().getAction(actionId);
- GotoActionAction.openOptionOrPerformAction(action, getField().getText(), project, getField(), myActionEvent);
- //noinspection SSBasedInspection
- ApplicationManager.getApplication().invokeLater(new Runnable() {
+ final String pattern = myPopupField.getText();
+ WidgetID wid = null;
+ if (index == model.moreIndex.classes) wid = WidgetID.CLASSES;
+ else if (index == model.moreIndex.files) wid = WidgetID.FILES;
+ else if (index == model.moreIndex.settings) wid = WidgetID.SETTINGS;
+ else if (index == model.moreIndex.actions) wid = WidgetID.ACTIONS;
+ else if (index == model.moreIndex.symbols) wid = WidgetID.SYMBOLS;
+ else if (index == model.moreIndex.runConfigurations) wid = WidgetID.RUN_CONFIGURATIONS;
+ if (wid != null) {
+ final WidgetID widgetID = wid;
+ myCurrentWorker.doWhenProcessed(new Runnable() {
@Override
public void run() {
- if (myPopup != null && myPopup.isVisible()) {
- myPopup.cancel();
- }
+ myCalcThread = new CalcThread(project, pattern, true);
+ myPopupActualWidth = 0;
+ myCurrentWorker = myCalcThread.insert(index, widgetID);
}
});
+
return;
}
}
@@ -570,19 +572,25 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myList.repaint();
return;
}
+ Runnable onDone = null;
AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
if (value instanceof PsiElement) {
- NavigationUtil.activateFileWithPsiElement((PsiElement)value, true);
+ onDone = new Runnable() {
+ public void run() {
+ NavigationUtil.activateFileWithPsiElement((PsiElement)value, true);
+ }
+ };
return;
}
else if (isVirtualFile(value)) {
- OpenFileDescriptor navigatable = new OpenFileDescriptor(project, (VirtualFile)value);
- if (navigatable.canNavigate()) {
- navigatable.navigate(true);
- return;
- }
+ onDone = new Runnable() {
+ public void run() {
+ OpenSourceUtil.navigate(true, new OpenFileDescriptor(project, (VirtualFile)value));
+ }
+ };
+ return;
}
else if (isActionValue(value) || isSetting(value) || isRunConfiguration(value)) {
focusManager.requestDefaultFocus(true);
@@ -600,29 +608,40 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
((ChooseRunConfigurationPopup.ItemWrapper)value).perform(project, executor, DataManager.getInstance().getDataContext(c));
} else {
GotoActionAction.openOptionOrPerformAction(value, pattern, project, c, event);
+ if (isToolWindowAction(value)) return;
}
}
});
return;
}
else if (value instanceof Navigatable) {
- IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
+ onDone = new Runnable() {
@Override
public void run() {
OpenSourceUtil.navigate(true, (Navigatable)value);
}
- });
+ };
+ return;
}
}
finally {
token.finish();
- onFocusLost();
+ final ActionCallback callback = onFocusLost();
+ if (onDone != null) {
+ callback.doWhenDone(onDone);
+ }
}
focusManager.requestDefaultFocus(true);
}
private boolean isMoreItem(int index) {
- return index == myMoreClassesIndex || index == myMoreFilesIndex || index == myMoreSettingsIndex || index == myMoreActionsIndex || index == myMoreSymbolsIndex;
+ final SearchListModel model = getModel();
+ return index == model.moreIndex.classes ||
+ index == model.moreIndex.files ||
+ index == model.moreIndex.settings ||
+ index == model.moreIndex.actions ||
+ index == model.moreIndex.symbols ||
+ index == model.moreIndex.runConfigurations;
}
private void rebuildList(final String pattern) {
@@ -630,6 +649,9 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
if (myCalcThread != null && !myCurrentWorker.isProcessed()) {
myCurrentWorker = myCalcThread.cancel();
}
+ if (myCalcThread != null && !myCalcThread.isCanceled()) {
+ myCalcThread.cancel();
+ }
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(getField().getTextEditor()));
assert project != null;
@@ -637,7 +659,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myCurrentWorker.doWhenProcessed(new Runnable() {
@Override
public void run() {
- myCalcThread = new CalcThread(project, pattern);
+ myCalcThread = new CalcThread(project, pattern, false);
myPopupActualWidth = 0;
myCurrentWorker = myCalcThread.start();
}
@@ -744,8 +766,19 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myBalloon.getContent().setBorder(new EmptyBorder(0,0,0,0));
final Window window = WindowManager.getInstance().suggestParentWindow(e.getProject());
- Component parent = UIUtil.findUltimateParent(window);
+ //noinspection ConstantConditions
+ e.getProject().getMessageBus().connect(myBalloon).subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
+ @Override
+ public void enteredDumbMode() {
+ }
+
+ @Override
+ public void exitDumbMode() {
+ rebuildList(myPopupField.getText());
+ }
+ });
+ Component parent = UIUtil.findUltimateParent(window);
registerDataProvider(panel);
final RelativePoint showPoint;
if (me != null) {
@@ -1014,7 +1047,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
bg = cmp.getBackground();
}
myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 2, 0));
- String title = myTitleIndexes.getTitle(index);
+ String title = getModel().titleIndex.getTitle(index);
myMainPanel.removeAll();
if (title != null) {
myTitle.setText(title);
@@ -1123,7 +1156,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myTitle.setFont(getTitleFont());
int index = 0;
while (index < model.getSize()) {
- String title = myTitleIndexes.getTitle(index);
+ String title = getModel().titleIndex.getTitle(index);
if (title != null) {
myTitle.setText(title);
}
@@ -1182,17 +1215,23 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return UIUtil.getLabelFont().deriveFont(UIUtil.getFontSize(UIUtil.FontSize.SMALL));
}
+ enum WidgetID {CLASSES, FILES, ACTIONS, SETTINGS, SYMBOLS, RUN_CONFIGURATIONS}
+
@SuppressWarnings("SSBasedInspection")
private class CalcThread implements Runnable {
private final Project project;
private final String pattern;
- private ProgressIndicator myProgressIndicator = new ProgressIndicatorBase();
+ private final ProgressIndicator myProgressIndicator = new ProgressIndicatorBase();
private final ActionCallback myDone = new ActionCallback();
- private SearchListModel myListModel = new SearchListModel();
+ private final SearchListModel myListModel;
+ private final ArrayList<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
+ private final ArrayList<AnAction> myAlreadyAddedActions = new ArrayList<AnAction>();
- public CalcThread(Project project, String pattern) {
+
+ public CalcThread(Project project, String pattern, boolean reuseModel) {
this.project = project;
this.pattern = pattern;
+ myListModel = reuseModel ? (SearchListModel)myList.getModel() : new SearchListModel();
}
@Override
@@ -1209,10 +1248,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
//noinspection unchecked
myList.setModel(myListModel);
- myTitleIndexes.clear();
- clearModel();
- myAlreadyAddedFiles.clear();
- myAlreadyAddedActions.clear();
}
});
@@ -1236,7 +1271,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}, true);
runReadAction(new Runnable() {
public void run() {
- buildClasses(pattern, false);
+ buildClasses(pattern);
}
}, true);
runReadAction(new Runnable() {
@@ -1254,11 +1289,15 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}, true);
}
- catch (Exception ignore) {
+ catch (ProcessCanceledException ignore) {
+ myDone.setRejected();
+ }
+ catch (Exception e) {
+ LOG.error(e);
myDone.setRejected();
}
finally {
- if (!myProgressIndicator.isCanceled()) {
+ if (!isCanceled()) {
myList.getEmptyText().setText(StatusText.DEFAULT_EMPTY_TEXT);
updatePopup();
}
@@ -1277,46 +1316,47 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
protected void check() {
myProgressIndicator.checkCanceled();
+ if (myDone.isRejected()) throw new ProcessCanceledException();
+ if (myBalloon == null || myBalloon.isDisposed()) throw new ProcessCanceledException();
}
- private void buildToolWindows(String pattern) {
- if (myActions == null) {
- myActions = myActionModel.getNames(true);
- }
- final HashSet<AnAction> toolWindows = new HashSet<AnAction>();
- List<MatchResult> matches = collectResults(pattern, myActions, myActionModel);
- for (MatchResult o : matches) {
- check();
- Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
- for (Object object : objects) {
- check();
- if (isToolWindowAction(object) && toolWindows.size() < MAX_TOOL_WINDOWS) {
- toolWindows.add(((GotoActionModel.ActionWrapper)object).getAction());
+ private synchronized void buildToolWindows(String pattern) {
+ final List<ActivateToolWindowAction> actions = new ArrayList<ActivateToolWindowAction>();
+ for (ActivateToolWindowAction action : ToolWindowsGroup.getToolWindowActions(project)) {
+ String text = action.getTemplatePresentation().getText();
+ if (text != null && StringUtil.startsWithIgnoreCase(text, pattern)) {
+ actions.add(action);
+
+ if (actions.size() == MAX_TOOL_WINDOWS) {
+ break;
}
}
}
check();
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ if (actions.isEmpty()) {
+ return;
+ }
+
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (myProgressIndicator.isCanceled()) return;
- if (toolWindows.size() > 0) {
- myTitleIndexes.toolWindows = myListModel.size();
- for (Object toolWindow : toolWindows) {
- myListModel.addElement(toolWindow);
- }
+ myListModel.titleIndex.toolWindows = myListModel.size();
+ for (Object toolWindow : actions) {
+ myListModel.addElement(toolWindow);
}
}
});
}
- private void buildActionsAndSettings(String pattern) {
- final Set<Object> actions = new HashSet<Object>();
- final Set<Object> settings = new HashSet<Object>();
+ private SearchResult getActionsOrSettings(final String pattern, final int max, final boolean actions) {
+ final SearchResult result = new SearchResult();
final MinusculeMatcher matcher = new MinusculeMatcher("*" +pattern, NameUtil.MatchingCaseSensitivity.NONE);
if (myActions == null) {
+ if (myActionModel == null) {
+ myActionModel = createActionModel();
+ }
myActions = myActionModel.getNames(true);
}
@@ -1327,144 +1367,86 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
for (Object object : objects) {
check();
- if (isSetting(object) && settings.size() < MAX_SETTINGS) {
+ if (myListModel.contains(object)) continue;
+
+ if (!actions && isSetting(object)) {
if (matcher.matches(getSettingText((OptionDescription)object))) {
- settings.add(object);
+ result.add(object);
}
+ } else if (actions && !isToolWindowAction(object) && isActionValue(object)) {
+ result.add(object);
}
- else if (!isToolWindowAction(object) && isActionValue(object) && actions.size() < MAX_ACTIONS) {
- actions.add(object);
- }
+ if (result.size() == max) return result;
}
}
+ return result;
+ }
+
+ private synchronized void buildActionsAndSettings(String pattern) {
+ final SearchResult actions = getActionsOrSettings(pattern, MAX_ACTIONS, true);
+ final SearchResult settings = getActionsOrSettings(pattern, MAX_SETTINGS, false);
check();
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (myProgressIndicator.isCanceled()) return;
+ if (isCanceled()) return;
if (actions.size() > 0) {
- myTitleIndexes.actions = myListModel.size();
+ myListModel.titleIndex.actions = myListModel.size();
for (Object action : actions) {
myListModel.addElement(action);
}
}
- myMoreActionsIndex = actions.size() >= MAX_ACTIONS ? myListModel.size() - 1 : -1;
+ myListModel.moreIndex.actions = actions.size() >= MAX_ACTIONS ? myListModel.size() - 1 : -1;
if (settings.size() > 0) {
- myTitleIndexes.settings = myListModel.size();
+ myListModel.titleIndex.settings = myListModel.size();
for (Object setting : settings) {
myListModel.addElement(setting);
}
}
- myMoreSettingsIndex = settings.size() >= MAX_SETTINGS ? myListModel.size() - 1 : -1;
+ myListModel.moreIndex.settings = settings.size() >= MAX_SETTINGS ? myListModel.size() - 1 : -1;
}
});
}
- private void buildFiles(final String pattern) {
- int filesCounter = 0;
- final Set<Object> elements = new LinkedHashSet<Object>();
- final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
- myFileChooseByName.getProvider().filterElements(myFileChooseByName, pattern, true,
- myProgressIndicator, new Processor<Object>() {
- @Override
- public boolean process(Object o) {
- VirtualFile file = null;
- if (o instanceof VirtualFile) {
- file = (VirtualFile)o;
- } else if (o instanceof PsiFile) {
- file = ((PsiFile)o).getVirtualFile();
- } else if (o instanceof PsiDirectory) {
- file = ((PsiDirectory)o).getVirtualFile();
- }
- if (file != null
- && !(pattern.indexOf(' ') != -1 && file.getName().indexOf(' ') == -1)
- && (showAll.get() || scope.accept(file))) {
- elements.add(o);
- }
- return elements.size() < 30;
- }
- });
- final List<Object> files = new ArrayList<Object>();
- for (Object object : elements) {
- if (filesCounter > MAX_FILES) break;
- if (!myListModel.contains(object)) {
- if (object instanceof PsiFile) {
- object = ((PsiFile)object).getVirtualFile();
- }
- if ((object instanceof VirtualFile && !myAlreadyAddedFiles.contains(object))
- || object instanceof PsiDirectory) {
- files.add(object);
- if (object instanceof VirtualFile) {
- myAlreadyAddedFiles.add((VirtualFile)object);
- }
- filesCounter++;
- if (filesCounter > MAX_FILES) break;
- }
- }
- }
-
+ private synchronized void buildFiles(final String pattern) {
+ final SearchResult files = getFiles(pattern, MAX_FILES);
check();
if (files.size() > 0) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.files = myListModel.size();
- for (Object file : files) {
- myListModel.addElement(file);
- }
- myMoreFilesIndex = files.size() >= MAX_FILES ? myListModel.size() - 1 : -1;
+ if (isCanceled()) return;
+ myListModel.titleIndex.files = myListModel.size();
+ for (Object file : files) {
+ myListModel.addElement(file);
}
+ myListModel.moreIndex.files = files.needMore ? myListModel.size() - 1 : -1;
}
});
}
}
- private void buildSymbols(final String pattern) {
- int symbolsCounter = 0;
- final Set<Object> elements = new LinkedHashSet<Object>();
- final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
- mySymbolsChooseByName.getProvider().filterElements(mySymbolsChooseByName, pattern, false,
- myProgressIndicator, new Processor<Object>() {
- @Override
- public boolean process(Object o) {
- if (o instanceof PsiElement) {
- final PsiElement element = (PsiElement)o;
- final PsiFile file = element.getContainingFile();
- if (file != null && file.getVirtualFile() != null && scope.accept(file.getVirtualFile())) {
- elements.add(o);
- }
- }
- return elements.size() < 30;
- }
- });
- final List<Object> symbols = new ArrayList<Object>();
- for (Object object : elements) {
- if (symbolsCounter > MAX_SYMBOLS) break;
- if (!myListModel.contains(object)) {
- symbols.add(object);
- symbolsCounter++;
- if (symbolsCounter > MAX_SYMBOLS) break;
- }
- }
+
+
+ private synchronized void buildSymbols(final String pattern) {
+ final SearchResult symbols = getSymbols(pattern, MAX_SYMBOLS);
check();
if (symbols.size() > 0) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.symbols = myListModel.size();
- for (Object file : symbols) {
- myListModel.addElement(file);
- }
- myMoreSymbolsIndex = symbols.size() >= MAX_SYMBOLS ? myListModel.size() - 1 : -1;
+ if (isCanceled()) return;
+ myListModel.titleIndex.symbols = myListModel.size();
+ for (Object file : symbols) {
+ myListModel.addElement(file);
}
+ myListModel.moreIndex.symbols = symbols.needMore ? myListModel.size() - 1 : -1;
}
});
}
@@ -1488,8 +1470,26 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return null;
}
- private void buildRunConfigurations(String pattern) {
- final List<Object> runConfigurations = new ArrayList<Object>();
+ private synchronized void buildRunConfigurations(String pattern) {
+ final SearchResult runConfigurations = getConfigurations(pattern, MAX_RUN_CONFIGURATION);
+
+ if (runConfigurations.size() > 0) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (isCanceled()) return;
+ myListModel.titleIndex.runConfigurations = myListModel.size();
+ for (Object runConfiguration : runConfigurations) {
+ myListModel.addElement(runConfiguration);
+ }
+ myListModel.moreIndex.runConfigurations = runConfigurations.needMore ? myListModel.getSize() - 1 : -1;
+ }
+ });
+ }
+ }
+
+ private SearchResult getConfigurations(String pattern, int max) {
+ SearchResult configurations = new SearchResult();
MinusculeMatcher matcher = new MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
final ChooseRunConfigurationPopup.ItemWrapper[] wrappers =
ChooseRunConfigurationPopup.createSettingsList(project, new ExecutorProvider() {
@@ -1500,83 +1500,129 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}, false);
check();
for (ChooseRunConfigurationPopup.ItemWrapper wrapper : wrappers) {
- if (matcher.matches(wrapper.getText())) {
- runConfigurations.add(wrapper);
+ if (matcher.matches(wrapper.getText()) && !myListModel.contains(wrapper)) {
+ if (configurations.size() == max) {
+ configurations.needMore = true;
+ break;
+ }
+ configurations.add(wrapper);
}
check();
}
- if (runConfigurations.size() > 0) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ return configurations;
+ }
+
+
+ private synchronized void buildClasses(final String pattern) {
+ if (pattern.indexOf('.') != -1) {
+ //todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere
+ //todo[kb] we don't want to see Java classes started with Png or Xml. This approach should be reworked someday.
+ return;
+ }
+ check();
+
+ final SearchResult classes = getClasses(pattern, showAll.get(), MAX_CLASSES);
+
+ check();
+
+ if (classes.size() > 0) {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.runConfigurations = myListModel.size();
- for (Object runConfiguration : runConfigurations) {
- myListModel.addElement(runConfiguration);
- }
- myMoreFilesIndex = runConfigurations.size() >= MAX_RUN_CONFIGURATION ? myListModel.size() - 1 : -1;
+ if (isCanceled()) return;
+ myListModel.titleIndex.classes = myListModel.size();
+ for (Object file : classes) {
+ myListModel.addElement(file);
+ }
+ myListModel.moreIndex.classes = -1;
+ if (classes.needMore) {
+ myListModel.moreIndex.classes = myListModel.size() - 1;
}
}
});
}
-
}
- private void buildClasses(final String pattern, boolean includeLibraries) {
- if (pattern.indexOf('.') != -1) {
- //todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere
- //todo[kb] we don't want to see Java classes started with Png or Xml. This approach should be reworked someday.
- return;
- }
+ private SearchResult getSymbols(String pattern, final int max) {
+ final SearchResult symbols = new SearchResult();
+ final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
+ mySymbolsChooseByName.getProvider().filterElements(mySymbolsChooseByName, pattern, false,
+ myProgressIndicator, new Processor<Object>() {
+ @Override
+ public boolean process(Object o) {
+ if (o instanceof PsiElement) {
+ final PsiElement element = (PsiElement)o;
+ final PsiFile file = element.getContainingFile();
+ if (!myListModel.contains(o) &&
+ //some elements are non-physical like DB columns
+ (file == null || (file.getVirtualFile() != null && scope.accept(file.getVirtualFile())))) {
+ symbols.add(o);
+ }
+ }
+ symbols.needMore = symbols.size() == max;
+ return !symbols.needMore;
+ }
+ });
+ return symbols;
+ }
- boolean includeLibs = includeLibraries || showAll.get();
- int filesCounter = 0;
- final Set<Object> elements = new LinkedHashSet<Object>();
+ private SearchResult getClasses(String pattern, boolean includeLibs, final int max) {
+ final SearchResult classes = new SearchResult();
myClassChooseByName.getProvider().filterElements(myClassChooseByName, pattern, includeLibs,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
- elements.add(o);
- return elements.size() < 30;
+ if (o instanceof PsiElement && !myListModel.contains(o) && !classes.contains(o)) {
+ if (classes.size() == max) {
+ classes.needMore = true;
+ return false;
+ }
+ classes.add(o);
+ }
+ return true;
}
});
- final List<Object> classes = new ArrayList<Object>();
- for (Object object : elements) {
- check();
- if (filesCounter > MAX_FILES) break;
- if (!myListModel.contains(object)) {
- if (object instanceof PsiElement) {
- classes.add(object);
- }
- filesCounter++;
- if (filesCounter > MAX_FILES) break;
- }
+ if (!includeLibs && classes.isEmpty()) {
+ return getClasses(pattern, true, max);
}
+ return classes;
+ }
- check();
-
- if (classes.size() > 0) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ private SearchResult getFiles(final String pattern, final int max) {
+ final SearchResult files = new SearchResult();
+ final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
+ myFileChooseByName.getProvider().filterElements(myFileChooseByName, pattern, true,
+ myProgressIndicator, new Processor<Object>() {
@Override
- public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.classes = myListModel.size();
- for (Object file : classes) {
- myListModel.addElement(file);
+ public boolean process(Object o) {
+ VirtualFile file = null;
+ if (o instanceof VirtualFile) {
+ file = (VirtualFile)o;
+ } else if (o instanceof PsiFile) {
+ file = ((PsiFile)o).getVirtualFile();
+ } else if (o instanceof PsiDirectory) {
+ file = ((PsiDirectory)o).getVirtualFile();
+ }
+ if (file != null
+ && !(pattern.indexOf(' ') != -1 && file.getName().indexOf(' ') == -1)
+ && (showAll.get() || scope.accept(file)
+ && !myListModel.contains(file)
+ && !myAlreadyAddedFiles.contains(file))
+ && !files.contains(file)) {
+ if (files.size() == max) {
+ files.needMore = true;
+ return false;
}
- myMoreClassesIndex = classes.size() >= MAX_CLASSES ? myListModel.size() - 1 : -1;
+ files.add(file);
}
+ return true;
}
});
- } else {
- if (!includeLibs) {
- buildClasses(pattern, true);
- }
- }
+ return files;
}
- private void buildRecentFiles(String pattern) {
+ private synchronized void buildRecentFiles(String pattern) {
final MinusculeMatcher matcher = new MinusculeMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
final List<VirtualFile> selected = Arrays.asList(FileEditorManager.getInstance(project).getSelectedFiles());
@@ -1592,21 +1638,24 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
if (files.size() > 0) {
myAlreadyAddedFiles.addAll(files);
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.recentFiles = myListModel.size();
- for (Object file : files) {
- myListModel.addElement(file);
- }
+ if (isCanceled()) return;
+ myListModel.titleIndex.recentFiles = myListModel.size();
+ for (Object file : files) {
+ myListModel.addElement(file);
}
}
});
}
}
- private void buildTopHit(String pattern) {
+ private boolean isCanceled() {
+ return myProgressIndicator.isCanceled() || myDone.isRejected();
+ }
+
+ private synchronized void buildTopHit(String pattern) {
final List<Object> elements = new ArrayList<Object>();
final HistoryItem history = myHistoryItem;
if (history != null) {
@@ -1695,21 +1744,40 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
provider.consumeTopHits(pattern, consumer);
}
if (elements.size() > 0) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
+ SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- if (!myProgressIndicator.isCanceled()) {
- myTitleIndexes.topHit = myListModel.size();
- for (Object element : elements) {
- myListModel.addElement(element);
+ if (isCanceled()) return;
+
+
+ for (Object element : elements.toArray()) {
+ if (element instanceof AnAction) {
+ final AnAction action = (AnAction)element;
+ final AnActionEvent e = new AnActionEvent(myActionEvent.getInputEvent(),
+ myActionEvent.getDataContext(),
+ myActionEvent.getPlace(),
+ action.getTemplatePresentation(),
+ myActionEvent.getActionManager(),
+ myActionEvent.getModifiers());
+ ActionUtil.performDumbAwareUpdate(action, e, false);
+ final Presentation presentation = e.getPresentation();
+ if (!presentation.isEnabled() || !presentation.isVisible() || StringUtil.isEmpty(presentation.getText())) {
+ elements.remove(element);
+ }
+ if (isCanceled()) return;
}
}
+ if (isCanceled() || elements.isEmpty()) return;
+ myListModel.titleIndex.topHit = myListModel.size();
+ for (Object element : elements) {
+ myListModel.addElement(element);
+ }
}
});
}
}
- private void checkModelsUpToDate() {
+ private synchronized void checkModelsUpToDate() {
if (myClassModel == null) {
myClassModel = new GotoClassModel2(project);
myFileModel = new GotoFileModel(project);
@@ -1816,7 +1884,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
if (names == null) return Collections.emptyList();
pattern = ChooseByNamePopup.getTransformedPattern(pattern, model);
pattern = DefaultChooseByNameItemProvider.getNamePattern(model, pattern);
- if (model != myFileModel && !pattern.startsWith("*") && pattern.length() > 1) {
+ if (model != myFileModel && model != myActionModel && !pattern.startsWith("*") && pattern.length() > 1) {
pattern = "*" + pattern;
}
final ArrayList<MatchResult> results = new ArrayList<MatchResult>();
@@ -1865,6 +1933,69 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
public ActionCallback cancel() {
myProgressIndicator.cancel();
+ myDone.setRejected();
+ return myDone;
+ }
+
+ public ActionCallback insert(final int index, final WidgetID id) {
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ public void run() {
+ runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final SearchResult result
+ = id == WidgetID.CLASSES ? getClasses(pattern, showAll.get(), DEFAULT_MORE_STEP_COUNT)
+ : id == WidgetID.FILES ? getFiles(pattern, DEFAULT_MORE_STEP_COUNT)
+ : id == WidgetID.RUN_CONFIGURATIONS ? getConfigurations(pattern, DEFAULT_MORE_STEP_COUNT)
+ : id == WidgetID.SYMBOLS ? getSymbols(pattern, DEFAULT_MORE_STEP_COUNT)
+ : id == WidgetID.ACTIONS ? getActionsOrSettings(pattern, DEFAULT_MORE_STEP_COUNT, true)
+ : id == WidgetID.SETTINGS ? getActionsOrSettings(pattern, DEFAULT_MORE_STEP_COUNT, false)
+ : new SearchResult();
+
+ check();
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ int shift = 0;
+ int i = index+1;
+ for (Object o : result) {
+ //noinspection unchecked
+ myListModel.insertElementAt(o, i);
+ shift++;
+ i++;
+ }
+ MoreIndex moreIndex = myListModel.moreIndex;
+ myListModel.titleIndex.shift(index, shift);
+ moreIndex.shift(index, shift);
+
+ if (!result.needMore) {
+ switch (id) {
+ case CLASSES: moreIndex.classes = -1; break;
+ case FILES: moreIndex.files = -1; break;
+ case ACTIONS: moreIndex.actions = -1; break;
+ case SETTINGS: moreIndex.settings = -1; break;
+ case SYMBOLS: moreIndex.symbols = -1; break;
+ case RUN_CONFIGURATIONS: moreIndex.runConfigurations = -1; break;
+ }
+ }
+ ListScrollingUtil.selectItem(myList, index);
+ myDone.setDone();
+ }
+ catch (Exception e) {
+ myDone.setRejected();
+ }
+ }
+ });
+ }
+ catch (Exception e) {
+ myDone.setRejected();
+ }
+ }
+ }, true);
+ }
+ });
return myDone;
}
@@ -1879,34 +2010,44 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myBalloon.cancel();
myBalloon = null;
}
- myFileModel = null;
- if (myFileChooseByName != null) {
- myFileChooseByName.close(false);
- myFileChooseByName = null;
- }
- if (myClassChooseByName != null) {
- myClassChooseByName.close(false);
- myClassChooseByName = null;
- }
- if (mySymbolsChooseByName != null) {
- mySymbolsChooseByName.close(false);
- mySymbolsChooseByName = null;
- }
- myClassModel = null;
- myActionModel = null;
- myActions = null;
- mySymbolsModel = null;
- myConfigurables.clear();
- myFocusComponent = null;
- myContextComponent = null;
- myFocusOwner = null;
- myRenderer.myProject = null;
- myCalcThread = null;
- myPopup = null;
- myHistoryIndex = 0;
- myPopupActualWidth = 0;
- myCurrentWorker = ActionCallback.DONE;
- showAll.set(false);
+ myCurrentWorker.doWhenProcessed(new Runnable() {
+ @Override
+ public void run() {
+ myFileModel = null;
+ if (myFileChooseByName != null) {
+ myFileChooseByName.close(false);
+ myFileChooseByName = null;
+ }
+ if (myClassChooseByName != null) {
+ myClassChooseByName.close(false);
+ myClassChooseByName = null;
+ }
+ if (mySymbolsChooseByName != null) {
+ mySymbolsChooseByName.close(false);
+ mySymbolsChooseByName = null;
+ }
+ final Object lock = myCalcThread;
+ if (lock != null) {
+ synchronized (lock) {
+ myClassModel = null;
+ myActionModel = null;
+ myActions = null;
+ mySymbolsModel = null;
+ myConfigurables.clear();
+ myFocusComponent = null;
+ myContextComponent = null;
+ myFocusOwner = null;
+ myRenderer.myProject = null;
+ myPopup = null;
+ myHistoryIndex = 0;
+ myPopupActualWidth = 0;
+ myCurrentWorker = ActionCallback.DONE;
+ showAll.set(false);
+ myCalcThread = null;
+ }
+ }
+ }
+ });
mySkipFocusGain = false;
}
@@ -2007,16 +2148,34 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
- static class TitleIndexes {
- int topHit;
- int recentFiles;
- int runConfigurations;
- int classes;
- int files;
- int actions;
- int settings;
- int toolWindows;
- int symbols;
+ static class MoreIndex {
+ volatile int classes = -1;
+ volatile int files = -1;
+ volatile int actions = -1;
+ volatile int settings = -1;
+ volatile int symbols = -1;
+ volatile int runConfigurations = -1;
+
+ public void shift(int index, int shift) {
+ if (runConfigurations >= index) runConfigurations += shift;
+ if (classes >= index) classes += shift;
+ if (files >= index) files += shift;
+ if (actions >= index) actions += shift;
+ if (settings >= index) settings += shift;
+ if (symbols >= index) symbols += shift;
+ }
+ }
+
+ static class TitleIndex {
+ volatile int topHit = -1;
+ volatile int recentFiles = -1;
+ volatile int runConfigurations = -1;
+ volatile int classes = -1;
+ volatile int files = -1;
+ volatile int actions = -1;
+ volatile int settings = -1;
+ volatile int toolWindows = -1;
+ volatile int symbols = -1;
final String gotoClassTitle;
final String gotoFileTitle;
@@ -2027,7 +2186,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
final String gotoSymbolTitle;
static final String toolWindowsTitle = "Tool Windows";
- TitleIndexes() {
+ TitleIndex() {
String gotoClass = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoClass"));
gotoClassTitle = StringUtil.isEmpty(gotoClass) ? "Classes" : "Classes (" + gotoClass + ")";
String gotoFile = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoFile"));
@@ -2060,25 +2219,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return null;
}
- int next(int index) {
- int[] all = new int[]{topHit, recentFiles, runConfigurations, classes, files, actions, settings, toolWindows, symbols};
- Arrays.sort(all);
- for (int next : all) {
- if (next > index) return next;
- }
- return 0;
- }
-
- int prev(int index) {
- int[] all = new int[]{topHit, recentFiles, runConfigurations, classes, files, actions, settings, toolWindows, symbols};
- Arrays.sort(all);
- for (int i = all.length-1; i >= 0; i--) {
- if (all[i] != -1 && all[i] < index) return all[i];
- }
- return all[all.length - 1];
- }
-
-
public void clear() {
topHit = -1;
runConfigurations = -1;
@@ -2089,6 +2229,20 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
settings = -1;
toolWindows = -1;
}
+
+ public void shift(int index, int shift) {
+ if (toolWindows != - 1 && toolWindows > index) toolWindows += shift;
+ if (settings != - 1 && settings > index) settings += shift;
+ if (actions != - 1 && actions > index) actions += shift;
+ if (files != - 1 && files > index) files += shift;
+ if (classes != - 1 && classes > index) classes += shift;
+ if (runConfigurations != - 1 && runConfigurations > index) runConfigurations += shift;
+ if (symbols != - 1 && symbols > index) symbols += shift;
+ }
+ }
+
+ static class SearchResult extends ArrayList<Object> {
+ boolean needMore;
}
@SuppressWarnings("unchecked")
@@ -2096,6 +2250,9 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@SuppressWarnings("UseOfObsoleteCollectionType")
Vector myDelegate;
+ volatile TitleIndex titleIndex = new TitleIndex();
+ volatile MoreIndex moreIndex = new MoreIndex();
+
private SearchListModel() {
super();
try {
@@ -2107,6 +2264,44 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
catch (IllegalAccessException ignore) {}
}
+ int next(int index) {
+ int[] all = getAll();
+ Arrays.sort(all);
+ for (int next : all) {
+ if (next > index) return next;
+ }
+ return 0;
+ }
+
+ int[] getAll() {
+ return new int[]{
+ titleIndex.topHit,
+ titleIndex.recentFiles,
+ titleIndex.runConfigurations,
+ titleIndex.classes,
+ titleIndex.files,
+ titleIndex.actions,
+ titleIndex.settings,
+ titleIndex.toolWindows,
+ titleIndex.symbols,
+ moreIndex.classes,
+ moreIndex.actions,
+ moreIndex.files,
+ moreIndex.settings,
+ moreIndex.symbols,
+ moreIndex.runConfigurations
+ };
+ }
+
+ int prev(int index) {
+ int[] all = getAll();
+ Arrays.sort(all);
+ for (int i = all.length-1; i >= 0; i--) {
+ if (all[i] != -1 && all[i] < index) return all[i];
+ }
+ return all[all.length - 1];
+ }
+
@Override
public void addElement(Object obj) {
myDelegate.add(obj);
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/TogglePowerSaveAction.java b/platform/lang-impl/src/com/intellij/ide/actions/TogglePowerSaveAction.java
index 3040982f253b..40028e0eb3e0 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/TogglePowerSaveAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/TogglePowerSaveAction.java
@@ -17,6 +17,7 @@ package com.intellij.ide.actions;
import com.intellij.ide.PowerSaveMode;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.DumbAware;
@@ -32,5 +33,8 @@ public class TogglePowerSaveAction extends ToggleAction implements DumbAware {
@Override
public void setSelected(AnActionEvent e, boolean state) {
PowerSaveMode.setEnabled(state);
+ if (state) {
+ PowerSaveModeNotifier.notifyOnPowerSaveMode(e.getData(CommonDataKeys.PROJECT));
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java
index e6cd53e811f8..d22e251ed4ca 100644
--- a/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java
+++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/Bookmark.java
@@ -27,6 +27,7 @@ import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
@@ -335,11 +336,15 @@ public class Bookmark implements Navigatable {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
- g.setColor(ICON_BACKGROUND_COLOR);
- g.fillRect(x, y, getIconWidth(), getIconHeight());
- g.setColor(JBColor.GRAY);
- g.drawRect(x, y, getIconWidth(), getIconHeight());
- myIcon.paintIcon(c, g, x, y);
+ Graphics2D g2 = (Graphics2D)g.create();
+ try {
+ Color gutterBackground = EditorColors.GUTTER_BACKGROUND.getDefaultColor();
+ g2.setColor(gutterBackground);
+ g2.fillRoundRect(x, y, getIconWidth(), getIconHeight(), 4, 4);
+ myIcon.paintIcon(c, g2, x, y);
+ } finally {
+ g2.dispose();
+ }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java
index 1a1e985f0a2c..28e417323281 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/FileTemplateUtil.java
@@ -272,7 +272,7 @@ public class FileTemplateUtil{
Velocity.evaluate(context, stringWriter, "", templateContent);
}
catch (final VelocityException e) {
- LOG.error("Error evaluating template:\n"+templateContent,e);
+ LOG.info("Error evaluating template:\n" + templateContent, e);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java
index 487b8f2dfeb1..9bfd75e0b4f9 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java
@@ -22,8 +22,10 @@ package com.intellij.ide.navigationToolbar;
import com.intellij.analysis.AnalysisScopeBundle;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.InternalModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Computable;
@@ -33,7 +35,6 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiFileSystemItemProcessor;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -113,7 +114,10 @@ public class DefaultNavBarExtension extends AbstractNavBarModelExtension {
new Computable<Boolean>() {
@Override
public Boolean compute() {
- return ContainerUtil.process(ModuleManager.getInstance(object).getModules(), processor);
+ for (Module module : ModuleManager.getInstance(object).getModules()) {
+ if (!(ModuleType.get(module) instanceof InternalModuleType) && !processor.process(module)) return false;
+ }
+ return true;
}
}
);
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
index a71fe8b4aef1..f41b9f5705df 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java
@@ -474,15 +474,17 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
private void doubleClick(final Object object) {
if (object instanceof Navigatable) {
- final Navigatable navigatable = (Navigatable)object;
+ Navigatable navigatable = (Navigatable)object;
if (navigatable.canNavigate()) {
navigatable.navigate(true);
}
}
else if (object instanceof Module) {
- final ProjectView projectView = ProjectView.getInstance(myProject);
- final AbstractProjectViewPane projectViewPane = projectView.getProjectViewPaneById(projectView.getCurrentViewId());
- projectViewPane.selectModule((Module)object, true);
+ ProjectView projectView = ProjectView.getInstance(myProject);
+ AbstractProjectViewPane projectViewPane = projectView.getProjectViewPaneById(projectView.getCurrentViewId());
+ if (projectViewPane != null) {
+ projectViewPane.selectModule((Module)object, true);
+ }
}
else if (object instanceof Project) {
return;
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java b/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java
index b18c16b36b18..024c3feabe5e 100644
--- a/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/CreateScratchFileAction.java
@@ -110,7 +110,12 @@ public class CreateScratchFileAction extends AnAction implements DumbAware {
}
}
- ListPopup popup = JBPopupFactory.getInstance().createListPopup(step);
+ ListPopup popup = updatePopupSize(JBPopupFactory.getInstance().createListPopup(step), languages);
+ popup.showCenteredInCurrentWindow(project);
+ }
+
+ @NotNull
+ public static ListPopup updatePopupSize(@NotNull ListPopup popup, @NotNull List<Language> languages) {
int nameLen = 0;
for (Language language : languages) {
nameLen = Math.max(nameLen, language.getDisplayName().length());
@@ -120,7 +125,7 @@ public class CreateScratchFileAction extends AnAction implements DumbAware {
size.height *= MAX_VISIBLE_SIZE;
popup.setSize(size);
}
- popup.showCenteredInCurrentWindow(project);
+ return popup;
}
public static void doAction(@NotNull Project project, @NotNull Language language) {
@@ -130,10 +135,10 @@ public class CreateScratchFileAction extends AnAction implements DumbAware {
}
@NotNull
- private static List<Language> getLanguages() {
+ public static List<Language> getLanguages() {
Set<Language> result = ContainerUtil.newTreeSet(new Comparator<Language>() {
@Override
- public int compare(Language l1, Language l2) {
+ public int compare(@NotNull Language l1, @NotNull Language l2) {
return l1.getDisplayName().compareTo(l2.getDisplayName());
}
});
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java
new file mode 100644
index 000000000000..fcd7372084ab
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.scratch;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.lang.Language;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.CustomStatusBarWidget;
+import com.intellij.openapi.wm.StatusBarWidget;
+import com.intellij.openapi.wm.impl.status.EditorBasedWidget;
+import com.intellij.openapi.wm.impl.status.TextPanel;
+import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.ui.ClickListener;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.util.FileContentUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.util.Collections;
+import java.util.List;
+
+class ScratchWidget extends EditorBasedWidget implements CustomStatusBarWidget.Multiframe, CustomStatusBarWidget {
+ public static final String ID = "Scratch";
+ private final MyTextPanel myPanel = new MyTextPanel();
+
+ public ScratchWidget(Project project) {
+ super(project);
+ new ClickListener() {
+ @Override
+ public boolean onClick(@NotNull MouseEvent e, int clickCount) {
+ Project project = getProject();
+ Editor editor = getEditor();
+ VirtualFile selectedFile = getSelectedFile();
+ if (project == null || editor == null || selectedFile == null) return false;
+
+ DataContext dataContext = createDataContext(editor, myPanel, selectedFile, project);
+ actionPerformed(dataContext);
+ update();
+ return true;
+ }
+ }.installOn(myPanel);
+ }
+
+ @NotNull
+ @Override
+ public String ID() {
+ return ID;
+ }
+
+ @Nullable
+ @Override
+ public WidgetPresentation getPresentation(@NotNull PlatformType type) {
+ return null;
+ }
+
+ private void update() {
+ VirtualFile file = getSelectedFile();
+ boolean enabled = checkEnabled(file);
+ if (enabled) {
+ Language lang = ((LightVirtualFile)file).getLanguage();
+ myPanel.setText(lang.getDisplayName());
+ myPanel.setBorder(WidgetBorder.INSTANCE);
+ myPanel.setIcon(getDefaultIcon(lang));
+ }
+ else {
+ myPanel.setBorder(null);
+ }
+ myPanel.setVisible(enabled);
+ if (myStatusBar != null) myStatusBar.updateWidget(ID);
+ }
+
+ @NotNull
+ public static DataContext createDataContext(Editor editor, Component component, VirtualFile selectedFile, Project project) {
+ DataContext parent = DataManager.getInstance().getDataContext(component);
+ DataContext context = SimpleDataContext.getSimpleContext(PlatformDataKeys.CONTEXT_COMPONENT.getName(), editor == null ? null : editor.getComponent(), parent);
+ DataContext projectContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PROJECT.getName(), project, context);
+ return SimpleDataContext.getSimpleContext(CommonDataKeys.VIRTUAL_FILE.getName(), selectedFile, projectContext);
+ }
+
+ void actionPerformed(DataContext context) {
+ ListPopup popup = createPopup(context);
+ if (popup != null) {
+ Dimension dimension = popup.getContent().getPreferredSize();
+ Point at = new Point(0, -dimension.height);
+ popup.show(new RelativePoint(myPanel, at));
+ }
+ }
+
+ @Nullable
+ private ListPopup createPopup(DataContext context) {
+ final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(context);
+ boolean enabled = checkEnabled(virtualFile);
+ if (!enabled) return null;
+
+ List<Language> languages = CreateScratchFileAction.getLanguages();
+ DefaultActionGroup group = createActionGroup(virtualFile, languages);
+ ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup("Choose language", group, context, JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
+ return CreateScratchFileAction.updatePopupSize(popup, languages);
+ }
+
+ @NotNull
+ private DefaultActionGroup createActionGroup(@NotNull VirtualFile virtualFile, @NotNull List<Language> languages) {
+ List<AnAction> list = ContainerUtil.newArrayListWithCapacity(languages.size());
+ for (Language language : languages) {
+ list.add(new ChangeLanguageAction(virtualFile, language));
+ }
+ return new DefaultActionGroup("Change language", list);
+ }
+
+ @Contract("null -> false")
+ private static boolean checkEnabled(@Nullable VirtualFile virtualFile) {
+ return virtualFile != null && virtualFile.getFileSystem() instanceof ScratchpadFileSystem;
+ }
+
+ @Override
+ public StatusBarWidget copy() {
+ return new ScratchWidget(myProject);
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ update();
+ super.fileOpened(source, file);
+ }
+
+ @Override
+ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ update();
+ super.fileClosed(source, file);
+ }
+
+ @Override
+ public void selectionChanged(@NotNull FileEditorManagerEvent event) {
+ update();
+ super.selectionChanged(event);
+ }
+
+ private static Icon getDefaultIcon(@NotNull Language language) {
+ LanguageFileType associatedLanguage = language.getAssociatedFileType();
+ return associatedLanguage != null ? associatedLanguage.getIcon() : null;
+ }
+
+ private static class MyTextPanel extends TextPanel {
+ private int myIconTextGap = 2;
+ private Icon myIcon;
+
+ @Override
+ protected void paintComponent(@NotNull final Graphics g) {
+ super.paintComponent(g);
+ if (getText() != null) {
+ Rectangle r = getBounds();
+ Insets insets = getInsets();
+ AllIcons.Ide.Statusbar_arrows.paintIcon(this, g, r.width - insets.right - AllIcons.Ide.Statusbar_arrows.getIconWidth() - 2,
+ r.height / 2 - AllIcons.Ide.Statusbar_arrows.getIconHeight() / 2);
+ if (myIcon != null) {
+ myIcon.paintIcon(this, g, insets.left - myIconTextGap - myIcon.getIconWidth(), r.height / 2 - myIcon.getIconHeight() / 2);
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ public Insets getInsets() {
+ Insets insets = super.getInsets();
+ if (myIcon != null) {
+ insets.left += myIcon.getIconWidth() + myIconTextGap * 2;
+ }
+ return insets;
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ final Dimension preferredSize = super.getPreferredSize();
+ int deltaWidth = AllIcons.Ide.Statusbar_arrows.getIconWidth() + myIconTextGap * 2;
+ if (myIcon != null) {
+ deltaWidth += myIcon.getIconWidth() + myIconTextGap * 2;
+ }
+ return new Dimension(preferredSize.width + deltaWidth, preferredSize.height);
+ }
+
+ public void setIcon(Icon icon) {
+ myIcon = icon;
+ }
+ }
+
+ private class ChangeLanguageAction extends AnAction implements DumbAware {
+ private final VirtualFile myVirtualFile;
+
+ private final Language myLanguage;
+
+ public ChangeLanguageAction(@NotNull VirtualFile virtualFile, @NotNull Language language) {
+ super(language.getDisplayName(), "", getDefaultIcon(language));
+ myVirtualFile = virtualFile;
+ myLanguage = language;
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Project project = e.getProject();
+ if (project == null) return;
+ if (myVirtualFile instanceof LightVirtualFile) {
+ ((LightVirtualFile)myVirtualFile).setLanguage(myLanguage);
+ FileContentUtil.reparseFiles(project, Collections.singletonList(myVirtualFile), false);
+ ScratchWidget.this.update();
+ }
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java
index e643b625a7b7..e2c906bbb45b 100644
--- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadFileSystem.java
@@ -20,7 +20,6 @@ import com.intellij.ide.presentation.Presentation;
import com.intellij.ide.presentation.PresentationProvider;
import com.intellij.lang.Language;
import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
@@ -29,6 +28,7 @@ import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
@@ -77,12 +77,15 @@ public class ScratchpadFileSystem extends DummyFileSystem {
@NotNull
@Override
public String extractPresentableUrl(@NotNull String path) {
- String substring = StringUtil.substringAfter(path, "/");
- return substring != null ? substring : super.extractPresentableUrl(path);
+ return calcSuffix(findFileByPath(path));
+ }
+
+ private static String calcSuffix(@Nullable VirtualFile file) {
+ return file instanceof LightVirtualFile ? ((LightVirtualFile)file).getLanguage().getDisplayName() : "Unknown language";
}
@Presentation(provider = ScratchPresentation.class)
- private static class MyLightVirtualFile extends LightVirtualFile {
+ public static class MyLightVirtualFile extends LightVirtualFile {
private final String myPrefix;
public MyLightVirtualFile(@NotNull String fileName, @NotNull Language language, @NotNull String projectPrefix) {
@@ -103,9 +106,9 @@ public class ScratchpadFileSystem extends DummyFileSystem {
}
}
- public static class ScratchPresentation extends PresentationProvider<MyLightVirtualFile> {
+ public static class ScratchPresentation extends PresentationProvider<LightVirtualFile> {
@Override
- public Icon getIcon(@NotNull MyLightVirtualFile file) {
+ public Icon getIcon(@NotNull LightVirtualFile file) {
return LayeredIcon.create(file.getFileType().getIcon(), AllIcons.Actions.New);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadIconProvider.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadIconProvider.java
new file mode 100644
index 000000000000..6771160b0551
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadIconProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.scratch;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.FileIconProvider;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.LayeredIcon;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class ScratchpadIconProvider implements FileIconProvider {
+ @Nullable
+ @Override
+ public Icon getIcon(@NotNull VirtualFile file, @Iconable.IconFlags int flags, @Nullable Project project) {
+ if (file instanceof ScratchpadFileSystem.MyLightVirtualFile) {
+ return LayeredIcon.create(file.getFileType().getIcon(), AllIcons.Actions.New);
+ }
+ return null;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java
index ed931e77f616..15d28418209d 100644
--- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchpadManagerImpl.java
@@ -18,22 +18,28 @@ package com.intellij.ide.scratch;
import com.intellij.lang.Language;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.containers.ContainerUtil;
+import com.intellij.openapi.wm.StatusBar;
+import com.intellij.openapi.wm.WindowManager;
import org.jetbrains.annotations.NotNull;
-import java.util.Map;
-
public class ScratchpadManagerImpl extends ScratchpadManager implements Disposable {
private final Project myProject;
- private final Map<String, Integer> myExtensionsCounterMap = ContainerUtil.newHashMap();
+ private Integer myIndex = 0;
private Language myLatestLanguage;
public ScratchpadManagerImpl(@NotNull Project project) {
myProject = project;
+ StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
+ if (statusBar == null) return;
+ if (statusBar.getWidget(ScratchWidget.ID) != null) return;
+ ScratchWidget widget = new ScratchWidget(myProject);
+ statusBar.addWidget(widget, "before Encoding", myProject);
+ statusBar.updateWidget(ScratchWidget.ID);
+ project.getMessageBus().connect(project).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, widget);
}
@NotNull
@@ -43,7 +49,7 @@ public class ScratchpadManagerImpl extends ScratchpadManager implements Disposab
return ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
@Override
public VirtualFile compute() {
- String name = generateFileName(language);
+ String name = generateFileName();
return ScratchpadFileSystem.getScratchFileSystem().addFile(name, language, calculatePrefix(ScratchpadManagerImpl.this.myProject));
}
});
@@ -60,14 +66,10 @@ public class ScratchpadManagerImpl extends ScratchpadManager implements Disposab
}
@NotNull
- private String generateFileName(@NotNull Language language) {
- LanguageFileType associatedFileType = language.getAssociatedFileType();
- String ext = associatedFileType != null ? associatedFileType.getDefaultExtension() : "unknown";
- Integer prev = myExtensionsCounterMap.get(ext);
- int updated = prev == null ? 1 : ++prev;
- myExtensionsCounterMap.put(ext, updated);
- String index = updated == 1 ? "" : updated + ".";
- return "scratch." + index + ext;
+ private String generateFileName() {
+ int updated = myIndex++;
+ String index = updated == 0 ? "" : "." + updated;
+ return "scratch" + index;
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java b/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java
index 83174587bf01..849b01b703b9 100644
--- a/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ide/structureView/impl/TemplateLanguageStructureViewBuilder.java
@@ -60,9 +60,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
myVirtualFile = psiElement.getContainingFile().getVirtualFile();
myProject = psiElement.getProject();
- final TemplateLanguageFileViewProvider provider = getViewProvider();
- assert provider != null;
- myTemplateDataLanguage = provider.getTemplateDataLanguage();
+ myTemplateDataLanguage = getNotNullViewProvider().getTemplateDataLanguage();
}
private void updateAfterPsiChange() {
@@ -115,6 +113,15 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
return provider instanceof TemplateLanguageFileViewProvider ? (TemplateLanguageFileViewProvider)provider : null;
}
+ @NotNull
+ private TemplateLanguageFileViewProvider getNotNullViewProvider() {
+ final FileViewProvider provider = PsiManager.getInstance(myProject).findViewProvider(myVirtualFile);
+ if (provider == null || !(provider instanceof TemplateLanguageFileViewProvider)) {
+ throw new AssertionError("Not a template view provider for " + myVirtualFile + ": " + provider);
+ }
+ return (TemplateLanguageFileViewProvider)provider;
+ }
+
private void updateBaseLanguageView() {
if (myBaseStructureViewDescriptor == null || !myProject.isOpen()) return;
final StructureViewComponent view = (StructureViewComponent)myBaseStructureViewDescriptor.structureView;
@@ -158,8 +165,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
public StructureView createStructureView(FileEditor fileEditor, @NotNull Project project) {
myFileEditor = fileEditor;
List<StructureViewComposite.StructureViewDescriptor> viewDescriptors = new ArrayList<StructureViewComposite.StructureViewDescriptor>();
- final TemplateLanguageFileViewProvider provider = getViewProvider();
- assert provider != null;
+ final TemplateLanguageFileViewProvider provider = getNotNullViewProvider();
final StructureViewComposite.StructureViewDescriptor structureViewDescriptor = createMainView(fileEditor, provider.getPsi(provider.getBaseLanguage()));
if (structureViewDescriptor != null) viewDescriptors.add(structureViewDescriptor);
diff --git a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java
index feb38bf3f25b..a8cc1658ab3f 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java
@@ -22,7 +22,6 @@ import com.intellij.navigation.NavigationItem;
import com.intellij.navigation.NavigationItemFileStatus;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
-import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.markup.EffectType;
@@ -107,7 +106,7 @@ public class NavigationItemListCellRenderer extends OpaquePanel implements ListC
final PsiElement psiElement = value instanceof PsiElement
? (PsiElement)value
: CommonDataKeys.PSI_ELEMENT.getData((DataProvider) value);
- if (psiElement != null) {
+ if (psiElement != null && psiElement.isValid()) {
final FileColorManager fileColorManager = FileColorManager.getInstance(psiElement.getProject());
final Color fileColor = fileColorManager.getRendererBackground(psiElement.getContainingFile());
if (fileColor != null) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index 3e0981185117..dcc1429c8bbd 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -25,6 +25,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.actions.CopyReferenceAction;
import com.intellij.ide.actions.GotoFileAction;
+import com.intellij.ide.actions.WindowAction;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
@@ -62,6 +63,7 @@ import com.intellij.psi.statistics.StatisticsManager;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
+import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.PopupOwner;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.ui.popup.PopupUpdateProcessor;
@@ -887,6 +889,12 @@ public abstract class ChooseByNameBase {
}
});
myTextPopup.show(layeredPane);
+ if (myTextPopup instanceof AbstractPopup) {
+ Window window = ((AbstractPopup)myTextPopup).getPopupWindow();
+ if (window instanceof JDialog) {
+ ((JDialog)window).getRootPane().putClientProperty(WindowAction.NO_WINDOW_ACTIONS, Boolean.TRUE);
+ }
+ }
}
private JLayeredPane getLayeredPane() {
@@ -1458,7 +1466,7 @@ public abstract class ChooseByNameBase {
return false;
}
- private static final String EXTRA_ELEM = "...";
+ public static final String EXTRA_ELEM = "...";
public static final String NON_PREFIX_SEPARATOR = "non-prefix matches:";
public static Component renderNonPrefixSeparatorComponent(Color backgroundColor) {
@@ -1551,13 +1559,13 @@ public abstract class ChooseByNameBase {
final String cardToShow = elements.isEmpty() ? NOT_FOUND_CARD : myScopeExpanded ? NOT_FOUND_IN_PROJECT_CARD : CHECK_BOX_CARD;
showCard(cardToShow, 0);
- final Set<Object> filtered = filter(elements);
-
+ final boolean edt = myModel instanceof EdtSortingModel;
+ final Set<Object> filtered = !edt ? filter(elements) : Collections.emptySet();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (!myCancelled.isCanceled()) {
- myCallback.consume(filtered);
+ myCallback.consume(edt ? filter(elements) : filtered);
}
}
}, myModalityState);
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
index 4f6959da84f6..cb03b68bfadb 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -41,6 +41,7 @@ import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.List;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -314,7 +315,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
}
public static ChooseByNamePopup createPopup(final Project project,
- @NotNull ChooseByNameModel model,
+ @NotNull final ChooseByNameModel model,
@NotNull ChooseByNameItemProvider provider,
@Nullable final String predefinedText,
boolean mayRequestOpenInCurrentWindow,
@@ -323,8 +324,13 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
if (oldPopup != null) {
oldPopup.close(false);
}
- ChooseByNamePopup newPopup = new ChooseByNamePopup(project, model, provider, oldPopup, predefinedText, mayRequestOpenInCurrentWindow,
- initialIndex);
+ ChooseByNamePopup newPopup = new ChooseByNamePopup(project, model, provider, oldPopup, predefinedText, mayRequestOpenInCurrentWindow, initialIndex) {
+ @NotNull
+ @Override
+ protected Set<Object> filter(@NotNull Set<Object> elements) {
+ return model instanceof EdtSortingModel ? super.filter(((EdtSortingModel)model).sort(elements)) : super.filter(elements);
+ }
+ };
if (project != null) {
project.putUserData(CHOOSE_BY_NAME_POPUP_IN_PROJECT_KEY, newPopup);
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EdtSortingModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EdtSortingModel.java
new file mode 100644
index 000000000000..a556eeda9676
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/EdtSortingModel.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util.gotoByName;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+import java.util.SortedSet;
+
+public interface EdtSortingModel {
+ @NotNull
+ SortedSet<Object> sort(@NotNull Set<Object> elements);
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
index ccd5f23a42ad..45fe6a9a074c 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,10 +23,10 @@ import com.intellij.ide.ui.search.ActionFromOptionDescriptorProvider;
import com.intellij.ide.ui.search.OptionDescription;
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl;
-import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
@@ -58,7 +58,7 @@ import java.awt.*;
import java.util.*;
import java.util.List;
-public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, Comparator<Object> {
+public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, Comparator<Object>, EdtSortingModel {
@NonNls public static final String SETTINGS_KEY = "$$$SETTINGS$$$";
@NonNls public static final String INTENTIONS_KEY = "$$$INTENTIONS_KEY$$$";
@Nullable private final Project myProject;
@@ -73,7 +73,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
protected final SearchableOptionsRegistrar myIndex;
protected final Map<AnAction, String> myActionsMap = new TreeMap<AnAction, String>(new Comparator<AnAction>() {
@Override
- public int compare(AnAction o1, AnAction o2) {
+ public int compare(@NotNull AnAction o1, @NotNull AnAction o2) {
int compare = Comparing.compare(o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText());
if (compare == 0 && !o1.equals(o2)) {
return o1.hashCode() - o2.hashCode();
@@ -124,7 +124,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
@Override
public String getCheckBoxName() {
- return IdeBundle.message("checkbox.other.included");
+ return null;
}
@Override
@@ -144,21 +144,11 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
@Override
public boolean loadInitialCheckBoxState() {
- PropertiesComponent propertiesComponent = getPropertiesStorage();
- return Boolean.TRUE.toString().equals(propertiesComponent.getValue("GoToAction.toSaveAllIncluded")) &&
- propertiesComponent.isTrueValue("GoToAction.allIncluded");
- }
-
- private PropertiesComponent getPropertiesStorage() {
- return myProject != null ? PropertiesComponent.getInstance(myProject) : PropertiesComponent.getInstance();
+ return true;
}
@Override
public void saveInitialCheckBoxState(boolean state) {
- PropertiesComponent propertiesComponent = getPropertiesStorage();
- if (Boolean.TRUE.toString().equals(propertiesComponent.getValue("GoToAction.toSaveAllIncluded"))) {
- propertiesComponent.setValue("GoToAction.allIncluded", Boolean.toString(state));
- }
}
@Override
@@ -166,7 +156,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
return new DefaultListCellRenderer() {
@Override
- public Component getListCellRendererComponent(final JList list,
+ public Component getListCellRendererComponent(@NotNull final JList list,
final Object value,
final int index, final boolean isSelected, final boolean cellHasFocus) {
final JPanel panel = new JPanel(new BorderLayout());
@@ -175,22 +165,16 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
Color bg = UIUtil.getListBackground(isSelected);
panel.setBackground(bg);
- Color groupFg = isSelected ? UIUtil.getListForeground() : UIUtil.getLabelDisabledForeground();
+ Color groupFg = isSelected ? UIUtil.getListSelectionForeground() : UIUtil.getLabelDisabledForeground();
if (value instanceof ActionWrapper) {
-
final ActionWrapper actionWithParentGroup = (ActionWrapper)value;
final AnAction anAction = actionWithParentGroup.getAction();
final Presentation templatePresentation = anAction.getTemplatePresentation();
final Icon icon = templatePresentation.getIcon();
- final DataContext dataContext = DataManager.getInstance().getDataContext(myContextComponent);
-
- final AnActionEvent event = updateActionBeforeShow(anAction, dataContext);
- final Presentation presentation = event.getPresentation();
-
- final Color fg = defaultActionForeground(isSelected, presentation);
+ final Color fg = defaultActionForeground(isSelected, actionWithParentGroup.getPresentation());
final JLabel actionLabel = createActionLabel(anAction, templatePresentation.getText(), fg, bg, icon);
panel.add(actionLabel, BorderLayout.WEST);
@@ -269,7 +253,10 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
}
@Override
- public int compare(Object o1, Object o2) {
+ public int compare(@NotNull Object o1, @NotNull Object o2) {
+ if (ChooseByNameBase.EXTRA_ELEM.equals(o1)) return 1;
+ if (ChooseByNameBase.EXTRA_ELEM.equals(o2)) return -1;
+
if (o1 instanceof OptionDescription && !(o2 instanceof OptionDescription)) {
return 1;
}
@@ -298,21 +285,15 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
}
protected static Color defaultActionForeground(boolean isSelected, Presentation presentation) {
- if (isSelected) {
- return UIUtil.getListSelectionForeground();
- }
-
- if (!presentation.isEnabled() || !presentation.isVisible()) {
- return UIUtil.getInactiveTextColor();
- }
-
+ if (isSelected) return UIUtil.getListSelectionForeground();
+ if (!presentation.isEnabled() || !presentation.isVisible()) return UIUtil.getInactiveTextColor();
return UIUtil.getListForeground();
}
@Override
@NotNull
public String[] getNames(boolean checkBoxState) {
- final ArrayList<String> result = new ArrayList<String>();
+ final LinkedHashSet<String> result = new LinkedHashSet<String>();
result.add(INTENTIONS_KEY);
for (AnAction action : myActionsMap.keySet()) {
result.add(getActionId(action));
@@ -332,12 +313,13 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
public Object[] getElementsByName(final String id, final boolean checkBoxState, final String pattern) {
List<Object> objects = new ArrayList<Object>();
final AnAction act = myActionManager.getAction(id);
+ DataContext dataContext = DataManager.getInstance().getDataContext(myContextComponent);
if (act != null) {
final HashMap<AnAction, String> map = new HashMap<AnAction, String>();
final MatchMode matchMode = actionMatches(pattern, act);
final String groupName = myActionsMap.get(act);
if (map.put(act, groupName) == null) {
- objects.add(new ActionWrapper(act, groupName, matchMode));
+ objects.add(new ActionWrapper(act, groupName, matchMode, dataContext));
}
if (checkBoxState) {
final Set<String> ids = ((ActionManagerImpl)myActionManager).getActionIds();
@@ -348,7 +330,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
final AnAction anAction = myActionManager.getAction(id);
map.put(anAction, null);
if (anAction != null) {
- objects.add(new ActionWrapper(anAction, null, MatchMode.NON_MENU));
+ objects.add(new ActionWrapper(anAction, null, MatchMode.NON_MENU, dataContext));
}
}
}
@@ -356,7 +338,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
for (String intentionText : myIntentions.keySet()) {
final ApplyIntentionAction intentionAction = myIntentions.get(intentionText);
if (actionMatches(pattern, intentionAction) != MatchMode.NONE) {
- objects.add(new ActionWrapper(intentionAction, intentionText, MatchMode.INTENTION));
+ objects.add(new ActionWrapper(intentionAction, intentionText, MatchMode.INTENTION, dataContext));
}
}
}
@@ -400,7 +382,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
AnAction action = converter.provide(description);
if (action != null) {
String title = getGroupName(description);
- objects.add(new ActionWrapper(action, title, MatchMode.NAME));
+ objects.add(new ActionWrapper(action, title, MatchMode.NAME, dataContext));
}
objects.add(description);
}
@@ -534,6 +516,14 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
return compiledPattern;
}
+ @NotNull
+ @Override
+ public SortedSet<Object> sort(@NotNull Set<Object> elements) {
+ TreeSet<Object> objects = ContainerUtil.newTreeSet(this);
+ objects.addAll(elements);
+ return objects;
+ }
+
protected enum MatchMode {
NONE, INTENTION, NAME, DESCRIPTION, GROUP, NON_MENU
}
@@ -633,7 +623,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
@Override
public boolean useMiddleMatching() {
- return false;
+ return true;
}
private final ThreadLocal<PatternMatcher> myMatcher = new ThreadLocal<PatternMatcher>() {
@@ -647,14 +637,17 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
}
public static class ActionWrapper implements Comparable<ActionWrapper>{
- private AnAction myAction;
- private MatchMode myMode;
- private String myGroupName;
+ private final AnAction myAction;
+ private final MatchMode myMode;
+ private final String myGroupName;
+ private final DataContext myDataContext;
+ private Presentation myPresentation;
- public ActionWrapper(AnAction action, String groupName, MatchMode mode) {
+ public ActionWrapper(@NotNull AnAction action, String groupName, MatchMode mode, DataContext dataContext) {
myAction = action;
myMode = mode;
myGroupName = groupName;
+ myDataContext = dataContext;
}
public AnAction getAction() {
@@ -667,18 +660,40 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
@Override
public int compareTo(@NotNull ActionWrapper o) {
- final int compared = myMode.compareTo(o.getMode());
+ if (ApplicationManager.getApplication().isDispatchThread()) {
+ boolean p1Enable = visible();
+ boolean p2enable = o.visible();
+ if (p1Enable && !p2enable) return -1;
+ if (!p1Enable && p2enable) return 1;
+ }
+
+ int compared = myMode.compareTo(o.getMode());
return compared != 0
? compared
: StringUtil.compare(myAction.getTemplatePresentation().getText(), o.getAction().getTemplatePresentation().getText(), true);
}
+ private boolean visible() {
+ return getPresentation().isEnabledAndVisible();
+ }
+
+ public Presentation getPresentation() {
+ if (myPresentation != null) return myPresentation;
+ return myPresentation = updateActionBeforeShow(myAction, myDataContext).getPresentation();
+ }
+
public String getGroupName() {
return myGroupName;
}
- public void setGroupName(String groupName) {
- myGroupName = groupName;
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ActionWrapper && compareTo((ActionWrapper)obj) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return myAction.getTemplatePresentation().getText().hashCode();
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java
index bade6b79ae23..38e157bac2a0 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/projectWizard/WebProjectTemplate.java
@@ -15,11 +15,9 @@
*/
package com.intellij.ide.util.projectWizard;
-import com.intellij.openapi.module.*;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ModifiableRootModel;
-import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.module.WebModuleBuilder;
+import com.intellij.openapi.module.WebModuleType;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.platform.ProjectTemplate;
@@ -28,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.List;
/**
* @author Dmitry Avdeev
@@ -60,8 +57,13 @@ public abstract class WebProjectTemplate<T> extends WebProjectGenerator<T> imple
return WebModuleBuilder.ICON;
}
+ public Icon getLogo() {
+ return AllIcons.Nodes.PpWebLogo;
+ }
+
@NotNull
public GeneratorPeer<T> getPeer() {
return myPeerHolder.getValue();
}
+
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
index 6f23746b534f..aef7c9a17e74 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
@@ -317,6 +317,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
if (!files.isEmpty()) {
GlobalSearchScope prev = new GlobalSearchScope(project) {
private Set<VirtualFile> myFiles = null;
+ @NotNull
@Override
public String getDisplayName() {
return IdeBundle.message("scope.files.in.previous.search.result");
@@ -371,6 +372,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
final Collection<TreeItem<Pair<AbstractUrl,String>>> rootUrls = favoritesManager.getFavoritesListRootUrls(favorite);
if (rootUrls.isEmpty()) continue; // ignore unused root
result.add(new GlobalSearchScope(project) {
+ @NotNull
@Override
public String getDisplayName() {
return "Favorite \'" + favorite + "\'";
@@ -404,6 +406,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
if (files != null) {
final List<VirtualFile> openFiles = Arrays.asList(files);
result.add(new DelegatingGlobalSearchScope(GlobalSearchScope.filesScope(project, openFiles)){
+ @NotNull
@Override
public String getDisplayName() {
return "Selected Files";
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
index d027fa6a2753..d0288d71a9a2 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
@@ -267,6 +267,16 @@ public class CaretModelWindow implements CaretModel {
}
@Override
+ public void runForEachCaret(@NotNull final CaretAction action, boolean reverseOrder) {
+ myDelegate.runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ action.perform(createInjectedCaret(caret));
+ }
+ }, reverseOrder);
+ }
+
+ @Override
public void runBatchCaretOperation(@NotNull Runnable runnable) {
myDelegate.runBatchCaretOperation(runnable);
}
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
index 0b077fa72fde..077c41e477ff 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java
@@ -580,7 +580,7 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow
if (offsetInLine > end- lineStartOffset) offsetInLine = end - lineStartOffset;
CharSequence text = myDocumentWindow.getCharsSequence();
- return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine, EditorUtil.getTabSize(myDelegate));
+ return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine);
}
private int calcOffset(int col, int lineNumber, int lineStartOffset) {
if (myDocumentWindow.getTextLength() == 0) return 0;
diff --git a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
index 5af6db07b9d7..09bca34d2a24 100644
--- a/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
+++ b/platform/lang-impl/src/com/intellij/lang/javascript/boilerplate/AbstractGithubTagDownloadedProjectGenerator.java
@@ -90,7 +90,8 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
@NotNull GithubTagInfo tag) throws GeneratorException {
File zipArchiveFile = getCacheFile(tag);
boolean brokenZip = true;
- if (zipArchiveFile.isFile()) {
+ boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
+ if (!unitTestMode && zipArchiveFile.isFile()) {
try {
ZipUtil.unzipWithProgressSynchronously(project, getTitle(), zipArchiveFile, extractToDir, true);
brokenZip = false;
@@ -111,6 +112,9 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
}
}
if (!downloaded) {
+ if (unitTestMode) {
+ throw new GeneratorException("Download " + tag.getZipballUrl() + " is skipped in unit test mode");
+ }
downloadAndUnzip(project, tag.getZipballUrl(), zipArchiveFile, extractToDir, true);
}
}
diff --git a/platform/lang-impl/src/com/intellij/mock/MockFileManager.java b/platform/lang-impl/src/com/intellij/mock/MockFileManager.java
index 2197dff2b9fa..2863363f509c 100644
--- a/platform/lang-impl/src/com/intellij/mock/MockFileManager.java
+++ b/platform/lang-impl/src/com/intellij/mock/MockFileManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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 com.intellij.psi.PsiFile;
import com.intellij.psi.SingleRootFileViewProvider;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.file.impl.FileManager;
-import com.intellij.util.containers.FactoryMap;
+import com.intellij.util.containers.WeakFactoryMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,20 +33,22 @@ import java.util.List;
*/
public class MockFileManager implements FileManager {
private final PsiManagerEx myManager;
- private final FactoryMap<VirtualFile,FileViewProvider> myViewProviders = new FactoryMap<VirtualFile, FileViewProvider>() {
+ // in mock tests it's LightVirtualFile, they're only alive when they're referenced,
+ // and there can not be several instances representing the same file
+ private final WeakFactoryMap<VirtualFile, FileViewProvider> myViewProviders = new WeakFactoryMap<VirtualFile, FileViewProvider>() {
@Override
- protected FileViewProvider create(final VirtualFile key) {
+ protected FileViewProvider create(VirtualFile key) {
return new SingleRootFileViewProvider(myManager, key);
}
};
@Override
@NotNull
- public FileViewProvider createFileViewProvider(@NotNull final VirtualFile file, final boolean eventSystemEnabled) {
+ public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, boolean eventSystemEnabled) {
return new SingleRootFileViewProvider(myManager, file, eventSystemEnabled);
}
- public MockFileManager(final PsiManagerEx manager) {
+ public MockFileManager(PsiManagerEx manager) {
myManager = manager;
}
@@ -76,7 +78,7 @@ public class MockFileManager implements FileManager {
@Override
@Nullable
public PsiFile getCachedPsiFile(@NotNull VirtualFile vFile) {
- final FileViewProvider provider = findCachedViewProvider(vFile);
+ FileViewProvider provider = findCachedViewProvider(vFile);
return provider.getPsi(provider.getBaseLanguage());
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
index 15a873180805..d135b528f5e2 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
@@ -42,10 +42,12 @@ public class SelectAllOccurrencesAction extends EditorAction {
public void doExecute(Editor editor, @Nullable Caret c, DataContext dataContext) {
Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
+ boolean wholeWordsSearch = false;
if (!caret.hasSelection()) {
TextRange wordSelectionRange = getSelectionRange(editor, caret);
if (wordSelectionRange != null) {
setSelection(editor, caret, wordSelectionRange);
+ wholeWordsSearch = true;
}
}
@@ -61,7 +63,7 @@ public class SelectAllOccurrencesAction extends EditorAction {
FindModel model = new FindModel();
model.setStringToFind(selectedText);
model.setCaseSensitive(true);
- model.setWholeWordsOnly(true);
+ model.setWholeWordsOnly(wholeWordsSearch);
int searchStartOffset = 0;
FindResult findResult = findManager.findString(editor.getDocument().getCharsSequence(), searchStartOffset, model);
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
index 7b47015394e3..54406106b976 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.DisposableIterator;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
@@ -55,6 +56,12 @@ import java.awt.*;
import java.util.*;
import java.util.List;
+/**
+ * Generates text with markup (in RTF and HTML formats) for interaction via clipboard with third-party applications.
+ *
+ * Interoperability with the following applications was tested:
+ * MS Office 2010 (Word, PowerPoint, Outlook), OpenOffice (Writer, Impress), Gmail, Mac TextEdit, Mac Mail.
+ */
public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithMarkup> {
private static final Logger LOG = Logger.getInstance("#" + TextWithMarkupProcessor.class.getName());
@@ -135,7 +142,7 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
SyntaxInfo syntaxInfo = context.finish();
logSyntaxInfo(syntaxInfo);
- createResult(syntaxInfo);
+ createResult(syntaxInfo, editor);
return ObjectUtils.notNull(myResult, Collections.<RawTextWithMarkup>emptyList());
}
catch (Exception e) {
@@ -155,9 +162,9 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
}
- void createResult(SyntaxInfo syntaxInfo) {
+ void createResult(SyntaxInfo syntaxInfo, Editor editor) {
myResult = new ArrayList<RawTextWithMarkup>(2);
- myResult.add(new HtmlTransferableData(syntaxInfo));
+ myResult.add(new HtmlTransferableData(syntaxInfo, EditorUtil.getTabSize(editor)));
myResult.add(new RtfTransferableData(syntaxInfo));
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/HtmlTransferableData.java b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/HtmlTransferableData.java
index de3d0c8311be..5a70b278b617 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/HtmlTransferableData.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/view/HtmlTransferableData.java
@@ -34,6 +34,7 @@ public class HtmlTransferableData extends AbstractSyntaxAwareReaderTransferableD
@NotNull public static final DataFlavor FLAVOR = new DataFlavor("text/html; class=java.io.Reader; charset=UTF-8", "HTML text");
+ private final int myTabSize;
private StringBuilder myResultBuffer;
private ColorRegistry myColorRegistry;
private FontNameRegistry myFontNameRegistry;
@@ -47,11 +48,13 @@ public class HtmlTransferableData extends AbstractSyntaxAwareReaderTransferableD
private int myFontFamily;
private boolean myBold;
private boolean myItalic;
+ private int myCurrentColumn;
private final TIntObjectHashMap<String> myColors = new TIntObjectHashMap<String>();
- public HtmlTransferableData(@NotNull SyntaxInfo syntaxInfo) {
+ public HtmlTransferableData(@NotNull SyntaxInfo syntaxInfo, int tabSize) {
super(syntaxInfo, FLAVOR);
+ myTabSize = tabSize;
}
@Override
@@ -61,6 +64,8 @@ public class HtmlTransferableData extends AbstractSyntaxAwareReaderTransferableD
myFontNameRegistry = mySyntaxInfo.getFontNameRegistry();
myDefaultForeground = myForeground = mySyntaxInfo.getDefaultForeground();
myDefaultBackground = myBackground = mySyntaxInfo.getDefaultBackground();
+ myBold = myItalic = false;
+ myCurrentColumn = 0;
myMaxLength = maxLength;
try {
buildColorMap();
@@ -164,8 +169,15 @@ public class HtmlTransferableData extends AbstractSyntaxAwareReaderTransferableD
case '<': myResultBuffer.append("&lt;"); break;
case '>': myResultBuffer.append("&gt;"); break;
case '&': myResultBuffer.append("&amp;"); break;
+ case ' ': myResultBuffer.append("&#32;"); break;
+ case '\n': myResultBuffer.append("<br>"); myCurrentColumn = 0; break;
+ case '\t':
+ int newColumn = (myCurrentColumn / myTabSize + 1) * myTabSize;
+ for (; myCurrentColumn < newColumn; myCurrentColumn++) myResultBuffer.append("&#32;");
+ break;
default: myResultBuffer.append(c);
}
+ myCurrentColumn++;
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
index e855b92a53e0..f451245b93d0 100644
--- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
+import com.intellij.openapi.module.impl.scopes.ModuleScopeProviderImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
import com.intellij.openapi.util.Comparing;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java
index 1b58b05357a6..100eb1bcd284 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -152,21 +153,45 @@ public class OrderEntryUtil {
rootModel.commit();
}
- public static void replaceLibrary(@NotNull ModifiableRootModel model, @NotNull Library oldLibrary, @NotNull Library newLibrary) {
- OrderEntry[] entries = model.getOrderEntries();
+ private static int findLibraryOrderEntry(@NotNull OrderEntry[] entries, @NotNull Library library) {
for (int i = 0; i < entries.length; i++) {
- OrderEntry orderEntry = entries[i];
- if (orderEntry instanceof LibraryOrderEntry && oldLibrary.equals(((LibraryOrderEntry)orderEntry).getLibrary())) {
- model.removeOrderEntry(orderEntry);
- final LibraryOrderEntry newEntry = model.addLibraryEntry(newLibrary);
- final OrderEntry[] newEntries = new OrderEntry[entries.length];
- System.arraycopy(entries, 0, newEntries, 0, i);
- newEntries[i] = newEntry;
- System.arraycopy(entries, i, newEntries, i+1, entries.length - i - 1);
- model.rearrangeOrderEntries(newEntries);
- return;
+ OrderEntry entry = entries[i];
+ if (entry instanceof LibraryOrderEntry && library.equals(((LibraryOrderEntry)entry).getLibrary())) {
+ return i;
}
}
+ return -1;
+ }
+
+ public static void replaceLibrary(@NotNull ModifiableRootModel model, @NotNull Library oldLibrary, @NotNull Library newLibrary) {
+ int i = findLibraryOrderEntry(model.getOrderEntries(), oldLibrary);
+ if (i == -1) return;
+
+ model.addLibraryEntry(newLibrary);
+ replaceLibraryByAdded(model, i);
+ }
+
+ public static void replaceLibraryEntryByAdded(@NotNull ModifiableRootModel model, @NotNull LibraryOrderEntry entry) {
+ int i = ArrayUtil.indexOf(model.getOrderEntries(), entry);
+ if (i == -1) return;
+
+ replaceLibraryByAdded(model, i);
+ }
+
+ private static void replaceLibraryByAdded(ModifiableRootModel model, int toReplace) {
+ OrderEntry[] entries = model.getOrderEntries();
+ LibraryOrderEntry newEntry = (LibraryOrderEntry)entries[entries.length - 1];
+ LibraryOrderEntry libraryEntry = (LibraryOrderEntry)entries[toReplace];
+ boolean exported = libraryEntry.isExported();
+ DependencyScope scope = libraryEntry.getScope();
+ model.removeOrderEntry(libraryEntry);
+ newEntry.setExported(exported);
+ newEntry.setScope(scope);
+ final OrderEntry[] newEntries = new OrderEntry[entries.length-1];
+ System.arraycopy(entries, 0, newEntries, 0, toReplace);
+ newEntries[toReplace] = newEntry;
+ System.arraycopy(entries, toReplace + 1, newEntries, toReplace + 1, entries.length - toReplace - 2);
+ model.rearrangeOrderEntries(newEntries);
}
public static <T extends OrderEntry> void processOrderEntries(@NotNull Module module,
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdater.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdater.java
index 4ec190127427..cb4b94016611 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdater.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdater.java
@@ -59,9 +59,10 @@ public class PushedFilePropertiesUpdater {
private final Project myProject;
private final FilePropertyPusher[] myPushers;
private final FilePropertyPusher[] myFilePushers;
- private final Queue<DumbModeTask> myTasks = new ConcurrentLinkedQueue<DumbModeTask>();
+ private final Queue<Runnable> myTasks = new ConcurrentLinkedQueue<Runnable>();
private final MessageBusConnection myConnection;
+ @NotNull
public static PushedFilePropertiesUpdater getInstance(Project project) {
return project.getComponent(PushedFilePropertiesUpdater.class);
}
@@ -84,7 +85,6 @@ public class PushedFilePropertiesUpdater {
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
@Override
public void rootsChanged(final ModuleRootEvent event) {
- pushAll(myPushers);
for (FilePropertyPusher pusher : myPushers) {
pusher.afterRootsChanged(project);
}
@@ -123,8 +123,6 @@ public class PushedFilePropertiesUpdater {
}
public void initializeProperties() {
- pushAll(myPushers);
-
for (final FilePropertyPusher pusher : myPushers) {
pusher.initExtra(myProject, myProject.getMessageBus(), new FilePropertyPusher.Engine() {
@Override
@@ -140,13 +138,18 @@ public class PushedFilePropertiesUpdater {
}
}
+ public void pushAllPropertiesNow() {
+ performPushTasks();
+ doPushAll(myPushers);
+ }
+
private void schedulePushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
if (pushers.length == 0) return;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
if (!fileIndex.isInContent(dir)) return;
- queueTask(new DumbModeTask() {
+ queueTask(new Runnable() {
@Override
- public void performInDumbMode(@NotNull final ProgressIndicator indicator) {
+ public void run() {
doPushRecursively(dir, pushers, fileIndex);
}
});
@@ -162,25 +165,32 @@ public class PushedFilePropertiesUpdater {
});
}
- private void queueTask(DumbModeTask task) {
- myTasks.offer(task);
- DumbService.getInstance(myProject).queueTask(new DumbModeTask() {
+ private void queueTask(Runnable action) {
+ myTasks.offer(action);
+ final DumbModeTask task = new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
- performPushTasks(indicator);
+ performPushTasks();
+ }
+ };
+ myProject.getMessageBus().connect(task).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+ @Override
+ public void rootsChanged(ModuleRootEvent event) {
+ DumbService.getInstance(myProject).cancelTask(task);
}
});
+ DumbService.getInstance(myProject).queueTask(task);
}
- public void performPushTasks(ProgressIndicator indicator) {
+ private void performPushTasks() {
boolean hadTasks = false;
while (true) {
- DumbModeTask task = myTasks.poll();
+ Runnable task = myTasks.poll();
if (task == null) {
break;
}
hadTasks = true;
- task.performInDumbMode(indicator);
+ task.run();
}
if (hadTasks && !myProject.isDisposed()) {
@@ -213,9 +223,9 @@ public class PushedFilePropertiesUpdater {
}
public void pushAll(final FilePropertyPusher... pushers) {
- queueTask(new DumbModeTask() {
+ queueTask(new Runnable() {
@Override
- public void performInDumbMode(@NotNull ProgressIndicator indicator) {
+ public void run() {
doPushAll(pushers);
}
});
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesCombobox.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesCombobox.java
index ab14685b0c12..5c5ea6463e2b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesCombobox.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModulesCombobox.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,77 +15,12 @@
*/
package com.intellij.openapi.roots.ui.configuration;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleType;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.ComboBox;
-import com.intellij.ui.ComboboxSpeedSearch;
-import com.intellij.ui.ListCellRendererWrapper;
-import com.intellij.ui.SortedComboBoxModel;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
+import com.intellij.application.options.ModulesComboBox;
/**
* @author nik
+ * @deprecated use {@link com.intellij.application.options.ModulesComboBox} instead
*/
-//todo[nik] use this class where possible
-public class ModulesCombobox extends ComboBox {
- private final SortedComboBoxModel<Module> myModel;
-
- public ModulesCombobox() {
- this(new SortedComboBoxModel<Module>(ModulesAlphaComparator.INSTANCE));
- }
-
- private ModulesCombobox(final SortedComboBoxModel<Module> model) {
- super(model);
- myModel = model;
- new ComboboxSpeedSearch(this){
- @Override
- protected String getElementText(Object element) {
- if (element instanceof Module) {
- return ((Module)element).getName();
- } else if (element == null) {
- return "";
- }
- return super.getElementText(element);
- }
- };
- setRenderer(new ListCellRendererWrapper<Module>() {
- @Override
- public void customize(JList list, Module value, int index, boolean selected, boolean hasFocus) {
- if (value != null) {
- setText(value.getName());
- setIcon(ModuleType.get(value).getIcon());
- }
- else {
- setText("[none]");
- }
- }
- });
- }
-
- public void fillModules(@NotNull Project project) {
- fillModules(project, null);
- }
-
- public void fillModules(@NotNull Project project, final @Nullable ModuleType moduleType) {
- myModel.clear();
- for (Module module : ModuleManager.getInstance(project).getModules()) {
- if (moduleType == null || moduleType.equals(ModuleType.get(module))) {
- myModel.add(module);
- }
- }
- }
-
- public void setSelectedModule(@Nullable Module module) {
- myModel.setSelectedItem(module);
- }
-
- @Nullable
- public Module getSelectedModule() {
- return myModel.getSelectedItem();
- }
+@Deprecated
+public class ModulesCombobox extends ModulesComboBox {
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
index f1e8b9253dc1..5937af147648 100644
--- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
+++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -101,7 +101,7 @@ public class RegistryUi implements Disposable {
myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
- public void valueChanged(ListSelectionEvent e) {
+ public void valueChanged(@NotNull ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
final int selected = myTable.getSelectedRow();
@@ -113,7 +113,7 @@ public class RegistryUi implements Disposable {
if (desc.endsWith(".")) {
desc += required;
} else {
- desc += (". " + required);
+ desc += ". " + required;
}
}
myDescriptionLabel.setText(desc);
@@ -137,7 +137,7 @@ public class RegistryUi implements Disposable {
search.setComparator(new SpeedSearchComparator(false));
myTable.addKeyListener(new KeyAdapter() {
@Override
- public void keyPressed(KeyEvent e) {
+ public void keyPressed(@NotNull KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
int row = myTable.getSelectedRow();
RegistryValue rv = myModel.getRegistryValue(row);
@@ -219,7 +219,7 @@ public class RegistryUi implements Disposable {
myAll = Registry.getAll();
Collections.sort(myAll, new Comparator<RegistryValue>() {
@Override
- public int compare(RegistryValue o1, RegistryValue o2) {
+ public int compare(@NotNull RegistryValue o1, @NotNull RegistryValue o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
@@ -308,7 +308,7 @@ public class RegistryUi implements Disposable {
super.createDefaultActions();
myCloseAction = new AbstractAction("Close") {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
processClose();
doOKAction();
}
@@ -336,7 +336,8 @@ public class RegistryUi implements Disposable {
final ApplicationInfo info = ApplicationInfo.getInstance();
final int r = Messages.showOkCancelDialog(myContent, "You need to restart " + info.getVersionName() + " for the changes to take effect", "Restart Required",
- (app.isRestartCapable() ? "Restart Now" : "Shutdown Now"), (app.isRestartCapable() ? "Restart Later": "Shutdown Later")
+ app.isRestartCapable() ? "Restart Now" : "Shutdown Now",
+ app.isRestartCapable() ? "Restart Later": "Shutdown Later"
, Messages.getQuestionIcon());
@@ -372,12 +373,15 @@ public class RegistryUi implements Disposable {
private final JLabel myLabel = new JLabel();
+ @NotNull
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ public Component getTableCellRendererComponent(@NotNull JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final RegistryValue v = ((MyTableModel)table.getModel()).getRegistryValue(row);
myLabel.setIcon(null);
myLabel.setText(null);
myLabel.setHorizontalAlignment(SwingConstants.LEFT);
+ Color fg = isSelected ? table.getSelectionForeground() : table.getForeground();
+ Color bg = isSelected ? table.getSelectionBackground() : table.getBackground();
if (v != null) {
switch (column) {
@@ -394,7 +398,7 @@ public class RegistryUi implements Disposable {
} else if (v.isBoolean()) {
final JCheckBox box = new JCheckBox();
box.setSelected(v.asBoolean());
- box.setBackground(table.getBackground());
+ box.setBackground(bg);
return box;
} else {
myLabel.setText(v.asString());
@@ -404,8 +408,8 @@ public class RegistryUi implements Disposable {
myLabel.setOpaque(true);
myLabel.setFont(myLabel.getFont().deriveFont(v.isChangedFromDefault() ? Font.BOLD : Font.PLAIN));
- myLabel.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
- myLabel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
+ myLabel.setForeground(fg);
+ myLabel.setBackground(bg);
}
return myLabel;
@@ -481,7 +485,7 @@ public class RegistryUi implements Disposable {
}
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
restoreDefaults();
}
}
diff --git a/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java b/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java
index 14c6674d8153..e4889af6a591 100644
--- a/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java
+++ b/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java
@@ -6,6 +6,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ObjectUtils;
import com.intellij.util.Producer;
import com.intellij.util.containers.Predicate;
import com.intellij.util.net.HttpConfigurable;
@@ -15,6 +16,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.net.HttpURLConnection;
+import java.net.URLConnection;
import java.util.Locale;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
@@ -171,7 +173,8 @@ public class DownloadUtil {
if (progress != null) {
progress.setText2("Downloading " + location);
}
- HttpURLConnection urlConnection = HttpConfigurable.getInstance().openHttpConnection(location);
+ URLConnection urlConnection = HttpConfigurable.getInstance().openConnection(location);
+ HttpURLConnection httpURLConnection = ObjectUtils.tryCast(urlConnection, HttpURLConnection.class);
try {
int timeout = (int) TimeUnit.MINUTES.toMillis(2);
urlConnection.setConnectTimeout(timeout);
@@ -182,19 +185,20 @@ public class DownloadUtil {
substituteContentLength(progress, originalText, contentLength);
NetUtils.copyStreamContent(progress, in, output, contentLength);
} catch (IOException e) {
- throw new IOException(
- "Can not download '" + location
- + "', response code: " + urlConnection.getResponseCode()
- + ", response message: " + urlConnection.getResponseMessage()
- + ", headers: " + urlConnection.getHeaderFields(),
- e
- );
+ String errorMessage = "Can not download '" + location + ", headers: " + urlConnection.getHeaderFields();
+ if (httpURLConnection != null) {
+ errorMessage += "', response code: " + httpURLConnection.getResponseCode()
+ + ", response message: " + httpURLConnection.getResponseMessage();
+ }
+ throw new IOException(errorMessage, e);
}
finally {
- try {
- urlConnection.disconnect();
- } catch (Exception e) {
- LOG.warn("Exception at disconnect()", e);
+ if (httpURLConnection != null) {
+ try {
+ httpURLConnection.disconnect();
+ } catch (Exception e) {
+ LOG.warn("Exception at disconnect()", e);
+ }
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooser.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooser.java
index 1137b428a42b..2229550d192f 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooser.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooser.java
@@ -97,4 +97,4 @@ public class LevelChooser extends ComboboxWithBrowseButton {
public void setLevel(HighlightDisplayLevel level) {
getComboBox().setSelectedItem(level.getSeverity());
}
-}
+} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java
new file mode 100644
index 000000000000..ec2fbce96cc5
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.profile.codeInspection.ui;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
+import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
+import com.intellij.codeInsight.daemon.impl.SeverityUtil;
+import com.intellij.codeInspection.ex.SeverityEditorDialog;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public abstract class LevelChooserAction extends ComboBoxAction {
+
+ private final SeverityRegistrar mySeverityRegistrar;
+ private HighlightSeverity myChosen = null;
+
+ public LevelChooserAction(final SeverityRegistrar severityRegistrar) {
+ mySeverityRegistrar = severityRegistrar;
+ }
+
+ @NotNull
+ @Override
+ protected DefaultActionGroup createPopupActionGroup(final JComponent button) {
+ final DefaultActionGroup group = new DefaultActionGroup();
+
+ final SortedSet<HighlightSeverity> severities = new TreeSet<HighlightSeverity>(mySeverityRegistrar);
+ for (final SeverityRegistrar.SeverityBasedTextAttributes type : SeverityUtil.getRegisteredHighlightingInfoTypes(mySeverityRegistrar)) {
+ severities.add(type.getSeverity());
+ }
+ severities.add(HighlightSeverity.ERROR);
+ severities.add(HighlightSeverity.WARNING);
+ severities.add(HighlightSeverity.WEAK_WARNING);
+ severities.add(HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING);
+ for (final HighlightSeverity severity : severities) {
+ final HighlightSeverityAction action = new HighlightSeverityAction(severity);
+ if (myChosen == null) {
+ setChosen(action.getSeverity());
+ }
+ group.add(action);
+ }
+ group.addSeparator();
+ group.add(new AnAction("Edit severities...") {
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final SeverityEditorDialog dlg = new SeverityEditorDialog(button, myChosen, mySeverityRegistrar);
+ dlg.show();
+ if (dlg.isOK()) {
+ final HighlightInfoType type = dlg.getSelectedType();
+ if (type != null) {
+ final HighlightSeverity severity = type.getSeverity(null);
+ setChosen(severity);
+ onChosen(severity);
+ }
+ }
+ }
+ });
+ return group;
+ }
+
+ protected abstract void onChosen(final HighlightSeverity severity);
+
+ public void setChosen(final HighlightSeverity severity) {
+ myChosen = severity;
+ final Presentation templatePresentation = getTemplatePresentation();
+ templatePresentation.setText(SingleInspectionProfilePanel.renderSeverity(severity));
+ templatePresentation.setIcon(HighlightDisplayLevel.find(severity).getIcon());
+ }
+
+ private class HighlightSeverityAction extends AnAction {
+ private final HighlightSeverity mySeverity;
+
+ public HighlightSeverity getSeverity() {
+ return mySeverity;
+ }
+
+ private HighlightSeverityAction(final HighlightSeverity severity) {
+ mySeverity = severity;
+ final Presentation presentation = getTemplatePresentation();
+ presentation.setText(SingleInspectionProfilePanel.renderSeverity(severity));
+ presentation.setIcon(HighlightDisplayLevel.find(severity).getIcon());
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final HighlightSeverity severity = getSeverity();
+ setChosen(severity);
+ onChosen(severity);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
index 4f4a6f021e91..62993f5cf9c8 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
@@ -24,7 +24,6 @@ import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
import com.intellij.codeInsight.daemon.impl.SeverityUtil;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.codeInspection.InspectionProfile;
-import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ModifiableModel;
import com.intellij.codeInspection.ex.*;
@@ -81,8 +80,6 @@ import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
@@ -295,7 +292,7 @@ public class SingleInspectionProfilePanel extends JPanel {
ModifiableModel profileModifiableModel = inspectionProfile.getModifiableModel();
final InspectionToolWrapper[] profileEntries = profileModifiableModel.getInspectionTools(null);
for (InspectionToolWrapper toolWrapper : profileEntries) {
- profileModifiableModel.disableTool(toolWrapper.getShortName(), (NamedScope)null, project);
+ profileModifiableModel.disableTool(toolWrapper.getShortName(), null, project);
}
profileModifiableModel.setLocal(true);
profileModifiableModel.setModified(true);
@@ -766,6 +763,9 @@ public class SingleInspectionProfilePanel extends JPanel {
//Can't be
}
}
+ catch (Throwable t) {
+ LOG.error("Failed to load description for: " + descriptor.getToolWrapper().getTool().getClass() + "; description: " + description, t);
+ }
}
else {
@@ -782,35 +782,26 @@ public class SingleInspectionProfilePanel extends JPanel {
final NamedScope scope = node.getScope(myProjectProfileManager.getProject());
if (scope != null || node.isInspectionNode()) {
final HighlightDisplayKey key = descriptor.getKey();
- final LevelChooser chooser = new LevelChooser(((SeverityProvider)mySelectedProfile.getProfileManager()).getOwnSeverityRegistrar()) {
- @Override
- public Dimension getPreferredSize() {
- Dimension preferredSize = super.getPreferredSize();
- return new Dimension(Math.min(300, preferredSize.width), preferredSize.height);
- }
-
- @Override
- public Dimension getMinimumSize() {
- return getPreferredSize();
- }
- };
- chooser.getComboBox().addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Project project = myProjectProfileManager.getProject();
- boolean toUpdate = mySelectedProfile.getErrorLevel(key, scope, project) != chooser.getLevel();
- mySelectedProfile.setErrorLevel(key, chooser.getLevel(), node.isInspectionNode() || node.isByDefault() ? -1 : node.getParent().getIndex(node),
- project);
- if (toUpdate) node.dropCache();
- }
- });
- chooser.setLevel(mySelectedProfile.getErrorLevel(key, scope, myProjectProfileManager.getProject()));
+ final LevelChooserAction chooser =
+ new LevelChooserAction(((SeverityProvider)mySelectedProfile.getProfileManager()).getOwnSeverityRegistrar()) {
+ @Override
+ protected void onChosen(final HighlightSeverity severity) {
+ final HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
+ final Project project = myProjectProfileManager.getProject();
+ final boolean toUpdate = mySelectedProfile.getErrorLevel(key, scope, project) != level;
+ mySelectedProfile.setErrorLevel(key, level,
+ node.isInspectionNode() || node.isByDefault() ? -1 : node.getParent().getIndex(node),
+ project);
+ if (toUpdate) node.dropCache();
+ }
+ };
+ chooser.setChosen(mySelectedProfile.getErrorLevel(key, scope, myProjectProfileManager.getProject()).getSeverity());
final JPanel withSeverity = new JPanel(new GridBagLayout());
withSeverity.add(new JLabel(InspectionsBundle.message("inspection.severity")),
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 0, 10, 10), 0, 0));
- withSeverity.add(chooser, new GridBagConstraints(1, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST,
+ withSeverity.add(chooser.createCustomComponent(chooser.getTemplatePresentation()), new GridBagConstraints(1, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));
final JComponent comp = descriptor.getState().getAdditionalConfigPanel();
@@ -1032,7 +1023,7 @@ public class SingleInspectionProfilePanel extends JPanel {
for (Map.Entry<Descriptor, List<Descriptor>> entry : myDescriptors.entrySet()) {
Descriptor desc = entry.getKey();
Project project = myProjectProfileManager.getProject();
- if (mySelectedProfile.isToolEnabled(desc.getKey(), (NamedScope)null, project) != desc.isEnabled()){
+ if (mySelectedProfile.isToolEnabled(desc.getKey(), null, project) != desc.isEnabled()){
return true;
}
if (mySelectedProfile.getErrorLevel(desc.getKey(), desc.getScope(), project) != desc.getLevel()) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
index 7ea34751fea2..e76aecfa1e0b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
@@ -20,6 +20,7 @@ import com.intellij.formatting.*;
import com.intellij.ide.DataManager;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
import com.intellij.lang.LanguageFormatting;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -39,10 +40,7 @@ import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiLanguageInjectionHost;
+import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
@@ -174,13 +172,16 @@ public class CodeFormatterFacade {
final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
+ final Language contextLanguage = file.getLanguage();
if (builder != null) {
if (file.getTextLength() > 0) {
LOG.assertTrue(document != null);
try {
- final PsiElement startElement = file.findElementAt(textRanges.get(0).getTextRange().getStartOffset());
- final PsiElement endElement = file.findElementAt(textRanges.get(textRanges.size() - 1).getTextRange().getEndOffset() - 1);
+ final FileViewProvider viewProvider = file.getViewProvider();
+ final PsiElement startElement = viewProvider.findElementAt(textRanges.get(0).getTextRange().getStartOffset(), contextLanguage);
+ final PsiElement endElement =
+ viewProvider.findElementAt(textRanges.get(textRanges.size() - 1).getTextRange().getEndOffset() - 1, contextLanguage);
final PsiElement commonParent = startElement != null && endElement != null ? PsiTreeUtil.findCommonParent(startElement, endElement) : null;
ASTNode node = null;
if (commonParent != null) {
@@ -258,7 +259,7 @@ public class CodeFormatterFacade {
private TextRange preprocess(@NotNull final ASTNode node, @NotNull TextRange range) {
TextRange result = range;
PsiElement psi = node.getPsi();
- if (!psi.isValid()) {
+ if (!psi.isValid()) {
return result;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
index 7c7945d653a3..85472e245b1f 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
@@ -43,7 +43,6 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -141,18 +140,9 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
if (indicator != null && indicator.isCanceled()) return false;
if (documentManager.isUncommited(hostDocument) || !hostPsiFile.isValid()) return false; // will be committed later
- Segment[] ranges = documentWindow.getHostRanges();
- Segment rangeMarker = ranges.length > 0 ? ranges[0] : null;
- PsiElement element = rangeMarker == null ? null : hostPsiFile.findElementAt(rangeMarker.getStartOffset());
- if (element == null) {
- synchronized (PsiLock.LOCK) {
- injected.remove(documentWindow);
- }
- return true;
- }
final DocumentWindow[] stillInjectedDocument = {null};
// it is here where the reparse happens and old file contents replaced
- InjectedLanguageUtil.enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(documentWindow, hostPsiFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
stillInjectedDocument[0] = (DocumentWindow)injectedPsi.getViewProvider().getDocument();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
index 1d6afc3d1fba..f2863469d614 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
@@ -92,6 +92,17 @@ public class InjectedLanguageUtil {
return ((DocumentWindowImpl)myFileViewProvider.getDocument()).getShreds();
}
+ public static void enumerate(@NotNull DocumentWindow documentWindow,
+ @NotNull PsiFile hostPsiFile,
+ @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
+ Segment[] ranges = documentWindow.getHostRanges();
+ Segment rangeMarker = ranges.length > 0 ? ranges[0] : null;
+ PsiElement element = rangeMarker == null ? null : hostPsiFile.findElementAt(rangeMarker.getStartOffset());
+ if (element != null) {
+ enumerate(element, hostPsiFile, true, visitor);
+ }
+ }
+
public static boolean enumerate(@NotNull PsiElement host, @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
PsiFile containingFile = host.getContainingFile();
return enumerate(host, containingFile, true, visitor);
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubProcessingHelper.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubProcessingHelper.java
index 2e0b5c578550..3bfa86b7ccc0 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubProcessingHelper.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubProcessingHelper.java
@@ -6,6 +6,7 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiCompiledElement;
+import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
import com.intellij.util.indexing.FileBasedIndex;
@@ -40,6 +41,7 @@ public class StubProcessingHelper extends StubProcessingHelperBase {
details += "\npsiFile" + psiFile;
details += "\npsiFile.class" + psiFile.getClass();
details += "\npsiFile.lang" + psiFile.getLanguage();
+ details += "\n" + DebugUtil.currentStackTrace();
String fileText = psiFile instanceof PsiCompiledElement ? "compiled" : psiFile.getText();
return LogMessageEx.createEvent("PSI and index do not match",
details,
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java
index 2826dfcf52d3..eefbba7e512b 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java
@@ -48,10 +48,6 @@ public class StubTreeLoaderImpl extends StubTreeLoader {
return fromIndices;
}
- if (!canHaveStub(vFile)) {
- return null;
- }
-
try {
final FileContent fc = new FileContentImpl(vFile, vFile.contentsToByteArray());
fc.putUserData(IndexingDataKeys.PROJECT, project);
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java
index 58d562543b1c..7289ed3883af 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.NotNullComputable;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
@@ -50,8 +51,6 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
public static final ID<Integer, SerializedStubTree> INDEX_ID = ID.create("Stubs");
- private static final int VERSION = 27;
-
private static final DataExternalizer<SerializedStubTree> KEY_EXTERNALIZER = new DataExternalizer<SerializedStubTree>() {
@Override
public void save(@NotNull final DataOutput out, @NotNull final SerializedStubTree v) throws IOException {
@@ -109,7 +108,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
}
@Override
- public boolean isKeyHighlySelective() {
+ public boolean keyIsUniqueForIndexedFile() {
return true;
}
@@ -199,29 +198,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
@Override
public int getVersion() {
- return getCumulativeVersion();
- }
-
- private static int getCumulativeVersion() {
- int version = VERSION;
- for (final FileType fileType : FileTypeManager.getInstance().getRegisteredFileTypes()) {
- if (fileType instanceof LanguageFileType) {
- Language l = ((LanguageFileType)fileType).getLanguage();
- ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
- if (parserDefinition != null) {
- final IFileElementType type = parserDefinition.getFileNodeType();
- if (type instanceof IStubFileElementType) {
- version += ((IStubFileElementType)type).getStubVersion();
- }
- }
- }
-
- BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
- if (builder != null) {
- version += builder.getStubVersion();
- }
- }
- return version;
+ return CumulativeStubVersion.getCumulativeVersion();
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
index 27f65c87ccc6..f83dcfe4788f 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -75,17 +75,18 @@ import java.util.*;
public abstract class BaseRefactoringProcessor implements Runnable {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.BaseRefactoringProcessor");
+ @NotNull
protected final Project myProject;
private RefactoringTransaction myTransaction;
private boolean myIsPreviewUsages;
protected Runnable myPrepareSuccessfulSwingThreadCallback = EmptyRunnable.INSTANCE;
- protected BaseRefactoringProcessor(Project project) {
+ protected BaseRefactoringProcessor(@NotNull Project project) {
this(project, null);
}
- protected BaseRefactoringProcessor(Project project, @Nullable Runnable prepareSuccessfulCallback) {
+ protected BaseRefactoringProcessor(@NotNull Project project, @Nullable Runnable prepareSuccessfulCallback) {
myProject = project;
myPrepareSuccessfulSwingThreadCallback = prepareSuccessfulCallback;
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/inline/AbstractInlineLocalDialog.java b/platform/lang-impl/src/com/intellij/refactoring/inline/AbstractInlineLocalDialog.java
new file mode 100644
index 000000000000..2bdf0256ef1a
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/refactoring/inline/AbstractInlineLocalDialog.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.inline;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class AbstractInlineLocalDialog extends InlineOptionsDialog {
+ public AbstractInlineLocalDialog(Project project, PsiElement variable, final PsiReference ref, int occurrencesCount) {
+ super(project, true, variable);
+ if (ref == null || occurrencesCount == 1) {
+ setDoNotAskOption(new DoNotAskOption() {
+ @Override
+ public boolean isToBeShown() {
+ return EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog();
+ }
+
+ @Override
+ public void setToBeShown(boolean value, int exitCode) {
+ EditorSettingsExternalizable.getInstance().setShowInlineLocalDialog(value);
+ }
+
+ @Override
+ public boolean canBeHidden() {
+ return true;
+ }
+
+ @Override
+ public boolean shouldSaveOptionsOnCancel() {
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public String getDoNotShowMessage() {
+ return CommonBundle.message("dialog.options.do.not.show");
+ }
+ });
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
index fe34cc6c6aa6..8735d9eaa769 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.meta.PsiMetaOwner;
@@ -82,7 +83,7 @@ public class PsiElementRenameHandler implements RenameHandler {
}
}
- public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, Editor editor) {
+ public static void invoke(PsiElement element, Project project, PsiElement nameSuggestionContext, @Nullable Editor editor) {
if (element != null && !canRename(project, editor, element)) {
return;
}
@@ -105,9 +106,8 @@ public class PsiElementRenameHandler implements RenameHandler {
static boolean canRename(Project project, Editor editor, PsiElement element) throws CommonRefactoringUtil.RefactoringErrorHintException {
String message = renameabilityStatus(project, element);
- if (message != null) {
- if (!message.isEmpty()) showErrorMessage(project, editor, message);
-
+ if (StringUtil.isNotEmpty(message)) {
+ showErrorMessage(project, editor, message);
return false;
}
return true;
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java
index 48460c912403..4020c8fc5cae 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -137,12 +136,12 @@ public class RenameDialog extends RefactoringDialog {
return RenamePsiElementProcessor.forElement(myPsiElement).isToSearchInComments(myPsiElement);
}
- private String getFullName() {
+ protected String getFullName() {
final String name = DescriptiveNameUtil.getDescriptiveName(myPsiElement);
return (UsageViewUtil.getType(myPsiElement) + " " + name).trim();
}
- private void createNewNameComponent() {
+ protected void createNewNameComponent() {
String[] suggestedNames = getSuggestedNames();
myOldName = suggestedNames.length > 0 ? suggestedNames[0] : null;
myNameSuggestionsField = new NameSuggestionsField(suggestedNames, myProject, FileTypes.PLAIN_TEXT, myEditor) {
@@ -341,4 +340,12 @@ public class RenameDialog extends RefactoringDialog {
final String newName = getNewName();
return RenameUtil.isValidName(myProject, myPsiElement, newName);
}
+
+ protected NameSuggestionsField getNameSuggestionsField() {
+ return myNameSuggestionsField;
+ }
+
+ public JCheckBox getCbSearchInComments() {
+ return myCbSearchInComments;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java
index 2c59c10fb486..04bfd2a4a06f 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.openapi.editor.Editor;
+import org.jetbrains.annotations.NotNull;
/**
* User: anna
@@ -29,7 +30,7 @@ import com.intellij.openapi.editor.Editor;
public class CompletionContributorForInplaceRename extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
final Editor editor = parameters.getEditor();
final TemplateState state = TemplateManagerImpl.getTemplateState(editor);
if (state != null) {
diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java b/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java
index 8f391d1947ed..48a4879a7bf4 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -99,7 +99,7 @@ public class TextOccurrencesUtil {
private static boolean processStringLiteralsContainingIdentifier(@NotNull String identifier, @NotNull SearchScope searchScope, PsiSearchHelper helper, final Processor<PsiElement> processor) {
TextOccurenceProcessor occurenceProcessor = new TextOccurenceProcessor() {
@Override
- public boolean execute(PsiElement element, int offsetInElement) {
+ public boolean execute(@NotNull PsiElement element, int offsetInElement) {
final ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage());
final ASTNode node = element.getNode();
if (definition != null && node != null && definition.getStringLiteralElements().contains(node.getElementType())) {
diff --git a/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java b/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java
index d739373b847c..b9428e00b9a0 100644
--- a/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java
+++ b/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -63,6 +63,7 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
final TestCreator creator = LanguageTestCreators.INSTANCE.forLanguage(file.getLanguage());
if (creator != null && creator.isAvailable(file.getProject(), editor, file)) {
actions.add(new AdditionalAction() {
+ @NotNull
@Override
public String getText() {
return "Create New Test...";
@@ -94,6 +95,7 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
return false;
}
+ @NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
if (TestFinderHelper.isTest(sourceElement)) {
@@ -104,6 +106,7 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
}
}
+ @NotNull
@Override
protected String getFindUsagesTitle(PsiElement sourceElement, String name, int length) {
if (TestFinderHelper.isTest(sourceElement)) {
@@ -114,8 +117,9 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
}
}
+ @NotNull
@Override
- protected String getNotFoundMessage(Project project, Editor editor, PsiFile file) {
+ protected String getNotFoundMessage(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
return CodeInsightBundle.message("goto.test.notFound");
}
diff --git a/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java b/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java
index 393c8d98a469..1d43ebb362a5 100644
--- a/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java
+++ b/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java
@@ -39,17 +39,25 @@ import javax.swing.*;
*/
public class StringComboboxEditor extends EditorComboBoxEditor {
public static final Key<JComboBox> COMBO_BOX_KEY = Key.create("COMBO_BOX_KEY");
+ public static final Key<Boolean> USE_PLAIN_PREFIX_MATCHER = Key.create("USE_PLAIN_PREFIX_MATCHER");
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.StringComboboxEditor");
private final Project myProject;
public StringComboboxEditor(final Project project, final FileType fileType, ComboBox comboBox) {
+ this(project, fileType, comboBox, false);
+ }
+
+ public StringComboboxEditor(final Project project, final FileType fileType, ComboBox comboBox, boolean usePlainMatcher) {
super(project, fileType);
myProject = project;
final PsiFile file = PsiFileFactory.getInstance(project).createFileFromText("a.dummy", StdFileTypes.PLAIN_TEXT, "", 0, true);
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
assert document != null;
document.putUserData(COMBO_BOX_KEY, comboBox);
+ if (usePlainMatcher) {
+ document.putUserData(USE_PLAIN_PREFIX_MATCHER, true);
+ }
document.putUserData(UndoConstants.DONT_RECORD_UNDO, true);
super.setItem(document);
}
diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
index 2debdbe82fe6..27ddc4e1b1b2 100644
--- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -57,7 +58,7 @@ public class TextFieldWithAutoCompletionContributor<T> extends CompletionContrib
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
final TextFieldWithAutoCompletionListProvider<T> provider = file.getUserData(KEY);
diff --git a/platform/lang-impl/src/com/intellij/ui/debugger/extensions/PlaybackDebugger.java b/platform/lang-impl/src/com/intellij/ui/debugger/extensions/PlaybackDebugger.java
index 579d7a19405a..20c2a7ae110c 100644
--- a/platform/lang-impl/src/com/intellij/ui/debugger/extensions/PlaybackDebugger.java
+++ b/platform/lang-impl/src/com/intellij/ui/debugger/extensions/PlaybackDebugger.java
@@ -406,7 +406,7 @@ public class PlaybackDebugger implements UiDebuggerExtension, PlaybackRunner.Sta
new Thread() {
@Override
public void run() {
- new WaitFor() {
+ new WaitFor(60000) {
@Override
protected boolean condition() {
return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow() instanceof IdeFrame || myRunner == null;
diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsConfigurablePanel.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsConfigurablePanel.java
index b2f41fcc7e5c..c22fe3fd056e 100644
--- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsConfigurablePanel.java
+++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsConfigurablePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -146,10 +146,10 @@ public class FileColorsConfigurablePanel extends JPanel implements Disposable {
infoPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
infoPanel.add(new JLabel("Scopes are processed from top to bottom with Local colors first.",
MessageType.INFO.getDefaultIcon(), SwingConstants.LEFT));
- final JButton editScopes = new JButton("Manage Scopes...");
+ JButton editScopes = new JButton("Manage Scopes...");
editScopes.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
EditScopesDialog.showDialog(myManager.getProject(), null, true);
}
});
diff --git a/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java b/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java
index d220e1fd7cdf..50eadaa0a2c4 100644
--- a/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java
+++ b/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java
@@ -7,6 +7,7 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPlainTextFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author sergey.evdokimov
@@ -14,7 +15,7 @@ import com.intellij.psi.PsiPlainTextFile;
public class CompletionContributorForTextField extends CompletionContributor implements DumbAware {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
if (!(file instanceof PsiPlainTextFile)) return;
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java b/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java
index 913faaeefe79..c3b3cbe580ad 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ChangeTrackingValueContainer.java
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.DataOutput;
import java.io.IOException;
-import java.util.Iterator;
import java.util.List;
/**
@@ -79,7 +78,7 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
@NotNull
@Override
- public Iterator<Value> getValueIterator() {
+ public ValueIterator<Value> getValueIterator() {
return getMergedData().getValueIterator();
}
@@ -118,6 +117,7 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
return merged;
}
+ FileId2ValueMapping<Value> fileId2ValueMapping = null;
final ValueContainer<Value> fromDisk = myInitializer.compute();
final ValueContainerImpl<Value> newMerged;
@@ -127,11 +127,17 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
newMerged = ((ChangeTrackingValueContainer<Value>)fromDisk).getMergedData().copy();
}
+ if (myAdded != null && newMerged.size() > ValueContainerImpl.NUMBER_OF_VALUES_THRESHOLD) {
+ // Calculate file ids that have Value mapped to avoid O(NumberOfValuesInMerged) during removal
+ fileId2ValueMapping = new FileId2ValueMapping<Value>(newMerged);
+ }
+ final FileId2ValueMapping<Value> finalFileId2ValueMapping = fileId2ValueMapping;
if (myInvalidated != null) {
myInvalidated.forEach(new TIntProcedure() {
@Override
public boolean execute(int inputId) {
- newMerged.removeAssociatedValue(inputId);
+ if (finalFileId2ValueMapping != null) finalFileId2ValueMapping.removeFileId(inputId);
+ else newMerged.removeAssociatedValue(inputId);
return true;
}
});
@@ -140,9 +146,13 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
if (myAdded != null) {
myAdded.forEach(new ContainerAction<Value>() {
@Override
- public boolean perform(final int id, final Value value) {
- newMerged.removeAssociatedValue(id); // enforcing "one-value-per-file for particular key" invariant
- newMerged.addValue(id, value);
+ public boolean perform(final int inputId, final Value value) {
+ // enforcing "one-value-per-file for particular key" invariant
+ if (finalFileId2ValueMapping != null) finalFileId2ValueMapping.removeFileId(inputId);
+ else newMerged.removeAssociatedValue(inputId);
+
+ newMerged.addValue(inputId, value);
+ if (finalFileId2ValueMapping != null) finalFileId2ValueMapping.associateFileIdToValue(inputId, value);
return true;
}
});
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java b/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
index 40e5d26e702e..d20d01dc4e03 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
@@ -16,6 +16,7 @@
package com.intellij.util.indexing;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.vfs.newvfs.persistent.ContentHashesUtil;
import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon;
import com.intellij.util.io.IOUtil;
@@ -44,7 +45,13 @@ class ContentHashesSupport {
FlushingDaemon.everyFiveSeconds(new Runnable() {
@Override
public void run() {
- if (ourHashesWithFileType.isDirty()) ourHashesWithFileType.force();
+ flushContentHashes();
+ }
+ });
+ ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
+ @Override
+ public void run() {
+ flushContentHashes();
}
});
ourHashesWithFileType = hashEnumerator;
@@ -55,6 +62,10 @@ class ContentHashesSupport {
}
}
+ static void flushContentHashes() {
+ if (ourHashesWithFileType.isDirty()) ourHashesWithFileType.force();
+ }
+
static int calcContentHashIdWithFileType(@NotNull byte[] bytes, @NotNull FileType fileType) throws IOException {
return enumerateHash(calcContentHashWithFileType(bytes, fileType));
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java b/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java
new file mode 100644
index 000000000000..0b7650aace4f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.indexing;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.SystemProperties;
+
+public class DebugAssertions {
+ private static final Logger LOG = Logger.getInstance(DebugAssertions.class);
+
+ public static final boolean DEBUG = SystemProperties.getBooleanProperty(
+ "intellij.idea.indices.debug",
+ ApplicationManager.getApplication().isInternal() || ApplicationManager.getApplication().isEAP()
+ );
+
+ public static final boolean EXTRA_SANITY_CHECKS = SystemProperties.getBooleanProperty(
+ "intellij.idea.indices.debug.extra.sanity",
+ DEBUG && ApplicationManager.getApplication().isInternal()
+ );
+
+ public static void assertTrue(boolean value) {
+ if (!value) {
+ LOG.assertTrue(false);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index a9856a4e8d3a..c81f7c485876 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -408,7 +408,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
extension.getKeyDescriptor(),
extension.getValueExternalizer(),
extension.getCacheSize(),
- extension.isKeyHighlySelective(),
+ extension.keyIsUniqueForIndexedFile(),
extension.traceKeyHashToVirtualFileMapping()
);
@@ -668,6 +668,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
index.dispose();
}
+ ContentHashesSupport.flushContentHashes();
myConnection.disconnect();
}
catch (Throwable e) {
@@ -701,6 +702,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
if (!HeavyProcessLatch.INSTANCE.isRunning() && modCount == myLocalModCount) { // do not interfere with 'main' jobs
mySerializationManagerEx.flushNameStorage();
}
+ ContentHashesSupport.flushContentHashes();
}
@Override
@@ -963,9 +965,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
if (restrictToFile != null) {
if (restrictToFile instanceof VirtualFileWithId) {
final int restrictedFileId = getFileId(restrictToFile);
- for (final Iterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
+ for (final ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
final V value = valueIt.next();
- if (container.getValueAssociationPredicate(value).contains(restrictedFileId)) {
+ if (valueIt.getValueAssociationPredicate().contains(restrictedFileId)) {
shouldContinue = processor.process(restrictToFile, value);
if (!shouldContinue) {
break;
@@ -978,9 +980,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
final PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
final IdFilter filter = idFilter != null ? idFilter : projectIndexableFiles(scope.getProject());
VALUES_LOOP:
- for (final Iterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
+ for (final ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
final V value = valueIt.next();
- for (final ValueContainer.IntIterator inputIdsIterator = container.getInputIdsIterator(value); inputIdsIterator.hasNext(); ) {
+ for (final ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) {
final int id = inputIdsIterator.next();
if (filter != null && !filter.containsFileId(id)) continue;
VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
@@ -1140,13 +1142,13 @@ public class FileBasedIndexImpl extends FileBasedIndex {
final TIntHashSet copy = new TIntHashSet();
final ValueContainer<V> container = index.getData(dataKey);
- for (final Iterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
+ for (final ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
final V value = valueIt.next();
if (valueChecker != null && !valueChecker.value(value)) {
continue;
}
- ValueContainer.IntIterator iterator = container.getInputIdsIterator(value);
+ ValueContainer.IntIterator iterator = valueIt.getInputIdsIterator();
if (mainIntersection == null || iterator.size() < mainIntersection.size()) {
while (iterator.hasNext()) {
@@ -1160,7 +1162,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
else {
mainIntersection.forEach(new TIntProcedure() {
- final ValueContainer.IntPredicate predicate = container.getValueAssociationPredicate(value);
+ final ValueContainer.IntPredicate predicate = valueIt.getValueAssociationPredicate();
@Override
public boolean execute(int id) {
@@ -1237,7 +1239,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
cleanupProcessedFlag();
advanceIndexVersion(indexId);
-
+
final Runnable rebuildRunnable = new Runnable() {
@Override
public void run() {
@@ -1657,20 +1659,26 @@ public class FileBasedIndexImpl extends FileBasedIndex {
final ID<?, ?> indexId = affectedIndexCandidates.get(i);
if (shouldIndexFile(file, indexId)) {
if (fc == null) {
+ if (project == null) {
+ project = ProjectUtil.guessProjectForFile(file);
+ }
+
byte[] currentBytes;
byte[] hash;
try {
currentBytes = content.getBytes();
- hash = fileType.isBinary() || !IdIndex.ourSnapshotMappingsEnabled ? null:ContentHashesSupport.calcContentHashWithFileType(currentBytes, fileType);
+ if (fileType.isBinary() || !IdIndex.ourSnapshotMappingsEnabled) {
+ hash = null;
+ } else {
+ hash = ContentHashesSupport
+ .calcContentHashWithFileType(currentBytes, SubstitutedFileType.substituteFileType(file, fileType, project));
+ }
}
catch (IOException e) {
currentBytes = ArrayUtil.EMPTY_BYTE_ARRAY;
hash = null;
}
fc = new FileContentImpl(file, currentBytes, hash);
- if (project == null) {
- project = ProjectUtil.guessProjectForFile(file);
- }
psiFile = content.getUserData(IndexingDataKeys.PSI_FILE);
initFileContent(fc, project, psiFile);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileId2ValueMapping.java b/platform/lang-impl/src/com/intellij/util/indexing/FileId2ValueMapping.java
new file mode 100644
index 000000000000..8c2b0f782e19
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileId2ValueMapping.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.indexing;
+
+import gnu.trove.TIntObjectHashMap;
+
+/**
+* Created by Maxim.Mossienko on 7/4/2014.
+*/
+class FileId2ValueMapping<Value> {
+ private TIntObjectHashMap<Value> id2ValueMap;
+ private ValueContainerImpl<Value> valueContainer;
+
+ FileId2ValueMapping(ValueContainerImpl<Value> _valueContainer) {
+ id2ValueMap = new TIntObjectHashMap<Value>();
+ valueContainer = _valueContainer;
+
+ for (final ValueContainer.ValueIterator<Value> valueIterator = _valueContainer.getValueIterator(); valueIterator.hasNext();) {
+ final Value value = valueIterator.next();
+
+ for (final ValueContainer.IntIterator intIterator = valueIterator.getInputIdsIterator(); intIterator.hasNext();) {
+ associateFileIdToValue(intIterator.next(), value);
+ }
+ }
+ }
+
+ void associateFileIdToValue(int fileId, Value value) {
+ Value previousValue = id2ValueMap.put(fileId, value);
+ if (previousValue != null) {
+ valueContainer.removeValue(fileId, previousValue);
+ }
+ }
+
+ boolean removeFileId(int inputId) {
+ Value mapped = id2ValueMap.remove(inputId);
+ if (mapped != null) {
+ valueContainer.removeValue(inputId, mapped);
+ }
+ if (DebugAssertions.EXTRA_SANITY_CHECKS) {
+ for (final ValueContainer.ValueIterator<Value> valueIterator = valueContainer.getValueIterator(); valueIterator.hasNext();) {
+ valueIterator.next();
+ DebugAssertions.assertTrue(!valueIterator.getValueAssociationPredicate().contains(inputId));
+ }
+ }
+ return mapped != null;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
index f40644600a94..7bea700016c8 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
@@ -166,7 +166,7 @@ public class IndexingStamp {
int[] outdatedIndices = null;
long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream);
long diff = dominatingIndexStamp - DataInputOutputUtil.timeBase;
- if (diff != 0 && diff < ID.MAX_NUMBER_OF_INDICES) {
+ if (diff > 0 && diff < ID.MAX_NUMBER_OF_INDICES) {
int numberOfOutdatedIndices = (int)diff;
outdatedIndices = new int[numberOfOutdatedIndices];
while(numberOfOutdatedIndices > 0) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
index c23164d4e0fb..ec7795d01585 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java
@@ -19,7 +19,6 @@ package com.intellij.util.indexing;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectAndLibrariesScope;
@@ -60,7 +59,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
private final Lock l = new ReentrantLock();
private final DataExternalizer<Value> myDataExternalizer;
- private final boolean myHighKeySelectivity;
+ private final boolean myKeyIsUniqueForIndexedFile;
public MapIndexStorage(@NotNull File storageFile,
@NotNull KeyDescriptor<Key> keyDescriptor,
@@ -74,19 +73,20 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
@NotNull KeyDescriptor<Key> keyDescriptor,
@NotNull DataExternalizer<Value> valueExternalizer,
final int cacheSize,
- boolean highKeySelectivity,
+ boolean keyIsUniqueForIndexedFile,
boolean buildKeyHashToVirtualFileMapping) throws IOException {
myStorageFile = storageFile;
myKeyDescriptor = keyDescriptor;
myCacheSize = cacheSize;
myDataExternalizer = valueExternalizer;
- myHighKeySelectivity = highKeySelectivity;
+ myKeyIsUniqueForIndexedFile = keyIsUniqueForIndexedFile;
myBuildKeyHashToVirtualFileMapping = buildKeyHashToVirtualFileMapping && FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
initMapAndCache();
}
private void initMapAndCache() throws IOException {
- final ValueContainerMap<Key, Value> map = new ValueContainerMap<Key, Value>(myStorageFile, myKeyDescriptor, myDataExternalizer);
+ final ValueContainerMap<Key, Value> map = new ValueContainerMap<Key, Value>(myStorageFile, myKeyDescriptor, myDataExternalizer,
+ myKeyIsUniqueForIndexedFile);
myCache = new SLRUCache<Key, ChangeTrackingValueContainer<Value>>(myCacheSize, (int)(Math.ceil(myCacheSize * 0.25)) /* 25% from the main cache size*/) {
@Override
@NotNull
@@ -385,7 +385,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
}
myMap.markDirty();
- if (!myHighKeySelectivity) {
+ if (!myKeyIsUniqueForIndexedFile) {
read(key).addValue(inputId, value);
return;
}
@@ -402,7 +402,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
cached.addValue(inputId, value);
return;
}
- // do not pollute the cache with highly selective data
+ // do not pollute the cache with keys unique to indexed file
ChangeTrackingValueContainer<Value> valueContainer = new ChangeTrackingValueContainer<Value>(null);
valueContainer.addValue(inputId, value);
myMap.put(key, valueContainer);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
index a79517e99f5e..3ad505baf207 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
@@ -325,6 +325,9 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
if (bytes != null) {
data = deserializeSavedPersistentData(bytes);
havePersistentData = true;
+ if (DebugAssertions.EXTRA_SANITY_CHECKS) {
+ DebugAssertions.assertTrue(myIndexer.map(content).equals(data));
+ }
}
} else {
skippedReadingPersistentDataButMayHaveIt = true;
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
index c044a8ea9a00..f500e5bc10e2 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.indexing;
+import com.intellij.ProjectTopics;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.caches.FileContent;
import com.intellij.ide.startup.impl.StartupManagerImpl;
@@ -24,8 +25,11 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.CacheUpdateRunner;
import com.intellij.openapi.project.DumbModeTask;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CollectingContentIterator;
+import com.intellij.openapi.roots.ModuleRootAdapter;
+import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,10 +52,16 @@ public class UnindexedFilesUpdater extends DumbModeTask {
public UnindexedFilesUpdater(final Project project, boolean onStartup) {
myProject = project;
myOnStartup = onStartup;
+ project.getMessageBus().connect(this).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+ @Override
+ public void rootsChanged(ModuleRootEvent event) {
+ DumbService.getInstance(project).cancelTask(UnindexedFilesUpdater.this);
+ }
+ });
}
private void updateUnindexedFiles(ProgressIndicator indicator) {
- PushedFilePropertiesUpdater.getInstance(myProject).performPushTasks(indicator);
+ PushedFilePropertiesUpdater.getInstance(myProject).pushAllPropertiesNow();
indicator.setIndeterminate(true);
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java
index 14234ad3b785..145388a3310a 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainer.java
@@ -31,12 +31,14 @@ import java.util.List;
public abstract class ValueContainer<Value> {
public interface IntIterator {
boolean hasNext();
-
+
int next();
int size();
boolean hasAscendingOrder();
+
+ IntIterator createCopyInInitialState();
}
public interface IntPredicate {
@@ -50,7 +52,17 @@ public abstract class ValueContainer<Value> {
public abstract IntPredicate getValueAssociationPredicate(Value value);
@NotNull
- public abstract Iterator<Value> getValueIterator();
+ public abstract ValueIterator<Value> getValueIterator();
+
+ public interface ValueIterator<Value> extends Iterator<Value> {
+ @NotNull
+ IntIterator getInputIdsIterator();
+
+ @NotNull
+ IntPredicate getValueAssociationPredicate();
+
+ Object getFileSetObject();
+ }
@NotNull
public abstract List<Value> toValueList();
@@ -63,9 +75,9 @@ public abstract class ValueContainer<Value> {
}
public final boolean forEach(@NotNull ContainerAction<Value> action) {
- for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
+ for (final ValueIterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
final Value value = valueIterator.next();
- for (final IntIterator intIterator = getInputIdsIterator(value); intIterator.hasNext();) {
+ for (final IntIterator intIterator = valueIterator.getInputIdsIterator(); intIterator.hasNext();) {
if (!action.perform(intIterator.next(), value)) return false;
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
index d68768f69320..3e7f3bd03739 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
@@ -16,7 +16,6 @@
package com.intellij.util.indexing;
-import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ThreadLocalCachedIntArray;
import com.intellij.util.SmartList;
@@ -28,14 +27,12 @@ import com.intellij.util.io.DataInputOutputUtil;
import gnu.trove.THashMap;
import gnu.trove.TObjectObjectProcedure;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
/**
* @author Eugene Zhuravlev
@@ -53,19 +50,19 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@Override
public void addValue(int inputId, Value value) {
- final Object input = getInput(value);
+ final Object fileSetObject = getFileSetObject(value);
- if (input == null) {
+ if (fileSetObject == null) {
attachFileSetForNewValue(value, inputId);
}
- else if (input instanceof Integer) {
+ else if (fileSetObject instanceof Integer) {
ChangeBufferingList list = new ChangeBufferingList();
- list.add(((Integer)input).intValue());
+ list.add(((Integer)fileSetObject).intValue());
list.add(inputId);
resetFileSetForValue(value, list);
}
else {
- ((ChangeBufferingList)input).add(inputId);
+ ((ChangeBufferingList)fileSetObject).add(inputId);
}
}
@@ -84,38 +81,47 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@Override
public void removeAssociatedValue(int inputId) {
if (myInputIdMapping == null) return;
- List<Value> toRemove = null;
- for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
+ List<Object> fileSetObjects = null;
+ List<Value> valueObjects = null;
+ for (final ValueIterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
final Value value = valueIterator.next();
- if (getValueAssociationPredicate(value).contains(inputId)) {
- if (toRemove == null) toRemove = new SmartList<Value>();
- else if (ApplicationInfoImpl.getShadowInstance().isEAP()) {
- LOG.error("Expected only one value per-inputId for " + ourDebugIndexInfo.get(), String.valueOf(toRemove.get(0)), String.valueOf(value));
+
+ if (valueIterator.getValueAssociationPredicate().contains(inputId)) {
+ if (fileSetObjects == null) {
+ fileSetObjects = new SmartList<Object>();
+ valueObjects = new SmartList<Value>();
+ }
+ else if (DebugAssertions.DEBUG) {
+ LOG.error("Expected only one value per-inputId for " + ourDebugIndexInfo.get(), String.valueOf(fileSetObjects.get(0)), String.valueOf(value));
}
- toRemove.add(value);
+ fileSetObjects.add(valueIterator.getFileSetObject());
+ valueObjects.add(value);
}
}
- if (toRemove != null) {
- for (Value value : toRemove) {
- removeValue(inputId, value);
+ if (fileSetObjects != null) {
+ for (int i = 0, len = valueObjects.size(); i < len; ++i) {
+ removeValue(inputId, fileSetObjects.get(i), valueObjects.get(i));
}
}
}
- private void removeValue(int inputId, Value value) {
- final Object input = getInput(value);
- if (input == null) {
+ void removeValue(int inputId, Value value) {
+ removeValue(inputId, getFileSetObject(value), value);
+ }
+
+ private void removeValue(int inputId, Object fileSet, Value value) {
+ if (fileSet == null) {
return;
}
- if (input instanceof ChangeBufferingList) {
- final ChangeBufferingList changesList = (ChangeBufferingList)input;
+ if (fileSet instanceof ChangeBufferingList) {
+ final ChangeBufferingList changesList = (ChangeBufferingList)fileSet;
changesList.remove(inputId);
if (!changesList.isEmpty()) return;
}
- else if (input instanceof Integer) {
- if (((Integer)input).intValue() != inputId) {
+ else if (fileSet instanceof Integer) {
+ if (((Integer)fileSet).intValue() != inputId) {
return;
}
}
@@ -135,11 +141,29 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@NotNull
@Override
- public Iterator<Value> getValueIterator() {
+ public ValueIterator<Value> getValueIterator() {
if (myInputIdMapping != null) {
if (!(myInputIdMapping instanceof THashMap)) {
- return new Iterator<Value>() {
+ return new ValueIterator<Value>() {
private Value value = (Value)myInputIdMapping;
+
+ @NotNull
+ @Override
+ public IntIterator getInputIdsIterator() {
+ return getIntIteratorOutOfFileSetObject(getFileSetObject());
+ }
+
+ @NotNull
+ @Override
+ public IntPredicate getValueAssociationPredicate() {
+ return getPredicateOutOfFileSetObject(getFileSetObject());
+ }
+
+ @Override
+ public Object getFileSetObject() {
+ return myInputIdMappingValue;
+ }
+
@Override
public boolean hasNext() {
return value != null;
@@ -159,8 +183,9 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
}
};
} else {
- return new Iterator<Value>() {
- final Iterator<Value> iterator = ((THashMap<Value, Object>)myInputIdMapping).keySet().iterator();
+ return new ValueIterator<Value>() {
+ private Map.Entry<Value, Object> current;
+ final Iterator<Map.Entry<Value, Object>> iterator = ((THashMap<Value, Object>)myInputIdMapping).entrySet().iterator();
@Override
public boolean hasNext() {
@@ -169,7 +194,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@Override
public Value next() {
- Value next = iterator.next();
+ Value next = (current = iterator.next()).getKey();
if (next == myNullValue) next = null;
return next;
}
@@ -178,13 +203,53 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
public void remove() {
throw new UnsupportedOperationException();
}
+
+ @NotNull
+ @Override
+ public IntIterator getInputIdsIterator() {
+ return getIntIteratorOutOfFileSetObject(getFileSetObject());
+ }
+
+ @NotNull
+ @Override
+ public IntPredicate getValueAssociationPredicate() {
+ return getPredicateOutOfFileSetObject(getFileSetObject());
+ }
+
+ @Override
+ public Object getFileSetObject() {
+ if (current == null) throw new IllegalStateException();
+ return current.getValue();
+ }
};
}
} else {
- return EmptyIterator.getInstance();
+ return emptyIterator;
}
}
+ static class EmptyValueIterator<Value> extends EmptyIterator<Value> implements ValueIterator<Value> {
+
+ @NotNull
+ @Override
+ public IntIterator getInputIdsIterator() {
+ throw new IllegalStateException();
+ }
+
+ @NotNull
+ @Override
+ public IntPredicate getValueAssociationPredicate() {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public Object getFileSetObject() {
+ throw new IllegalStateException();
+ }
+ }
+
+ private static final EmptyValueIterator emptyIterator = new EmptyValueIterator();
+
@NotNull
@Override
public List<Value> toValueList() {
@@ -200,7 +265,10 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@NotNull
@Override
public IntPredicate getValueAssociationPredicate(Value value) {
- Object input = getInput(value);
+ return getPredicateOutOfFileSetObject(getFileSetObject(value));
+ }
+
+ private static @NotNull IntPredicate getPredicateOutOfFileSetObject(@Nullable Object input) {
if (input == null) return EMPTY_PREDICATE;
if (input instanceof Integer) {
@@ -219,7 +287,10 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
@NotNull
@Override
public IntIterator getInputIdsIterator(Value value) {
- Object input = getInput(value);
+ return getIntIteratorOutOfFileSetObject(getFileSetObject(value));
+ }
+
+ private static @NotNull IntIterator getIntIteratorOutOfFileSetObject(@Nullable Object input) {
if (input == null) return EMPTY_ITERATOR;
if (input instanceof Integer){
return new SingleValueIterator(((Integer)input).intValue());
@@ -228,7 +299,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
}
}
- private Object getInput(Value value) {
+ private Object getFileSetObject(Value value) {
if (myInputIdMapping == null) return null;
value = value != null ? value:(Value)myNullValue;
@@ -279,6 +350,11 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
public boolean hasAscendingOrder() {
return true;
}
+
+ @Override
+ public IntIterator createCopyInInitialState() {
+ return this;
+ }
};
@NotNull
@@ -312,15 +388,15 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
private void ensureFileSetCapacityForValue(Value value, int count) {
if (count <= 1) return;
- Object input = getInput(value);
+ Object fileSetObject = getFileSetObject(value);
- if (input != null) {
- if (input instanceof Integer) {
+ if (fileSetObject != null) {
+ if (fileSetObject instanceof Integer) {
ChangeBufferingList list = new ChangeBufferingList(count + 1);
- list.add(((Integer)input).intValue());
+ list.add(((Integer)fileSetObject).intValue());
resetFileSetForValue(value, list);
- } else if (input instanceof ChangeBufferingList) {
- ChangeBufferingList list = (ChangeBufferingList)input;
+ } else if (fileSetObject instanceof ChangeBufferingList) {
+ ChangeBufferingList list = (ChangeBufferingList)fileSetObject;
list.ensureCapacity(count);
}
return;
@@ -372,16 +448,16 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
public void saveTo(DataOutput out, DataExternalizer<Value> externalizer) throws IOException {
DataInputOutputUtil.writeINT(out, size());
- for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
+ for (final ValueIterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
final Value value = valueIterator.next();
externalizer.save(out, value);
- Object input = getInput(value);
+ Object fileSetObject = valueIterator.getFileSetObject();
- if (input instanceof Integer) {
- DataInputOutputUtil.writeINT(out, (Integer)input); // most common 90% case during index building
+ if (fileSetObject instanceof Integer) {
+ DataInputOutputUtil.writeINT(out, (Integer)fileSetObject); // most common 90% case during index building
} else {
// serialize positive file ids with delta encoding
- ChangeBufferingList originalInput = (ChangeBufferingList)input;
+ ChangeBufferingList originalInput = (ChangeBufferingList)fileSetObject;
IntIterator intIterator = originalInput.intIterator();
DataInputOutputUtil.writeINT(out, -intIterator.size());
@@ -436,26 +512,48 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
}
}
+ static final int NUMBER_OF_VALUES_THRESHOLD = 20;
+
public void readFrom(DataInputStream stream, DataExternalizer<Value> externalizer) throws IOException {
+ FileId2ValueMapping<Value> mapping = null;
+
while (stream.available() > 0) {
final int valueCount = DataInputOutputUtil.readINT(stream);
if (valueCount < 0) {
- removeAssociatedValue(-valueCount); // ChangeTrackingValueContainer marked inputId as invalidated, see ChangeTrackingValueContainer.saveTo
- setNeedsCompacting(true);
+ // ChangeTrackingValueContainer marked inputId as invalidated, see ChangeTrackingValueContainer.saveTo
+ final int inputId = -valueCount;
+
+ if (mapping == null && size() > NUMBER_OF_VALUES_THRESHOLD) { // avoid O(NumberOfValues)
+ mapping = new FileId2ValueMapping<Value>(this);
+ }
+
+ boolean doCompact;
+ if(mapping != null) {
+ doCompact = mapping.removeFileId(inputId);
+ } else {
+ removeAssociatedValue(inputId);
+ doCompact = true;
+ }
+
+ if (doCompact) setNeedsCompacting(true);
}
else {
for (int valueIdx = 0; valueIdx < valueCount; valueIdx++) {
final Value value = externalizer.read(stream);
int idCountOrSingleValue = DataInputOutputUtil.readINT(stream);
+
if (idCountOrSingleValue > 0) {
addValue(idCountOrSingleValue, value);
+ if (mapping != null) mapping.associateFileIdToValue(idCountOrSingleValue, value);
} else {
idCountOrSingleValue = -idCountOrSingleValue;
ensureFileSetCapacityForValue(value, idCountOrSingleValue);
int prev = 0;
+
for (int i = 0; i < idCountOrSingleValue; i++) {
final int id = DataInputOutputUtil.readINT(stream);
addValue(prev + id, value);
+ if (mapping != null) mapping.associateFileIdToValue(prev + id, value);
prev += id;
}
}
@@ -493,6 +591,11 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
public boolean hasAscendingOrder() {
return true;
}
+
+ @Override
+ public IntIterator createCopyInInitialState() {
+ return new SingleValueIterator(myValue);
+ }
}
private THashMap<Value, Object> mapCopy(final THashMap<Value, Object> map) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java
index 0eb1a5410083..ac8d88da17eb 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java
@@ -30,13 +30,16 @@ import java.io.*;
*/
class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContainer<Value>> {
@NotNull private final DataExternalizer<Value> myValueExternalizer;
+ private final boolean myKeyIsUniqueForIndexedFile;
ValueContainerMap(@NotNull final File file,
@NotNull KeyDescriptor<Key> keyKeyDescriptor,
- @NotNull DataExternalizer<Value> valueExternalizer) throws IOException {
-
+ @NotNull DataExternalizer<Value> valueExternalizer,
+ boolean keyIsUniqueForIndexedFile
+ ) throws IOException {
super(file, keyKeyDescriptor, new ValueContainerExternalizer<Value>(valueExternalizer));
myValueExternalizer = valueExternalizer;
+ myKeyIsUniqueForIndexedFile = keyIsUniqueForIndexedFile;
}
@NotNull
@@ -48,7 +51,11 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
protected void doPut(Key key, ValueContainer<Value> container) throws IOException {
synchronized (myEnumerator) {
ChangeTrackingValueContainer<Value> valueContainer = (ChangeTrackingValueContainer<Value>)container;
- if (!valueContainer.needsCompacting()) {
+
+ // try to accumulate index value calculated for particular key to avoid fragmentation: usually keys are scattered across many files
+ // note that keys unique for indexed file have their value calculated at once (e.g. key is file id, index calculates something for particular
+ // file) and there is no benefit to accumulate values for particular key because only one value exists
+ if (!valueContainer.needsCompacting() && !myKeyIsUniqueForIndexedFile) {
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
//noinspection IOResourceOpenedButNotSafelyClosed
final DataOutputStream _out = new DataOutputStream(bytes);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java
index bbf2832d27a7..77c5b50581ea 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java
@@ -15,11 +15,14 @@
*/
package com.intellij.util.indexing.containers;
+import com.intellij.util.indexing.DebugAssertions;
import com.intellij.util.indexing.ValueContainer;
import gnu.trove.TIntProcedure;
import java.util.Arrays;
+import static com.intellij.util.indexing.DebugAssertions.DEBUG;
+
/**
* Class buffers changes in 2 modes:
* - Accumulating up to MAX_FILES changes appending them *sequentially* to changes array
@@ -37,8 +40,6 @@ public class ChangeBufferingList implements Cloneable {
private short removals;
private volatile RandomAccessIntContainer randomAccessContainer;
- private static final boolean DEBUG = false;
- //private static final boolean DEBUG = false;
private IdSet checkSet;
public ChangeBufferingList() { this(3); }
@@ -126,8 +127,19 @@ public class ChangeBufferingList implements Cloneable {
if (someElementsNumberEstimation < MAX_FILES) {
if (removals == 0) {
- Arrays.sort(currentChanges, 0, length);
- idSet = new SortedIdSet(currentChanges, length);
+ if (DEBUG) {
+ ValueContainer.IntIterator sorted = SortedFileIdSetIterator.getTransientIterator(new ChangesIterator(changes, length));
+ int lastIndex = 0;
+ while(sorted.hasNext()) {
+ currentChanges[lastIndex++] = sorted.next();
+ }
+
+ DebugAssertions.assertTrue(lastIndex == length);
+ idSet = new SortedIdSet(currentChanges, lastIndex);
+ } else {
+ Arrays.sort(currentChanges, 0, length);
+ idSet = new SortedIdSet(currentChanges, length);
+ }
copyChanges = false;
} else {
idSet = new SortedIdSet(Math.max(someElementsNumberEstimation, 3));
@@ -162,16 +174,12 @@ public class ChangeBufferingList implements Cloneable {
}
if (DEBUG) {
- if(checkSet.size() != idSet.size()) {
- int a = 1; assert false;
- }
+ DebugAssertions.assertTrue(checkSet.size() == idSet.size());
final RandomAccessIntContainer finalIdSet = idSet;
checkSet.forEach(new TIntProcedure() {
@Override
public boolean execute(int value) {
- if (!finalIdSet.contains(value)) {
- int a = 1; assert false;
- }
+ DebugAssertions.assertTrue(finalIdSet.contains(value));
return true;
}
});
@@ -205,15 +213,22 @@ public class ChangeBufferingList implements Cloneable {
static int calcNextArraySize(int currentSize, int wantedSize) {
return Math.min(
- Math.max(currentSize < 1024 ? currentSize << 1 : currentSize + currentSize / 5, wantedSize),
- MAX_FILES
- );
+ Math.max(currentSize < 1024 ? currentSize << 1 : currentSize + currentSize / 5, wantedSize),
+ MAX_FILES
+ );
}
public boolean isEmpty() {
if (randomAccessContainer == null) {
- if (changes == null) return true;
- if (removals == 0) return length == 0;
+ if (changes == null) {
+ if (DEBUG) DebugAssertions.assertTrue(checkSet.isEmpty());
+ return true;
+ }
+ if (removals == 0) {
+ boolean b = length == 0;
+ if (DEBUG) DebugAssertions.assertTrue(b == checkSet.isEmpty());
+ return b;
+ }
}
// todo we can calculate isEmpty in more cases (without container)
RandomAccessIntContainer intContainer = getRandomAccessContainer();
@@ -227,9 +242,7 @@ public class ChangeBufferingList implements Cloneable {
@Override
public boolean contains(int id) {
boolean answer = predicate.contains(id);
- if (answer != checkSet.contains(id)) {
- int a = 1; assert false;
- }
+ DebugAssertions.assertTrue(answer == checkSet.contains(id));
return answer;
}
};
@@ -240,30 +253,12 @@ public class ChangeBufferingList implements Cloneable {
public ValueContainer.IntIterator intIterator() {
RandomAccessIntContainer intContainer = randomAccessContainer;
if (intContainer == null && removals == 0) {
- return new ValueContainer.IntIterator() {
- int cursor;
- @Override
- public boolean hasNext() {
- return cursor < length;
- }
-
- @Override
- public int next() {
- int current = cursor;
- ++cursor;
- return changes[current];
- }
-
- @Override
- public int size() {
- return length;
- }
-
- @Override
- public boolean hasAscendingOrder() {
- return false;
- }
- };
+ ValueContainer.IntIterator iterator = new ChangesIterator(changes, length);
+ if (DEBUG) {
+ iterator = SortedFileIdSetIterator.getTransientIterator(iterator);
+ DebugAssertions.assertTrue(iterator.size() == length);
+ }
+ return iterator;
}
return getRandomAccessContainer().intIterator();
}
@@ -271,4 +266,42 @@ public class ChangeBufferingList implements Cloneable {
public IdSet getCheckSet() {
return checkSet;
}
+
+ private static class ChangesIterator implements ValueContainer.IntIterator {
+ private int cursor;
+ private final int length;
+ private final int[] changes;
+
+ ChangesIterator(int[] _changes, int _length) {
+ changes = _changes;
+ length = _length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return cursor < length;
+ }
+
+ @Override
+ public int next() {
+ int current = cursor;
+ ++cursor;
+ return changes[current];
+ }
+
+ @Override
+ public int size() {
+ return length;
+ }
+
+ @Override
+ public boolean hasAscendingOrder() {
+ return false;
+ }
+
+ @Override
+ public ValueContainer.IntIterator createCopyInInitialState() {
+ return new ChangesIterator(changes, length);
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/IdBitSet.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/IdBitSet.java
index be70286ecdd8..357c919f7162 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/containers/IdBitSet.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/IdBitSet.java
@@ -220,5 +220,10 @@ class IdBitSet implements Cloneable, RandomAccessIntContainer {
public boolean hasAscendingOrder() {
return true;
}
+
+ @Override
+ public ValueContainer.IntIterator createCopyInInitialState() {
+ return new Iterator();
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/IdSet.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/IdSet.java
index f09dea88c747..aec57a934ad1 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/containers/IdSet.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/IdSet.java
@@ -79,5 +79,10 @@ public class IdSet extends TIntHashSet implements RandomAccessIntContainer {
public boolean hasAscendingOrder() {
return false;
}
+
+ @Override
+ public ValueContainer.IntIterator createCopyInInitialState() {
+ return new IntSetIterator();
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedFileIdSetIterator.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedFileIdSetIterator.java
new file mode 100644
index 000000000000..3482d94ba88f
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedFileIdSetIterator.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.indexing.containers;
+
+import com.intellij.openapi.util.ThreadLocalCachedIntArray;
+import com.intellij.util.indexing.ValueContainer;
+
+/**
+* Created by Maxim.Mossienko on 6/12/2014.
+*/
+public class SortedFileIdSetIterator implements ValueContainer.IntIterator {
+ private final int[] myBits;
+ private final int myBitsLength;
+ private final int myOffset;
+ private int myPosition;
+ private final int mySize;
+
+ private SortedFileIdSetIterator(int[] bits, int bitsLength, int offset, int size) {
+ myBits = bits;
+ myBitsLength = bitsLength;
+ myOffset = offset;
+ myPosition = nextSetBit(0, myBits, myBitsLength);
+ mySize = size;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return myPosition != -1;
+ }
+
+ @Override
+ public int next() {
+ int next = myPosition + myOffset;
+ myPosition = nextSetBit(myPosition + 1, myBits, myBitsLength);
+ return next;
+ }
+
+ @Override
+ public int size() {
+ return mySize;
+ }
+
+ @Override
+ public boolean hasAscendingOrder() {
+ return true;
+ }
+
+ @Override
+ public ValueContainer.IntIterator createCopyInInitialState() {
+ return new SortedFileIdSetIterator(myBits, myBitsLength, myOffset, mySize);
+ }
+
+ public static ValueContainer.IntIterator getTransientIterator(ValueContainer.IntIterator intIterator) {
+ final ValueContainer.IntIterator intIteratorConed = intIterator.createCopyInInitialState();
+ int max = 0, min = Integer.MAX_VALUE;
+
+ while(intIterator.hasNext()) {
+ int nextInt = intIterator.next();
+ max = Math.max(max, nextInt);
+ min = Math.min(min, nextInt);
+ }
+
+ assert min > 0;
+
+ final int offset = (min >> INT_BITS_SHIFT) << INT_BITS_SHIFT;
+ final int bitsLength = ((max - offset) >> INT_BITS_SHIFT) + 1;
+ final int[] bits = ourSpareBuffer.getBuffer(bitsLength);
+ for(int i = 0; i < bitsLength; ++i) bits[i] = 0;
+
+ intIterator = intIteratorConed;
+ int size = 0;
+ while(intIterator.hasNext()) {
+ final int id = intIterator.next() - offset;
+ bits[id >> INT_BITS_SHIFT] |= (1 << (id));
+ ++size;
+ }
+
+ return new SortedFileIdSetIterator(bits, bitsLength, offset, size);
+ }
+
+ private static final ThreadLocalCachedIntArray ourSpareBuffer = new ThreadLocalCachedIntArray();
+
+ private static final int INT_BITS_SHIFT = 5;
+ private static int nextSetBit(int bitIndex, int[] bits, int bitsLength) {
+ int wordIndex = bitIndex >> INT_BITS_SHIFT;
+ if (wordIndex >= bitsLength) {
+ return -1;
+ }
+
+ int word = bits[wordIndex] & (-1 << bitIndex);
+
+ while (true) {
+ if (word != 0) {
+ return (wordIndex << INT_BITS_SHIFT) + Long.numberOfTrailingZeros(word);
+ }
+ if (++wordIndex == bitsLength) {
+ return -1;
+ }
+ word = bits[wordIndex];
+ }
+ }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedIdSet.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedIdSet.java
index 5405bbc2cf98..3e77e25aad7b 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedIdSet.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/SortedIdSet.java
@@ -132,6 +132,11 @@ public class SortedIdSet implements Cloneable, RandomAccessIntContainer {
public boolean hasAscendingOrder() {
return true;
}
+
+ @Override
+ public ValueContainer.IntIterator createCopyInInitialState() {
+ return new Iterator();
+ }
}
private static int binarySearch(int[] set, int off, int length, int key) {
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atNextLine-after.java b/platform/lang-impl/testData/editor/indentingBackspace/atNextLine-after.java
new file mode 100644
index 000000000000..7180cd368c25
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atNextLine-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atNextLine.java b/platform/lang-impl/testData/editor/indentingBackspace/atNextLine.java
new file mode 100644
index 000000000000..a41b2a20a0b2
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atNextLine.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atSameLine-after.java b/platform/lang-impl/testData/editor/indentingBackspace/atSameLine-after.java
new file mode 100644
index 000000000000..d91f66f3c590
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atSameLine-after.java
@@ -0,0 +1,4 @@
+class Foo {
+ <caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atSameLine.java b/platform/lang-impl/testData/editor/indentingBackspace/atSameLine.java
new file mode 100644
index 000000000000..ff85b46aa743
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atSameLine.java
@@ -0,0 +1,4 @@
+class Foo {
+ <caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition-after.java b/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition-after.java
new file mode 100644
index 000000000000..f0c299c64593
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition-after.java
@@ -0,0 +1,3 @@
+class Foo {<caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition.java b/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition.java
new file mode 100644
index 000000000000..d91f66f3c590
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/atTargetPosition.java
@@ -0,0 +1,4 @@
+class Foo {
+ <caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition-after.java b/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition-after.java
new file mode 100644
index 000000000000..f0c299c64593
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition-after.java
@@ -0,0 +1,3 @@
+class Foo {<caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition.java b/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition.java
new file mode 100644
index 000000000000..089b14cff9e4
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/beforeTargetPosition.java
@@ -0,0 +1,4 @@
+class Foo {
+ <caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1-after.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1-after.java
new file mode 100644
index 000000000000..7180cd368c25
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1.java
new file mode 100644
index 000000000000..14a7793e9c98
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText1.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret> int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2-after.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2-after.java
new file mode 100644
index 000000000000..7180cd368c25
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2.java
new file mode 100644
index 000000000000..35f82262dddd
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText2.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret> int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3-after.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3-after.java
new file mode 100644
index 000000000000..7180cd368c25
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3.java
new file mode 100644
index 000000000000..411d17ea2ad7
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText3.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ <caret> int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4-after.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4-after.java
new file mode 100644
index 000000000000..7180cd368c25
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4.java b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4.java
new file mode 100644
index 000000000000..64073eaac6d8
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/caretAheadOfText4.java
@@ -0,0 +1,4 @@
+class Foo {
+
+<caret> int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/emptyLines-after.java b/platform/lang-impl/testData/editor/indentingBackspace/emptyLines-after.java
new file mode 100644
index 000000000000..ba5cbf5dcd98
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/emptyLines-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ <caret>
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/emptyLines.java b/platform/lang-impl/testData/editor/indentingBackspace/emptyLines.java
new file mode 100644
index 000000000000..04ecf9dceadb
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/emptyLines.java
@@ -0,0 +1,4 @@
+class Foo {
+
+<caret>
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/inText-after.java b/platform/lang-impl/testData/editor/indentingBackspace/inText-after.java
new file mode 100644
index 000000000000..296c5767689b
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/inText-after.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ int fi<caret>ld;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/inText.java b/platform/lang-impl/testData/editor/indentingBackspace/inText.java
new file mode 100644
index 000000000000..c02be8a42be4
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/inText.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ int fie<caret>ld;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle-after.java b/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle-after.java
new file mode 100644
index 000000000000..b66d09789cae
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle-after.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ int <caret>field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle.java b/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle.java
new file mode 100644
index 000000000000..44b977275c46
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/inTheMiddle.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ int <caret>field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/lastLine-after.java b/platform/lang-impl/testData/editor/indentingBackspace/lastLine-after.java
new file mode 100644
index 000000000000..434592750ec7
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/lastLine-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ int field;
+} <caret> \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/lastLine.java b/platform/lang-impl/testData/editor/indentingBackspace/lastLine.java
new file mode 100644
index 000000000000..688f58dd8c44
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/lastLine.java
@@ -0,0 +1,3 @@
+class Foo {
+ int field;
+} <caret> \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace-after.java b/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace-after.java
new file mode 100644
index 000000000000..cd1c1ebec7a4
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace-after.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace.java b/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace.java
new file mode 100644
index 000000000000..221e14bc68a4
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/multilineSpace.java
@@ -0,0 +1,5 @@
+class Foo {
+
+
+ <caret>int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/plainText-after.txt b/platform/lang-impl/testData/editor/indentingBackspace/plainText-after.txt
new file mode 100644
index 000000000000..484f3cd0c17e
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/plainText-after.txt
@@ -0,0 +1,2 @@
+line1
+<caret>line2 \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/plainText.txt b/platform/lang-impl/testData/editor/indentingBackspace/plainText.txt
new file mode 100644
index 000000000000..7cc28e1f8631
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/plainText.txt
@@ -0,0 +1,2 @@
+line1
+ <caret>line2 \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/selection-after.java b/platform/lang-impl/testData/editor/indentingBackspace/selection-after.java
new file mode 100644
index 000000000000..c82144a072cf
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/selection-after.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ <caret>
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/selection.java b/platform/lang-impl/testData/editor/indentingBackspace/selection.java
new file mode 100644
index 000000000000..15e6cb90ea77
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/selection.java
@@ -0,0 +1,4 @@
+class Foo {
+
+ <selection>int field;<caret></selection>
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart-after.java b/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart-after.java
new file mode 100644
index 000000000000..f0c299c64593
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart-after.java
@@ -0,0 +1,3 @@
+class Foo {<caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart.java b/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart.java
new file mode 100644
index 000000000000..7fab47e1fe41
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/targetLineStart.java
@@ -0,0 +1,4 @@
+class Foo {
+<caret>
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/textStart-after.java b/platform/lang-impl/testData/editor/indentingBackspace/textStart-after.java
new file mode 100644
index 000000000000..a02efb5a31f5
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/textStart-after.java
@@ -0,0 +1,4 @@
+<caret>class Foo {
+
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/textStart.java b/platform/lang-impl/testData/editor/indentingBackspace/textStart.java
new file mode 100644
index 000000000000..a02efb5a31f5
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/textStart.java
@@ -0,0 +1,4 @@
+<caret>class Foo {
+
+ int field;
+} \ No newline at end of file
diff --git a/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerTest.java b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerTest.java
new file mode 100644
index 000000000000..009338fa8f7d
--- /dev/null
+++ b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.editorActions;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.testFramework.FileBasedTestCaseHelper;
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SuppressWarnings("JUnit4AnnotatedMethodInJUnit3TestCase")
+@RunWith(com.intellij.testFramework.Parameterized.class)
+@TestDataPath("/testData/../../../platform/lang-impl/testData/editor/indentingBackspace/")
+public class IndentingBackspaceHandlerTest extends LightPlatformCodeInsightTestCase implements FileBasedTestCaseHelper {
+ @Test
+ public void testAction() {
+ new WriteCommandAction<Void>(null) {
+ @Override
+ protected void run(@NotNull Result<Void> result) throws Throwable {
+ configureByFile(myFileSuffix);
+ backspace();
+ checkResultByFile(myFileSuffix.replace(".", "-after."));
+ }
+ }.execute();
+ }
+
+ @Nullable
+ @Override
+ public String getFileSuffix(String fileName) {
+ return fileName.contains("-after.") ? null : fileName;
+ }
+} \ No newline at end of file
diff --git a/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerVirtualSpaceTest.java b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerVirtualSpaceTest.java
new file mode 100644
index 000000000000..78cf05abe4cb
--- /dev/null
+++ b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerVirtualSpaceTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.editorActions;
+
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+
+import java.io.IOException;
+
+public class IndentingBackspaceHandlerVirtualSpaceTest extends LightPlatformCodeInsightTestCase {
+ public void testAfterLargeIndent() throws IOException {
+ doTest("class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 10),
+ "class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4));
+ }
+
+ public void testAfterProperIndent() throws IOException {
+ doTest("class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 10),
+ "class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4));
+ }
+
+ public void testAfterSmallIndent() throws IOException {
+ doTest("class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 10),
+ "class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4));
+ }
+
+ public void testAfterEmptyIndent() throws IOException {
+ doTest("class Foo {\n" +
+ "\n" +
+ "}",
+ new LogicalPosition(1, 10),
+ "class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4));
+ }
+
+ public void testAtIndent() throws IOException {
+ doTest("class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4),
+ "class Foo {\n" +
+ "}",
+ new LogicalPosition(0, 11));
+ }
+
+ public void testAtIndentOnEmptyLine() throws IOException {
+ doTest("class Foo {\n" +
+ "\n" +
+ "}",
+ new LogicalPosition(1, 4),
+ "class Foo {\n" +
+ "}",
+ new LogicalPosition(0, 11));
+ }
+
+ public void testBeforeIndent() throws IOException {
+ doTest("class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 3),
+ "class Foo {\n" +
+ "}",
+ new LogicalPosition(0, 11));
+ }
+
+ public void testDeleteLine() throws IOException {
+ doTest("class Foo {\n" +
+ "\n" +
+ "\n" +
+ "}",
+ new LogicalPosition(2, 0),
+ "class Foo {\n" +
+ " \n" +
+ "}",
+ new LogicalPosition(1, 4));
+ }
+
+ private void doTest(String textBefore, LogicalPosition caretBefore, String textAfter, LogicalPosition caretAfter) throws IOException {
+ configureFromFileText(getTestName(false) + ".java", textBefore);
+ myEditor.getSettings().setVirtualSpace(true);
+ myEditor.getCaretModel().moveToLogicalPosition(caretBefore);
+ backspace();
+ checkResultByText(textAfter);
+ assertEquals(caretAfter, myEditor.getCaretModel().getLogicalPosition());
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/NodeRenderer.java b/platform/platform-api/src/com/intellij/ide/util/treeView/NodeRenderer.java
index a07370e1238a..6183fae779e5 100644
--- a/platform/platform-api/src/com/intellij/ide/util/treeView/NodeRenderer.java
+++ b/platform/platform-api/src/com/intellij/ide/util/treeView/NodeRenderer.java
@@ -59,6 +59,11 @@ public class NodeRenderer extends ColoredTreeCellRenderer {
String text = tree.convertValueToText(value.toString(), selected, expanded, leaf, row, hasFocus);
SimpleTextAttributes simpleTextAttributes = getSimpleTextAttributes(node, presentation.getForcedTextForeground() != null ? presentation.getForcedTextForeground() : color);
append(text, simpleTextAttributes);
+ String location = presentation.getLocationString();
+ if (!StringUtil.isEmpty(location)) {
+ SimpleTextAttributes attributes = SimpleTextAttributes.merge(simpleTextAttributes, SimpleTextAttributes.GRAY_ATTRIBUTES);
+ append(presentation.getLocationPrefix() + location + presentation.getLocationSuffix(), attributes, false);
+ }
}
else {
boolean first = true;
@@ -82,11 +87,10 @@ public class NodeRenderer extends ColoredTreeCellRenderer {
boolean isMain = simpleTextAttributes != SimpleTextAttributes.GRAYED_ATTRIBUTES;
append(each.getText(), simpleTextAttributes, isMain);
}
- }
-
- final String location = presentation.getLocationString();
- if (!StringUtil.isEmpty(location)) {
- append(presentation.getLocationPrefix() + location + presentation.getLocationSuffix(), SimpleTextAttributes.GRAY_ATTRIBUTES, false);
+ String location = presentation.getLocationString();
+ if (!StringUtil.isEmpty(location)) {
+ append(presentation.getLocationPrefix() + location + presentation.getLocationSuffix(), SimpleTextAttributes.GRAY_ATTRIBUTES, false);
+ }
}
setToolTipText(presentation.getTooltip());
@@ -119,7 +123,7 @@ public class NodeRenderer extends ColoredTreeCellRenderer {
return addColorToSimpleTextAttributes(simpleTextAttributes, color);
}
- private SimpleTextAttributes addColorToSimpleTextAttributes(SimpleTextAttributes simpleTextAttributes, Color color) {
+ private static SimpleTextAttributes addColorToSimpleTextAttributes(SimpleTextAttributes simpleTextAttributes, Color color) {
if (color != null) {
final TextAttributes textAttributes = simpleTextAttributes.toTextAttributes();
textAttributes.setForegroundColor(color);
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
index 30c1aa2b7859..cfc5270ba4c0 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
@@ -76,6 +76,15 @@ public class DefaultActionGroup extends ActionGroup {
*/
public DefaultActionGroup(@NotNull List<? extends AnAction> actions) {
this(null, false);
+ addActions(actions);
+ }
+
+ public DefaultActionGroup(@NotNull String name, @NotNull List<? extends AnAction> actions) {
+ this(name, false);
+ addActions(actions);
+ }
+
+ private void addActions(@NotNull List<? extends AnAction> actions) {
for (AnAction action : actions) {
add(action);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java
index ab2612311fee..60375d05ce0f 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionManagerEx.java
@@ -16,15 +16,15 @@
package com.intellij.openapi.actionSystem.ex;
+import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.extensions.PluginId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.Collections;
+import java.awt.event.InputEvent;
import java.util.Comparator;
-import java.util.List;
public abstract class ActionManagerEx extends ActionManager {
@@ -98,14 +98,13 @@ public abstract class ActionManagerEx extends ActionManager {
public abstract boolean isTransparentOnlyActionsUpdateNow();
- @NotNull
- public List<String> getAbbreviations() {
- return Collections.emptyList();
- }
-
- @NotNull
- public List<String> findActionIdsByAbbreviation(String abbreviation) {
- return Collections.emptyList();
+ public void fireBeforeActionPerformed(String actionId, InputEvent event) {
+ final AnAction action = getAction(actionId);
+ if (action != null) {
+ final DataContext context = DataManager.getInstance().getDataContext();
+ final AnActionEvent e = new AnActionEvent(event, context, ActionPlaces.UNKNOWN, action.getTemplatePresentation(), this, 0);
+ fireBeforeActionPerformed(action, context, e);
+ }
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
index d93bc12cac3f..e72428804ee4 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -105,6 +105,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private boolean myMouseInside = false;
private JBPopup myPopup;
private boolean myForceTransparent = false;
+ private Boolean myForceEnabled = null;
public ComboBoxButton(Presentation presentation) {
myPresentation = presentation;
@@ -201,6 +202,12 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
}
+ @Override
+ public void setEnabled(final boolean enabled) {
+ super.setEnabled(enabled);
+ myForceEnabled = enabled;
+ }
+
public void setForceTransparent(boolean transparent) {
myForceTransparent = transparent;
}
@@ -284,9 +291,10 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
@Override
public void updateUI() {
super.updateUI();
- if (!UIUtil.isUnderGTKLookAndFeel()) {
- setBorder(UIUtil.getButtonBorder());
- }
+ //if (!UIUtil.isUnderGTKLookAndFeel()) {
+ // setBorder(UIUtil.getButtonBorder());
+ //}
+ //((JComponent)getParent().getParent()).revalidate();
}
protected class MyButtonModel extends DefaultButtonModel {
@@ -359,12 +367,20 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
@Override
+ public Font getFont() {
+ return SystemInfo.isMac ? UIUtil.getLabelFont(UIUtil.FontSize.SMALL) : UIUtil.getLabelFont();
+ }
+
+ @Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
GraphicsUtil.setupAAPainting(g);
final Dimension size = getSize();
final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText());
+ final Color textColor = (myForceEnabled == null ? myPresentation.isEnabled() : myForceEnabled)
+ ? UIManager.getColor("Panel.foreground")
+ : UIUtil.getInactiveTextColor();
if (myForceTransparent) {
final Icon icon = getIcon();
int x = 7;
@@ -375,7 +391,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
if (!StringUtil.isEmpty(getText())) {
final Font font = getFont();
g.setFont(font);
- g.setColor(UIManager.getColor("Panel.foreground"));
+ g.setColor(textColor);
g.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1);
}
} else {
@@ -410,7 +426,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
if (!StringUtil.isEmpty(getText())) {
final Font font = getFont();
g2.setFont(font);
- g2.setColor(UIManager.getColor("Panel.foreground"));
+ g2.setColor(textColor);
g2.drawString(getText(), x, (size.height + font.getSize()) / 2 - 1);
}
}
@@ -440,6 +456,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
protected void updateButtonSize() {
invalidate();
repaint();
+ setSize(getPreferredSize());
}
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
index 9a176e37aaf4..26537316b4e9 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
@@ -48,6 +48,8 @@ public class FragmentContent extends DiffContent {
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
+ rangeMarker.setGreedyToLeft(true);
+ rangeMarker.setGreedyToRight(true);
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
myOriginal = original;
myType = fileType;
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
index d67466ec7916..3fddbc344585 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
@@ -40,7 +40,9 @@ public class EditorModificationUtil {
public static void deleteSelectedText(Editor editor) {
deleteSelectedTextNoScrolling(editor);
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ if (editor.getCaretModel().getCurrentCaret() == editor.getCaretModel().getPrimaryCaret()) {
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
}
private static void deleteSelectedTextNoScrolling(Editor editor) {
@@ -106,13 +108,21 @@ public class EditorModificationUtil {
insertStringAtCaret(editor, s, false, true);
}
+ public static int insertStringAtCaret(Editor editor, @NotNull String s, boolean toProcessOverwriteMode) {
+ return insertStringAtCaret(editor, s, toProcessOverwriteMode, s.length());
+ }
+
public static int insertStringAtCaret(Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret) {
return insertStringAtCaret(editor, s, toProcessOverwriteMode, toMoveCaret, s.length());
}
+ public static int insertStringAtCaret(Editor editor, @NotNull String s, boolean toProcessOverwriteMode, int caretShift) {
+ return insertStringAtCaret(editor, s, toProcessOverwriteMode, true, caretShift);
+ }
+
public static int insertStringAtCaret(Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift) {
int result = insertStringAtCaretNoScrolling(editor, s, toProcessOverwriteMode, toMoveCaret, caretShift);
- if (toMoveCaret) {
+ if (toMoveCaret && editor.getCaretModel().getCurrentCaret() == editor.getCaretModel().getPrimaryCaret()) {
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
return result;
@@ -480,6 +490,11 @@ public class EditorModificationUtil {
});
}
+ public static void moveCaretRelatively(@NotNull Editor editor, final int caretShift) {
+ CaretModel caretModel = editor.getCaretModel();
+ caretModel.moveToOffset(caretModel.getOffset() + caretShift);
+ }
+
/** @deprecated use {@link #pasteTransferable(Editor, Producer)} (to remove in IDEA 14) */
@SuppressWarnings("UnusedDeclaration")
public static TextRange pasteFromClipboard(Editor editor) {
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
index 2dca4e6c88a8..3780e3a79e0c 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,21 +23,23 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.SmartList;
-import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
-import java.util.concurrent.ConcurrentMap;
public class LazyRangeMarkerFactory {
private final Project myProject;
- private final ConcurrentMap<VirtualFile,WeakList<LazyMarker>> myMarkers = new ConcurrentWeakHashMap<VirtualFile, WeakList<LazyMarker>>();
+ private static final Key<WeakList<LazyMarker>> LAZY_MARKERS_KEY = Key.create("LAZY_MARKERS_KEY");
+
+ public static LazyRangeMarkerFactory getInstance(Project project) {
+ return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
+ }
public LazyRangeMarkerFactory(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
myProject = project;
@@ -53,13 +55,14 @@ public class LazyRangeMarkerFactory {
transformRangeMarkers(e);
}
- private void transformRangeMarkers(DocumentEvent e) {
- VirtualFile file = fileDocumentManager.getFile(e.getDocument());
+ private void transformRangeMarkers(@NotNull DocumentEvent e) {
+ Document document = e.getDocument();
+ VirtualFile file = fileDocumentManager.getFile(document);
if (file == null) {
return;
}
- WeakList<LazyMarker> lazyMarkers = myMarkers.get(file);
+ WeakList<LazyMarker> lazyMarkers = file.getUserData(LAZY_MARKERS_KEY);
if (lazyMarkers == null) {
return;
}
@@ -67,7 +70,7 @@ public class LazyRangeMarkerFactory {
List<LazyMarker> markers = lazyMarkers.toStrongList();
List<LazyMarker> markersToRemove = null;
for (LazyMarker marker : markers) {
- if (file.equals(marker.getFile()) && marker.documentChanged(e.getDocument()) != null) {
+ if (file.equals(marker.getFile()) && marker.documentChanged(document) != null) {
if (markersToRemove == null) {
markersToRemove = new SmartList<LazyMarker>();
}
@@ -81,18 +84,15 @@ public class LazyRangeMarkerFactory {
}, project);
}
- private void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
- List<LazyMarker> markers = myMarkers.get(file);
+ private static void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
+ WeakList<LazyMarker> markers = file.getUserData(LAZY_MARKERS_KEY);
+
if (markers == null) {
- markers = ConcurrencyUtil.cacheOrGet(myMarkers, file, new WeakList<LazyMarker>());
+ markers = file.putUserDataIfAbsent(LAZY_MARKERS_KEY, new WeakList<LazyMarker>());
}
markers.add(marker);
}
- public static LazyRangeMarkerFactory getInstance(Project project) {
- return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
- }
-
@NotNull
public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset) {
return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
@@ -124,7 +124,7 @@ public class LazyRangeMarkerFactory {
});
}
- private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker{
+ private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker {
private RangeMarker myDelegate;
private final VirtualFile myFile;
protected final int myInitialOffset;
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java
index a09236a768cf..c43fd13d8bef 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java
@@ -119,7 +119,7 @@ public abstract class EditorActionHandler {
public void perform(Caret caret) {
doExecute(editor, caret, dataContext);
}
- });
+ }, true);
}
else {
doExecute(editor, contextCaret, dataContext);
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java
index 1e49937e7765..98d83656b580 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/TypedAction.java
@@ -107,10 +107,6 @@ public class TypedAction {
CommandProcessor.getInstance().executeCommand(CommonDataKeys.PROJECT.getData(dataContext), command, "", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
}
- public static boolean isTypedActionInProgress() {
- return CommandProcessor.getInstance().getCurrentCommand() instanceof TypingCommand;
- }
-
private class TypingCommand implements Runnable {
private final Editor myEditor;
private final char myCharTyped;
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
index d3f7d9f13f8c..13b2c43faa7b 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
@@ -16,8 +16,6 @@
package com.intellij.openapi.editor.highlighter;
import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.markup.TextAttributes;
@@ -25,9 +23,10 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
/**
* Created by IntelliJ IDEA.
@@ -36,10 +35,9 @@ import java.util.TreeMap;
* Time: 12:52 PM
*/
public class FragmentedEditorHighlighter implements EditorHighlighter {
- private final TreeMap<Integer, Element> myPieces;
+ private final List<Element> myPieces;
private final Document myDocument;
private final int myAdditionalOffset;
- private TextAttributes myUsualAttributes;
private final boolean myMergeByTextAttributes;
public FragmentedEditorHighlighter(HighlighterIterator sourceIterator, List<TextRange> ranges) {
@@ -52,50 +50,72 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
boolean mergeByTextAttributes) {
myMergeByTextAttributes = mergeByTextAttributes;
myDocument = sourceIterator.getDocument();
- myPieces = new TreeMap<Integer, Element>();
+ myPieces = new ArrayList<Element>();
myAdditionalOffset = additionalOffset;
translate(sourceIterator, ranges);
}
private void translate(HighlighterIterator iterator, List<TextRange> ranges) {
- if (iterator.atEnd()) return;
int offset = 0;
- for (TextRange range : ranges) {
- while (range.getStartOffset() > iterator.getStart()) {
+ int index = 0;
+
+ while (!iterator.atEnd() && index < ranges.size()) {
+ TextRange range = ranges.get(index);
+
+ if (range.getStartOffset() >= iterator.getEnd()) {
iterator.advance();
- if (iterator.atEnd()) return;
+ continue;
}
- while (range.getEndOffset() >= iterator.getEnd()) {
- int relativeStart = iterator.getStart() - range.getStartOffset();
+
+ if (range.getEndOffset() >= iterator.getStart()) {
+ int relativeStart = Math.max(iterator.getStart() - range.getStartOffset(), 0);
+ int relativeEnd = Math.min(iterator.getEnd() - range.getStartOffset(), range.getLength() + 1);
boolean merged = false;
- if (myMergeByTextAttributes && ! myPieces.isEmpty()) {
- final Integer first = myPieces.descendingKeySet().first();
- final Element element = myPieces.get(first);
- if (element.getEnd() >= offset + relativeStart && myPieces.get(first).getAttributes().equals(iterator.getTextAttributes())) {
- // merge
+ if (myMergeByTextAttributes && !myPieces.isEmpty()) {
+ Element element = myPieces.get(myPieces.size() - 1);
+ if (element.getEnd() >= offset + relativeStart &&
+ element.getAttributes().equals(iterator.getTextAttributes()) &&
+ element.getElementType().equals(iterator.getTokenType())) {
merged = true;
- myPieces.put(element.getStart(), new Element(element.getStart(),
- offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(),
- iterator.getTextAttributes()));
+ myPieces.add(new Element(element.getStart(),
+ offset + relativeEnd,
+ iterator.getTokenType(),
+ iterator.getTextAttributes()));
}
}
- if (! merged) {
- myPieces.put(offset + relativeStart, new Element(offset + relativeStart,
- offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(),
- iterator.getTextAttributes()));
+ if (!merged) {
+ myPieces.add(new Element(offset + relativeStart,
+ offset + relativeEnd,
+ iterator.getTokenType(),
+ iterator.getTextAttributes()));
}
- iterator.advance();
- if (iterator.atEnd()) return;
}
- offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
+
+ if (range.getEndOffset() < iterator.getEnd()) {
+ offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
+ int lastEnd = myPieces.isEmpty() ? -1 : myPieces.get(myPieces.size() - 1).getEnd();
+ myPieces.add(new Element(Math.max(offset - 1 - myAdditionalOffset, lastEnd), offset, null, TextAttributes.ERASE_MARKER));
+ index++;
+ continue;
+ }
+
+ iterator.advance();
}
}
@NotNull
@Override
public HighlighterIterator createIterator(int startOffset) {
- Map.Entry<Integer, Element> entry = myPieces.ceilingEntry(startOffset);
- return new ProxyIterator(myDocument, entry == null ? -1 : entry.getKey());
+ int index = Collections.binarySearch(myPieces, new Element(startOffset, 0, null, null), new Comparator<Element>() {
+ @Override
+ public int compare(Element o1, Element o2) {
+ return o1.getStart() - o2.getStart();
+ }
+ });
+ // index: (-insertion point - 1), where insertionPoint is the index of the first element greater than the key
+ // and we need index of the first element that is less or equal (floorElement)
+ if (index < 0) index = Math.max(-index - 2, 0);
+ return new ProxyIterator(myDocument, index);
}
@Override
@@ -149,27 +169,21 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
@Override
public void advance() {
- if (myIdx == myPieces.lastKey() || myIdx == -1) {
- myIdx = -1;
- return;
+ if (myIdx < myPieces.size()) {
+ myIdx++;
}
- Map.Entry<Integer, Element> entry = myPieces.tailMap(myIdx, false).firstEntry();
- myIdx = entry.getKey();
}
@Override
public void retreat() {
- if (myIdx == myPieces.firstKey() || myIdx == -1) {
- myIdx = -1;
- return;
+ if (myIdx > -1) {
+ myIdx--;
}
- Map.Entry<Integer, Element> entry = myPieces.headMap(myIdx, false).lastEntry();
- myIdx = entry.getKey();
}
@Override
public boolean atEnd() {
- return myIdx < 0;
+ return myIdx < 0 || myIdx >= myPieces.size();
}
@Override
@@ -178,22 +192,6 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
}
}
- private boolean isUsualAttributes(final TextAttributes ta) {
- if (myUsualAttributes == null) {
- final EditorColorsManager manager = EditorColorsManager.getInstance();
- final EditorColorsScheme[] schemes = manager.getAllSchemes();
- EditorColorsScheme defaultScheme = schemes[0];
- for (EditorColorsScheme scheme : schemes) {
- if (manager.isDefaultScheme(scheme)) {
- defaultScheme = scheme;
- break;
- }
- }
- myUsualAttributes = defaultScheme.getAttributes(HighlighterColors.TEXT);
- }
- return myUsualAttributes.equals(ta);
- }
-
private static class Element {
private final int myStart;
private final int myEnd;
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
index 64c4e7372d2e..9ec804def43d 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
@@ -271,4 +271,10 @@ public class OpenFileDescriptor implements Navigatable {
public boolean isUseCurrentWindow() {
return myUseCurrentWindow;
}
+
+ public void dispose() {
+ if (myRangeMarker != null) {
+ myRangeMarker.dispose();
+ }
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java
index 602615a656e2..906e2496296e 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java
@@ -40,7 +40,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -66,7 +65,8 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
if (browseActionListener != null) {
myBrowseButton.addActionListener(browseActionListener);
}
- add(myBrowseButton, BorderLayout.EAST);
+ // don't force FixedSizeButton to occupy the whole height
+ add(wrapWithoutResize(myBrowseButton), BorderLayout.EAST);
myBrowseButton.setToolTipText(UIBundle.message("component.with.browse.button.browse.button.tooltip.text"));
@@ -74,9 +74,12 @@ public class ComponentWithBrowseButton<Comp extends JComponent> extends JPanel i
if (ApplicationManager.getApplication() != null) { // avoid crash at design time
new MyDoClickAction(myBrowseButton).registerShortcut(myComponent);
}
- if (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula()) {
- setBorder(new EmptyBorder(0, 1, 0, 1));
- }
+ }
+
+ private static JPanel wrapWithoutResize(JComponent component) {
+ JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+ panel.add(component);
+ return panel;
}
public final Comp getChildComponent() {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
index 5eb15bd9d3cf..5bbd3d12da6a 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.ui;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -44,13 +45,13 @@ public class DetailsComponent {
private final NonOpaquePanel myBanner;
private String[] myBannerText;
- private boolean myDetailsEnabled = true;
+ private boolean myDetailsEnabled = !Registry.is("ide.new.project.settings");
private String[] myPrefix;
private String[] myText;
private final Wrapper myContentGutter = new Wrapper();
- private boolean myPaintBorder = true;
+ private boolean myPaintBorder = !Registry.is("ide.new.project.settings");
public DetailsComponent() {
myComponent = new JPanel(new BorderLayout()) {
@@ -109,7 +110,9 @@ public class DetailsComponent {
myBanner = new NonOpaquePanel(new BorderLayout());
myBannerLabel = new Banner();
- myBanner.add(myBannerLabel, BorderLayout.CENTER);
+ if (!Registry.is("ide.new.project.settings")) {
+ myBanner.add(myBannerLabel, BorderLayout.CENTER);
+ }
myEmptyContentLabel = new JLabel("", SwingConstants.CENTER);
@@ -167,7 +170,11 @@ public class DetailsComponent {
myContent.setBorder(new EmptyBorder(UIUtil.PANEL_REGULAR_INSETS));
}
else {
- myContent.setBorder(null);
+ if (Registry.is("ide.new.project.settings")) {
+ myContent.setBorder(new EmptyBorder(16, 10, 16, 10));
+ } else {
+ myContent.setBorder(null);
+ }
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
index 65b5d76b40a1..ed374a905462 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
@@ -42,6 +42,7 @@ public class DialogBuilder implements Disposable {
@NonNls public static final String REQUEST_FOCUS_ENABLED = "requestFocusEnabled";
private JComponent myCenterPanel;
+ private JComponent myNorthPanel;
private String myTitle;
private JComponent myPreferedFocusComponent;
private String myDimensionServiceKey;
@@ -89,6 +90,12 @@ public class DialogBuilder implements Disposable {
myCenterPanel = centerPanel;
}
+ @NotNull
+ public DialogBuilder setNorthPanel(@NotNull JComponent northPanel) {
+ myNorthPanel = northPanel;
+ return this;
+ }
+
public void setTitle(String title) {
myTitle = title;
}
@@ -349,6 +356,9 @@ public class DialogBuilder implements Disposable {
protected JComponent createCenterPanel() { return myCenterPanel; }
@Override
+ protected JComponent createNorthPanel() { return myNorthPanel; }
+
+ @Override
public void dispose() {
myPreferedFocusComponent = null;
super.dispose();
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index 188618e2f319..75cb4de7af74 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
@@ -73,12 +74,14 @@ import java.util.Set;
*/
@SuppressWarnings({"SSBasedInspection", "MethodMayBeStatic", "UnusedDeclaration"})
public abstract class DialogWrapper {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.ui.DialogWrapper");
- public static enum IdeModalityType {
+ public enum IdeModalityType {
IDE,
PROJECT,
MODELESS;
+ @NotNull
public Dialog.ModalityType toAwtModality() {
switch (this) {
case IDE:
@@ -88,7 +91,7 @@ public abstract class DialogWrapper {
case MODELESS:
return Dialog.ModalityType.MODELESS;
}
- return null;
+ throw new IllegalStateException(toString());
}
}
@@ -125,6 +128,7 @@ public abstract class DialogWrapper {
private static final KeyStroke SHOW_OPTION_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
+ @NotNull
private final DialogWrapperPeer myPeer;
private int myExitCode = CANCEL_EXIT_CODE;
@@ -158,10 +162,11 @@ public abstract class DialogWrapper {
@Nullable
private DoNotAskOption myDoNotAsk;
- private JComponent myPreferredFocusedComponent;
+ protected JComponent myPreferredFocusedComponent;
private Computable<Point> myInitialLocationCallback;
protected final Disposable myDisposable = new Disposable() {
+ @Override
public String toString() {
return DialogWrapper.this.toString();
}
@@ -176,6 +181,7 @@ public abstract class DialogWrapper {
private boolean myResizeInProgress = false;
private ComponentAdapter myResizeListener;
+ @NotNull
protected String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
}
@@ -203,7 +209,7 @@ public abstract class DialogWrapper {
this(project, canBeParent, IdeModalityType.IDE);
}
- protected DialogWrapper(@Nullable Project project, boolean canBeParent, IdeModalityType ideModalityType) {
+ protected DialogWrapper(@Nullable Project project, boolean canBeParent, @NotNull IdeModalityType ideModalityType) {
myPeer = createPeer(project, canBeParent, ideModalityType);
final Window window = myPeer.getWindow();
if (window != null) {
@@ -576,7 +582,7 @@ public abstract class DialogWrapper {
}
@NotNull
- public static JPanel addDoNotShowCheckBox(JComponent southPanel, @NotNull JCheckBox checkBox) {
+ public static JPanel addDoNotShowCheckBox(@NotNull JComponent southPanel, @NotNull JCheckBox checkBox) {
final JPanel panel = new JPanel(new BorderLayout());
JPanel wrapper = new JPanel(new GridBagLayout());
@@ -720,14 +726,14 @@ public abstract class DialogWrapper {
}
setMargin(button);
if (action.getValue(DEFAULT_ACTION) != null) {
- if (myPeer != null && !myPeer.isHeadless()) {
+ if (!myPeer.isHeadless()) {
getRootPane().setDefaultButton(button);
}
}
return button;
}
- private void setMargin(JButton button) {
+ private void setMargin(@NotNull JButton button) {
// Aqua LnF does a good job of setting proper margin between buttons. Setting them specifically causes them be 'square' style instead of
// 'rounded', which is expected by apple users.
if (!SystemInfo.isMac) {
@@ -738,6 +744,7 @@ public abstract class DialogWrapper {
}
}
+ @NotNull
protected DialogWrapperPeer createPeer(@NotNull Component parent, final boolean canBeParent) {
return DialogWrapperPeerFactory.getInstance().createPeer(this, parent, canBeParent);
}
@@ -747,26 +754,31 @@ public abstract class DialogWrapper {
* Instead, use e.g. {@link DialogWrapper#createPeer(Window, boolean, boolean)}
*/
@Deprecated
+ @NotNull
protected DialogWrapperPeer createPeer(boolean canBeParent, boolean applicationModalIfPossible) {
return createPeer(null, canBeParent, applicationModalIfPossible);
}
+ @NotNull
protected DialogWrapperPeer createPeer(final Window owner, final boolean canBeParent, final IdeModalityType ideModalityType) {
return DialogWrapperPeerFactory.getInstance().createPeer(this, owner, canBeParent, ideModalityType);
}
@Deprecated
+ @NotNull
protected DialogWrapperPeer createPeer(final Window owner, final boolean canBeParent, final boolean applicationModalIfPossible) {
return DialogWrapperPeerFactory.getInstance()
.createPeer(this, owner, canBeParent, applicationModalIfPossible ? IdeModalityType.IDE : IdeModalityType.PROJECT);
}
+ @NotNull
protected DialogWrapperPeer createPeer(@Nullable final Project project,
final boolean canBeParent,
- final IdeModalityType ideModalityType) {
+ @NotNull IdeModalityType ideModalityType) {
return DialogWrapperPeerFactory.getInstance().createPeer(this, project, canBeParent, ideModalityType);
}
+ @NotNull
protected DialogWrapperPeer createPeer(@Nullable final Project project, final boolean canBeParent) {
return DialogWrapperPeerFactory.getInstance().createPeer(this, project, canBeParent);
}
@@ -827,7 +839,7 @@ public abstract class DialogWrapper {
/**
* Dispose the wrapped and releases all resources allocated be the wrapper to help
- * more effecient garbage collection. You should never invoke this method twice or
+ * more efficient garbage collection. You should never invoke this method twice or
* invoke any method of the wrapper after invocation of <code>dispose</code>.
*
* @throws IllegalStateException if the dialog is disposed not on the event dispatch thread
@@ -865,7 +877,7 @@ public abstract class DialogWrapper {
for (KeyStroke eachStroke : strokes) {
boolean remove = true;
if (actionMap != null) {
- for (int i = 0; i < 3; i++) {
+ for (int i : new int[]{JComponent.WHEN_FOCUSED, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, JComponent.WHEN_IN_FOCUSED_WINDOW}) {
final InputMap inputMap = eachComp.getInputMap(i);
final Object key = inputMap.get(eachStroke);
if (key != null) {
@@ -1036,7 +1048,6 @@ public abstract class DialogWrapper {
* @see javax.swing.JDialog#getContentPane
*/
public Container getContentPane() {
- assert myPeer != null;
return myPeer.getContentPane();
}
@@ -1152,6 +1163,9 @@ public abstract class DialogWrapper {
}
protected void init() {
+ if (!SwingUtilities.isEventDispatchThread()) {
+ LOG.error("Dialog must be init in EDT only: "+Thread.currentThread());
+ }
myErrorText = new ErrorText();
myErrorText.setVisible(false);
@@ -1221,6 +1235,7 @@ public abstract class DialogWrapper {
}
}
+ @NotNull
LayoutManager createRootLayout() {
return new BorderLayout();
}
@@ -1309,6 +1324,7 @@ public abstract class DialogWrapper {
return true;
}
+ @NotNull
protected JComponent createContentPane() {
return new JPanel();
}
@@ -1486,6 +1502,7 @@ public abstract class DialogWrapper {
* @return dialog location
* @see javax.swing.JDialog#getLocation
*/
+ @NotNull
public Point getLocation() {
return myPeer.getLocation();
}
@@ -1494,7 +1511,7 @@ public abstract class DialogWrapper {
* @param p new dialog location
* @see javax.swing.JDialog#setLocation(Point)
*/
- public void setLocation(Point p) {
+ public void setLocation(@NotNull Point p) {
myPeer.setLocation(p);
}
@@ -1564,7 +1581,7 @@ public abstract class DialogWrapper {
return myInitialLocationCallback == null ? null : myInitialLocationCallback.compute();
}
- public void setInitialLocationCallback(Computable<Point> callback) {
+ public void setInitialLocationCallback(@NotNull Computable<Point> callback) {
myInitialLocationCallback = callback;
}
@@ -1711,7 +1728,7 @@ public abstract class DialogWrapper {
*
* @param name the action name (see {@link Action#NAME})
*/
- protected DialogWrapperAction(String name) {
+ protected DialogWrapperAction(@NotNull String name) {
putValue(NAME, name);
}
@@ -1838,9 +1855,6 @@ public abstract class DialogWrapper {
if (myMaxErrorTextLength == 0) {
updateHeightForErrorText();
}
- else {
- //if (getRootPane() != null) myPeer.pack();
- }
myMaxErrorTextLength = text.length();
updateHeightForErrorText();
}
@@ -1864,7 +1878,7 @@ public abstract class DialogWrapper {
return null;
}
- private void resizeWithAnimation(final Dimension size) {
+ private void resizeWithAnimation(@NotNull final Dimension size) {
//todo[kb]: fix this PITA
myResizeInProgress = true;
if (!Registry.is("enable.animation.on.dialogs")) {
@@ -1961,6 +1975,7 @@ public abstract class DialogWrapper {
}
}
+ @NotNull
public final DialogWrapperPeer getPeer() {
return myPeer;
}
@@ -1976,6 +1991,7 @@ public abstract class DialogWrapper {
}
}
+ @NotNull
public final Disposable getDisposable() {
return myDisposable;
}
@@ -1996,14 +2012,15 @@ public abstract class DialogWrapper {
boolean shouldSaveOptionsOnCancel();
+ @NotNull
String getDoNotShowMessage();
}
public static class PropertyDoNotAskOption implements DoNotAskOption {
-
+ @NotNull
private final String myProperty;
- public PropertyDoNotAskOption(String property) {
+ public PropertyDoNotAskOption(@NotNull String property) {
myProperty = property;
}
@@ -2027,12 +2044,14 @@ public abstract class DialogWrapper {
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.ask");
}
}
+ @NotNull
private ErrorPaintingType getErrorPaintingType() {
return ErrorPaintingType.SIGN;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java
index dddef7fa3705..9012dbfbb03c 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -129,12 +130,13 @@ public abstract class DialogWrapperPeer {
/**
* @see javax.swing.JDialog#getLocation
*/
+ @NotNull
public abstract Point getLocation();
/**
* @see javax.swing.JDialog#setLocation(java.awt.Point)
*/
- public abstract void setLocation(Point p);
+ public abstract void setLocation(@NotNull Point p);
/**
* @see javax.swing.JDialog#setLocation(int,int)
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
index 6c39569a8f56..c9515a884f97 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -37,20 +37,28 @@ public abstract class DialogWrapperPeerFactory {
return ServiceManager.getService(DialogWrapperPeerFactory.class);
}
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent);
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, boolean canBeParent);
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType);
/** @see DialogWrapper#DialogWrapper(boolean, boolean)
*/
@Deprecated
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, boolean canBeParent, boolean applicationModalIfPossible);
@Deprecated
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, Window owner, boolean canBeParent, boolean applicationModalIfPossible);
@Deprecated
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent);
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType);
+ @NotNull
public abstract DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, Window owner, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType);
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java
index bdb9660c9090..6f38d9a96356 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java
@@ -87,14 +87,15 @@ public class FixedSizeButton extends JButton {
public Dimension getPreferredSize() {
if (myComponent != null) {
int size = myComponent.getPreferredSize().height;
+ if (myComponent instanceof ComboBox && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) {
+ size -= 2; // decrement to match JTextField's preferred height
+ }
return new Dimension(size, size);
}
- else if (mySize != -1) {
+ if (mySize != -1) {
return new Dimension(mySize, mySize);
}
- else {
- return super.getPreferredSize();
- }
+ return super.getPreferredSize();
}
public void setAttachedComponent(JComponent component) {
@@ -108,5 +109,21 @@ public class FixedSizeButton extends JButton {
public void setSize(int size) {
mySize = size;
}
-}
+ @Override
+ public void setBounds(int x, int y, int width, int height) {
+ int size = Math.min(width, height);
+ super.setBounds(x, y, size, size);
+ }
+
+ @Override
+ public void setBounds(Rectangle r) {
+ if (r.width != r.height) {
+ int size = Math.min(r.width, r.height);
+ r = new Rectangle(r);
+ r.width = size;
+ r.height = size;
+ }
+ super.setBounds(r);
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
index 0003e717b35c..35e81b032ba5 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.navigation.History;
@@ -46,6 +47,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.tree.*;
import java.awt.*;
import java.util.*;
@@ -61,7 +63,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected static final Icon COPY_ICON = PlatformIcons.COPY_ICON;
protected NamedConfigurable myCurrentConfigurable;
- private final Splitter mySplitter = new Splitter(false, .2f);
+ private final JBSplitter mySplitter;
@NonNls public static final String TREE_OBJECT = "treeObject";
@NonNls public static final String TREE_NAME = "treeName";
@@ -79,7 +81,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
public void queryPlace(@NotNull final Place place) {
}
});
- private JScrollPane myMaster;
+ private JComponent myMaster;
public void setHistory(final History history) {
myHistory = history;
@@ -128,6 +130,18 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected MasterDetailsComponent(MasterDetailsState state) {
myState = state;
+
+ mySplitter = new JBSplitter(false, .2f);
+ mySplitter.setSplitterProportionKey("ProjectStructure.SecondLevelElements");
+ mySplitter.setHonorComponentsMinimumSize(true);
+ if (Registry.is("ide.new.project.settings")) {
+ mySplitter.setDividerWidth(1);
+ mySplitter.setShowDividerIcon(false);
+ mySplitter.getDivider().setBackground(Gray._153.withAlpha(128));
+ mySplitter.setShowDividerControls(false);
+ mySplitter.setOrientation(mySplitter.getOrientation());
+ }
+
installAutoScroll();
reInitWholePanelIfNeeded();
}
@@ -163,8 +177,18 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
}
};
- left.add(myNorthPanel, BorderLayout.NORTH);
- myMaster = ScrollPaneFactory.createScrollPane(myTree);
+ if (Registry.is("ide.new.project.settings")) {
+ ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree);
+ DefaultActionGroup group = createToolbarActionGroup();
+ if (group != null) {
+ decorator.setActionGroup(group);
+ }
+ //left.add(myNorthPanel, BorderLayout.NORTH);
+ myMaster = decorator.setPanelBorder(new EmptyBorder(0, 0, 0, 0)).createPanel();
+ } else {
+ left.add(myNorthPanel, BorderLayout.NORTH);
+ myMaster = ScrollPaneFactory.createScrollPane(myTree);
+ }
left.add(myMaster, BorderLayout.CENTER);
mySplitter.setFirstComponent(left);
@@ -245,7 +269,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
return myHistory == null || !myHistory.isNavigatingNow();
}
- private void initToolbar() {
+ protected DefaultActionGroup createToolbarActionGroup() {
final ArrayList<AnAction> actions = createActions(false);
if (actions != null) {
final DefaultActionGroup group = new DefaultActionGroup();
@@ -257,6 +281,14 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
group.add(action);
}
}
+ return group;
+ }
+ return null;
+ }
+
+ private void initToolbar() {
+ DefaultActionGroup group = createToolbarActionGroup();
+ if (group != null) {
final JComponent component = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
myNorthPanel.add(component, BorderLayout.NORTH);
}
@@ -270,6 +302,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
return new Dimension(800, 600);
}
+ @NotNull
public JComponent createComponent() {
reInitWholePanelIfNeeded();
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
index 72ac12abc065..dae35d4b685d 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
@@ -1374,6 +1374,7 @@ public class Messages {
return doCreateCenterPanel();
}
+ @NotNull
@Override
LayoutManager createRootLayout() {
return isMacSheetEmulation() ? myLayout = new MyBorderLayout() : super.createRootLayout();
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
index afce920e5f07..faa26e2415b8 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -46,7 +46,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
*
* /-------/
* | | |
- * This is horihontal split | 1 | 2 |
+ * This is horizontal split | 1 | 2 |
* | | |
* /-------/
*/
diff --git a/platform/platform-api/src/com/intellij/openapi/util/DefaultModificationTracker.java b/platform/platform-api/src/com/intellij/openapi/util/DefaultModificationTracker.java
index 05f8417e1780..bd5a2dfc61c2 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/DefaultModificationTracker.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/DefaultModificationTracker.java
@@ -1,16 +1,19 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.openapi.util;
-import java.util.concurrent.atomic.AtomicLong;
-
-public class DefaultModificationTracker implements ModificationTracker {
- private volatile AtomicLong myCount = new AtomicLong();
-
- @Override
- public long getModificationCount() {
- return myCount.get();
- }
-
- public void incModificationCount() {
- myCount.incrementAndGet();
- }
+public class DefaultModificationTracker extends SimpleModificationTracker {
}
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
index 13269fee8c5a..6584184a1bb2 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.wm;
+import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.ActiveRunnable;
@@ -141,6 +142,10 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
return myAllocation;
}
+ public boolean canFocusChangeFrom(@Nullable Component component) {
+ return true;
+ }
+
@Override
public String toString() {
final Object[] objects = getEqualityObjects();
@@ -213,5 +218,11 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
public Component getComponent() {
return myToFocus;
}
+
+ @Override
+ public boolean canFocusChangeFrom(@Nullable Component component) {
+ DialogWrapper dialog = DialogWrapper.findInstance(component);
+ return (dialog == null) || (dialog == DialogWrapper.findInstance(myToFocus));
+ }
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/EditorNotificationPanel.java b/platform/platform-api/src/com/intellij/ui/EditorNotificationPanel.java
index deb1f0545b74..2872a4592c01 100644
--- a/platform/platform-api/src/com/intellij/ui/EditorNotificationPanel.java
+++ b/platform/platform-api/src/com/intellij/ui/EditorNotificationPanel.java
@@ -36,11 +36,12 @@ import java.awt.*;
*/
public class EditorNotificationPanel extends JPanel {
protected final JLabel myLabel = new JLabel();
+ protected final JLabel myGearLabel = new JLabel();
protected final JPanel myLinksPanel;
public EditorNotificationPanel() {
super(new BorderLayout());
- setBorder(BorderFactory.createEmptyBorder(1, 15, 1, 15));
+ setBorder(BorderFactory.createEmptyBorder(1, 10, 1, 10));
setPreferredSize(new Dimension(-1, 24));
@@ -48,7 +49,13 @@ public class EditorNotificationPanel extends JPanel {
myLinksPanel = new JPanel(new FlowLayout());
myLinksPanel.setBackground(getBackground());
- add(myLinksPanel, BorderLayout.EAST);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setBackground(getBackground());
+ myGearLabel.setBorder(IdeBorderFactory.createEmptyBorder(0, 3, 0, 0));
+ panel.add(myLinksPanel, BorderLayout.WEST);
+ panel.add(myGearLabel, BorderLayout.EAST);
+ add(panel, BorderLayout.EAST);
}
public void setText(String text) {
diff --git a/platform/platform-api/src/com/intellij/ui/EditorNotifications.java b/platform/platform-api/src/com/intellij/ui/EditorNotifications.java
index 4db32d94dd30..6805266e57ad 100644
--- a/platform/platform-api/src/com/intellij/ui/EditorNotifications.java
+++ b/platform/platform-api/src/com/intellij/ui/EditorNotifications.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -31,10 +32,11 @@ import javax.swing.*;
public abstract class EditorNotifications extends AbstractProjectComponent {
public abstract static class Provider<T extends JComponent> {
+ @NotNull
public abstract Key<T> getKey();
@Nullable
- public abstract T createNotificationPanel(VirtualFile file, FileEditor fileEditor);
+ public abstract T createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor);
}
public static EditorNotifications getInstance(Project project) {
@@ -45,7 +47,7 @@ public abstract class EditorNotifications extends AbstractProjectComponent {
super(project);
}
- public abstract void updateNotifications(final VirtualFile file);
+ public abstract void updateNotifications(@NotNull VirtualFile file);
public abstract void updateAllNotifications();
diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
index 2293d45bf329..3ddbf47028f4 100644
--- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,7 +15,9 @@
*/
package com.intellij.ui;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.panels.OpaquePanel;
+import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
@@ -24,16 +26,43 @@ import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
+import static javax.swing.SwingConstants.CENTER;
+import static javax.swing.SwingConstants.LEFT;
+
public abstract class GroupedElementsRenderer {
public static final Color POPUP_SEPARATOR_FOREGROUND = new JBColor(Color.gray.brighter(), Gray._43);
public static final Color POPUP_SEPARATOR_TEXT_FOREGROUND = Color.gray;
public static final Color SELECTED_FRAME_FOREGROUND = Color.black;
- protected SeparatorWithText mySeparatorComponent = new SeparatorWithText();
+ protected SeparatorWithText mySeparatorComponent = new SeparatorWithText() {
+ @Override
+ protected void paintComponent(Graphics g) {
+ if (Registry.is("ide.new.project.settings")) {
+ g.setColor(POPUP_SEPARATOR_FOREGROUND);
+ Rectangle viewR = new Rectangle(0, getVgap(), getWidth() - 1, getHeight() - getVgap() - 1);
+ Rectangle iconR = new Rectangle();
+ Rectangle textR = new Rectangle();
+ String s = SwingUtilities
+ .layoutCompoundLabel(g.getFontMetrics(), getCaption(), null, CENTER,
+ LEFT,
+ CENTER,
+ LEFT,
+ viewR, iconR, textR, 0);
+ GraphicsUtil.setupAAPainting(g);
+ g.setColor(Gray._255.withAlpha(80));
+ g.drawString(s, textR.x + 10, textR.y + 1 + g.getFontMetrics().getAscent());
+ g.setColor(new Color(0x5F6D7B));
+ g.drawString(s, textR.x + 10, textR.y + g.getFontMetrics().getAscent());
+ } else {
+ super.paintComponent(g);
+ }
+ }
+ };
+
protected JComponent myComponent;
protected MyComponent myRendererComponent;
- protected ErrorLabel myTextLabel;
+ protected JLabel myTextLabel;
public GroupedElementsRenderer() {
@@ -58,14 +87,16 @@ public abstract class GroupedElementsRenderer {
myTextLabel.setIcon(icon);
myTextLabel.setDisabledIcon(disabledIcon);
+ if (myTextLabel instanceof EngravedLabel) {
+ ((EngravedLabel)myTextLabel).setShadowColor(isSelected ? UIUtil.getTreeSelectionBackground() : null);
+ }
if (isSelected) {
- myComponent.setBorder(getSelectedBorder());
+ //myComponent.setBorder(getSelectedBorder());
setSelected(myComponent);
setSelected(myTextLabel);
- }
- else {
- myComponent.setBorder(getBorder());
+ } else {
+ //myComponent.setBorder(getBorder());
setDeselected(myComponent);
setDeselected(myTextLabel);
}
@@ -98,7 +129,7 @@ public abstract class GroupedElementsRenderer {
protected final void setDeselected(JComponent aComponent) {
aComponent.setBackground(getBackground());
- aComponent.setForeground(getForeground());
+ aComponent.setForeground(Registry.is("ide.new.project.settings") ? Gray._60 : getForeground());
}
protected abstract Color getSelectionBackground();
@@ -139,12 +170,12 @@ public abstract class GroupedElementsRenderer {
}
@Override
- protected final Color getBackground() {
+ protected Color getBackground() {
return UIUtil.getListBackground();
}
@Override
- protected final Color getForeground() {
+ protected Color getForeground() {
return UIUtil.getListForeground();
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/SeparatorWithText.java b/platform/platform-api/src/com/intellij/ui/SeparatorWithText.java
index 059875a4acfc..2633ef31c9f3 100644
--- a/platform/platform-api/src/com/intellij/ui/SeparatorWithText.java
+++ b/platform/platform-api/src/com/intellij/ui/SeparatorWithText.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +20,8 @@ import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
-import static javax.swing.SwingConstants.*;
+import static javax.swing.SwingConstants.CENTER;
+import static javax.swing.SwingConstants.LEFT;
public class SeparatorWithText extends JComponent {
@@ -34,11 +35,11 @@ public class SeparatorWithText extends JComponent {
setFont(getFont().deriveFont(Font.BOLD));
}
- private static int getVgap() {
+ protected static int getVgap() {
return UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
}
- private static int getHgap() {
+ protected static int getHgap() {
return 3;
}
@@ -109,6 +110,10 @@ public class SeparatorWithText extends JComponent {
}
}
+ protected String getCaption() {
+ return myCaption;
+ }
+
public void setCaption(String captionAboveOf) {
myCaption = captionAboveOf;
}
diff --git a/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java b/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
index 3d816000de70..695bad005135 100644
--- a/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
@@ -123,14 +123,13 @@ public class TableScrollingUtil {
}
- public static void moveDown(JTable list, @JdkConstants.InputEventMask int modifiers) {
+ public static void moveDown(JTable list, @JdkConstants.InputEventMask int modifiers, boolean cycleScrolling) {
int size = list.getModel().getRowCount();
if (size == 0) {
return;
}
final ListSelectionModel selectionModel = list.getSelectionModel();
int index = selectionModel.getLeadSelectionIndex();
- boolean cycleScrolling = UISettings.getInstance().CYCLE_SCROLLING;
final int indexToSelect;
if (index < size - 1) {
indexToSelect = index + 1;
@@ -153,11 +152,10 @@ public class TableScrollingUtil {
}
}
- public static void moveUp(JTable list, @JdkConstants.InputEventMask int modifiers) {
+ public static void moveUp(JTable list, @JdkConstants.InputEventMask int modifiers, boolean cycleScrolling) {
int size = list.getModel().getRowCount();
final ListSelectionModel selectionModel = list.getSelectionModel();
int index = selectionModel.getMinSelectionIndex();
- boolean cycleScrolling = UISettings.getInstance().CYCLE_SCROLLING;
int indexToSelect;
if (index > 0) {
indexToSelect = index - 1;
@@ -249,6 +247,10 @@ public class TableScrollingUtil {
}
public static void installActions(final JTable list) {
+ installActions(list, UISettings.getInstance().CYCLE_SCROLLING);
+ }
+
+ public static void installActions(final JTable list, final boolean cycleScrolling) {
ActionMap actionMap = list.getActionMap();
actionMap.put(ListScrollingUtil.SCROLLUP_ACTION_ID, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
@@ -262,12 +264,12 @@ public class TableScrollingUtil {
});
actionMap.put(ListScrollingUtil.SELECT_PREVIOUS_ROW_ACTION_ID, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
- moveUp(list, e.getModifiers());
+ moveUp(list, e.getModifiers(), cycleScrolling);
}
});
actionMap.put(ListScrollingUtil.SELECT_NEXT_ROW_ACTION_ID, new AbstractAction() {
public void actionPerformed(ActionEvent e) {
- moveDown(list, e.getModifiers());
+ moveDown(list, e.getModifiers(), cycleScrolling);
}
});
actionMap.put(ListScrollingUtil.SELECT_LAST_ROW_ACTION_ID, new AbstractAction() {
diff --git a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java
index 24cb28001fed..80e3d1eec7fb 100644
--- a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java
+++ b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,10 +15,7 @@
*/
package com.intellij.ui;
-import com.intellij.openapi.actionSystem.ActionGroup;
-import com.intellij.openapi.actionSystem.ActionToolbar;
-import com.intellij.openapi.actionSystem.ActionToolbarPosition;
-import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
@@ -296,7 +293,9 @@ public abstract class ToolbarDecorator implements CommonActionsPanel.ListenerFac
public ToolbarDecorator setActionGroup(@NotNull ActionGroup actionGroup) {
AnAction[] actions = actionGroup.getChildren(null);
for (AnAction action : actions) {
- addExtraAction(AnActionButton.fromAction(action));
+ if (!(action instanceof Separator)) {
+ addExtraAction(AnActionButton.fromAction(action));
+ }
}
return this;
}
diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
index e0c326ad1edb..83944a51755d 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
@@ -33,7 +33,10 @@ import java.lang.reflect.Method;
public class JBScrollPane extends JScrollPane {
private int myViewportBorderWidth = -1;
- private JLayeredPane myLayeredPane;
+ private boolean myHasOverlayScrollbars;
+
+ private int myOverriddenVPolicy = -1;
+ private int myOverriddenHPolicy = -1;
public JBScrollPane(int viewportWidth) {
init(false);
@@ -64,89 +67,14 @@ public class JBScrollPane extends JScrollPane {
if (c == null) return null;
if (!(c instanceof JViewport)) {
- // if asked for a viewport child, take a viewport.
- // If not (e.g asked for a scrollbar), go straight to JLayeredPane
Container vp = c.getParent();
if (vp instanceof JViewport) c = vp;
}
c = c.getParent();
- if (c instanceof JLayeredPane) {
- c = c.getParent();
- }
- if (!(c instanceof JBScrollPane)) return null;
-
- return (JBScrollPane)c;
- }
-
- @Override
- public void setVerticalScrollBar(JScrollBar c) {
- JScrollBar old = getVerticalScrollBar();
- super.setVerticalScrollBar(c);
- transferToLayeredPane(old, c, ScrollPaneConstants.VERTICAL_SCROLLBAR);
- }
-
- @Override
- public void setHorizontalScrollBar(JScrollBar c) {
- JScrollBar old = getHorizontalScrollBar();
- super.setHorizontalScrollBar(c);
- transferToLayeredPane(old, c, ScrollPaneConstants.HORIZONTAL_SCROLLBAR);
- }
-
- @Override
- public void setColumnHeader(JViewport c) {
- JViewport old = getColumnHeader();
- super.setColumnHeader(c);
- transferToLayeredPane(old, c, ScrollPaneConstants.COLUMN_HEADER);
- }
+ if (!(c instanceof JScrollPane)) return null;
- @Override
- public void setRowHeader(JViewport c) {
- JViewport old = getRowHeader();
- super.setRowHeader(c);
- transferToLayeredPane(old, c, ScrollPaneConstants.ROW_HEADER);
- }
-
- @Override
- public void setViewport(JViewport c) {
- JViewport old = getViewport();
- super.setViewport(c);
- transferToLayeredPane(old, c, ScrollPaneConstants.VIEWPORT);
- }
-
- @Override
- public void setCorner(String key, Component c) {
- Component old = getCorner(key);
- super.setCorner(key, c);
- transferToLayeredPane(old, c, key);
- }
-
- private void transferToLayeredPane(Component old, Component c, String key) {
- if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return;
-
- JLayeredPane pane = getLayoutPane();
- LayoutManager layout = getLayout();
-
- if (old != null && old != c) {
- pane.remove(old);
- layout.removeLayoutComponent(old);
- }
-
- if (c != null) {
- if (ScrollPaneConstants.VERTICAL_SCROLLBAR.equals(key) || ScrollPaneConstants.HORIZONTAL_SCROLLBAR.equals(key)) {
- pane.setLayer(c, JLayeredPane.PALETTE_LAYER);
- }
- pane.add(c);
- layout.addLayoutComponent(key, c);
- }
- }
-
- @NotNull
- private JLayeredPane getLayoutPane() {
- if (myLayeredPane == null) {
- myLayeredPane = new JLayeredPane();
- }
- return myLayeredPane;
+ return (JScrollPane)c;
}
private void init() {
@@ -154,9 +82,6 @@ public class JBScrollPane extends JScrollPane {
}
private void init(boolean setupCorners) {
- if (ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) {
- add(getLayoutPane());
- }
setLayout(new ScrollPaneLayout());
if (setupCorners) {
@@ -178,6 +103,11 @@ public class JBScrollPane extends JScrollPane {
updateViewportBorder();
}
+ @Override
+ public boolean isOptimizedDrawingEnabled() {
+ return !myHasOverlayScrollbars;
+ }
+
private void updateViewportBorder() {
setViewportBorder(new ViewportBorder(myViewportBorderWidth >= 0 ? myViewportBorderWidth : 1));
}
@@ -201,24 +131,75 @@ public class JBScrollPane extends JScrollPane {
return new JBViewport();
}
+ @Override
+ public int getHorizontalScrollBarPolicy() {
+ // See layout() for explanation
+ //noinspection MagicConstant
+ return myOverriddenHPolicy != -1 ? myOverriddenHPolicy : super.getHorizontalScrollBarPolicy();
+ }
+
+ @Override
+ public int getVerticalScrollBarPolicy() {
+ // See layout() for explanation
+ //noinspection MagicConstant
+ return myOverriddenVPolicy != -1 ? myOverriddenVPolicy : super.getVerticalScrollBarPolicy();
+ }
+
@SuppressWarnings("deprecation")
@Override
public void layout() {
+ LayoutManager layout = getLayout();
+ ScrollPaneLayout scrollLayout = layout instanceof ScrollPaneLayout ? (ScrollPaneLayout)layout : null;
+
+ // Logic here is a workaround necessary to support OS X overlaid scrollbars.
+
+ int oldHPolicy = -1;
+ int oldVPolicy = -1;
+ if (scrollLayout != null) {
+ // First, we override scrollbar policy to HORIZONTAL_SCROLLBAR_AS_NEEDED so JScrollPane could correctly lay them out.
+ // We do so only when policy is ALWAYS so they could be hidden by JScrollPane when necessary.
+ // Also, we only override when scrollbar is an overlay scrollbar.
+ // (The related problem is IDEA-123688)
+ if (isOverlaidScrollbar(getHorizontalScrollBar())) {
+ oldHPolicy = scrollLayout.getHorizontalScrollBarPolicy();
+ if (oldHPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
+ scrollLayout.setHorizontalScrollBarPolicy(myOverriddenHPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ }
+ }
+
+ if (isOverlaidScrollbar(getVerticalScrollBar())) {
+ oldVPolicy = scrollLayout.getVerticalScrollBarPolicy();
+ if (oldVPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
+ scrollLayout.setVerticalScrollBarPolicy(myOverriddenVPolicy = VERTICAL_SCROLLBAR_AS_NEEDED);
+ }
+ }
+ }
+
+ // Now we let JScrollPane layout everything as necessary
super.layout();
- if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return;
-
- LayoutManager layout = getLayout();
- if (layout instanceof ScrollPaneLayout && myLayeredPane != null) {
- relayoutScrollbars(this, (ScrollPaneLayout)layout, myLayeredPane);
+ if (scrollLayout != null) {
+ // Now it's time to jump in and expand the viewport so it fits the whole area
+ // (taking into consideration corners, headers and other stuff).
+ myHasOverlayScrollbars = relayoutScrollbars(
+ this, scrollLayout,
+ myHasOverlayScrollbars // If last time we did relayouting, we should restore it back.
+ );
+
+ // Now we restore overridden policies as though nothing happened at all.
+ if (oldHPolicy != -1) scrollLayout.setHorizontalScrollBarPolicy(oldHPolicy);
+ if (oldVPolicy != -1) scrollLayout.setVerticalScrollBarPolicy(oldVPolicy);
+ myOverriddenHPolicy = -1;
+ myOverriddenVPolicy = -1;
+ }
+ else {
+ myHasOverlayScrollbars = false;
}
}
- private static void relayoutScrollbars(@NotNull JComponent container,
- @NotNull ScrollPaneLayout layout,
- @NotNull JLayeredPane layeredPane) {
+ private static boolean relayoutScrollbars(@NotNull JComponent container, @NotNull ScrollPaneLayout layout, boolean forceRelayout) {
JViewport viewport = layout.getViewport();
- if (viewport == null) return;
+ if (viewport == null) return false;
JScrollBar vsb = layout.getVerticalScrollBar();
JScrollBar hsb = layout.getHorizontalScrollBar();
@@ -227,22 +208,29 @@ public class JBScrollPane extends JScrollPane {
Rectangle viewportBounds = viewport.getBounds();
- boolean extendsViewportUnderVScrollbar = vsb != null && shouldExtendViewportUnderScrollbar(vsb);
- boolean extendsViewportUnderHScrollbar = hsb != null && shouldExtendViewportUnderScrollbar(hsb);
-
- if (extendsViewportUnderVScrollbar) {
+ boolean extendViewportUnderVScrollbar = vsb != null && shouldExtendViewportUnderScrollbar(vsb);
+ boolean extendViewportUnderHScrollbar = hsb != null && shouldExtendViewportUnderScrollbar(hsb);
+ boolean hasOverlayScrollbars = extendViewportUnderVScrollbar || extendViewportUnderHScrollbar;
+
+ if (!hasOverlayScrollbars && !forceRelayout) return false;
+
+ container.setComponentZOrder(viewport, container.getComponentCount() - 1);
+ if (vsb != null) container.setComponentZOrder(vsb, 0);
+ if (hsb != null) container.setComponentZOrder(hsb, 0);
+
+ if (extendViewportUnderVScrollbar) {
viewportBounds.x = Math.min(viewportBounds.x, vsb.getX());
- viewportBounds.width = Math.max(viewportBounds.width, vsb.getX() + vsb.getWidth());
+ viewportBounds.width = vsb.getX() + vsb.getWidth() - viewportBounds.x;
}
- if (extendsViewportUnderHScrollbar) {
+ if (extendViewportUnderHScrollbar) {
viewportBounds.y = Math.min(viewportBounds.y, hsb.getY());
- viewportBounds.height = Math.max(viewportBounds.height, hsb.getY() + hsb.getHeight());
+ viewportBounds.height = hsb.getY() + hsb.getHeight() - viewportBounds.y;
}
- if (extendsViewportUnderVScrollbar) {
+ if (extendViewportUnderVScrollbar) {
if (hsb != null) {
Rectangle scrollbarBounds = hsb.getBounds();
- scrollbarBounds.width = viewportBounds.width - scrollbarBounds.x;
+ scrollbarBounds.width = viewportBounds.x + viewportBounds.width - scrollbarBounds.x;
hsb.setBounds(scrollbarBounds);
}
if (colHead != null) {
@@ -253,10 +241,10 @@ public class JBScrollPane extends JScrollPane {
hideFromView(layout.getCorner(UPPER_RIGHT_CORNER));
hideFromView(layout.getCorner(LOWER_RIGHT_CORNER));
}
- if (extendsViewportUnderHScrollbar) {
+ if (extendViewportUnderHScrollbar) {
if (vsb != null) {
Rectangle scrollbarBounds = vsb.getBounds();
- scrollbarBounds.height = viewportBounds.height - scrollbarBounds.y;
+ scrollbarBounds.height = viewportBounds.y + viewportBounds.height - scrollbarBounds.y;
vsb.setBounds(scrollbarBounds);
}
if (rowHead != null) {
@@ -270,14 +258,19 @@ public class JBScrollPane extends JScrollPane {
}
viewport.setBounds(viewportBounds);
- Insets insets = container.getInsets();
- if (insets == null) insets = new Insets(0, 0, 0, 0);
- layeredPane.setBounds(0, 0, container.getWidth() - insets.right, container.getHeight() - insets.bottom);
+
+ return hasOverlayScrollbars;
}
private static boolean shouldExtendViewportUnderScrollbar(@Nullable JScrollBar scrollbar) {
if (scrollbar == null || !scrollbar.isVisible()) return false;
- ScrollBarUI vsbUI = scrollbar.getUI();
+ return isOverlaidScrollbar(scrollbar);
+ }
+
+ private static boolean isOverlaidScrollbar(@Nullable JScrollBar scrollbar) {
+ if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return false;
+
+ ScrollBarUI vsbUI = scrollbar == null ? null : scrollbar.getUI();
return vsbUI instanceof ButtonlessScrollBarUI && !((ButtonlessScrollBarUI)vsbUI).alwaysShowTrack();
}
diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
index 1c4cd484ac61..51fb54a5baa1 100644
--- a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
+++ b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
@@ -57,7 +57,7 @@ public class SpeedSearch {
}
else {
final char ch = e.getKeyChar();
- if (Character.isLetterOrDigit(ch) || ch == ' ' || ch == '*' || ch == '_' || ch == '-' || ch == '"' || ch == '\'') {
+ if (Character.isLetterOrDigit(ch) || ch == ' ' || ch == '*' || ch == '_' || ch == '-' || ch == '"' || ch == '\'' || ch == '/' || ch == '.') {
type(Character.toString(ch));
e.consume();
}
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index f8e91cb5cebf..d8736f6fc08e 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -19,7 +19,6 @@ import com.intellij.Patches;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.*;
-import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.JBViewport;
import com.intellij.ui.speedSearch.SpeedSearchSupply;
import com.intellij.util.ui.*;
@@ -135,45 +134,6 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
}
@Override
- protected void configureEnclosingScrollPane() {
- super.configureEnclosingScrollPane();
-
- // base class' method doesn't expect layered pane between the viewport and the scrollpane (required for mac scrollbars)
- JBScrollPane sp = getJBScrollPane();
- if (sp == null) return;
-
- JViewport viewport = sp.getViewport();
- if (viewport == null || viewport.getView() != this) return;
- sp.setColumnHeaderView(getTableHeader());
- }
-
- @Override
- protected void unconfigureEnclosingScrollPane() {
- super.unconfigureEnclosingScrollPane();
-
- JBScrollPane sp = getJBScrollPane();
- if (sp == null) return;
-
- JViewport viewport = sp.getViewport();
- if (viewport == null || viewport.getView() != this) return;
- sp.setColumnHeaderView(null);
- }
-
- private JBScrollPane getJBScrollPane() {
- Container p = getParent();
- if (p instanceof JViewport) {
- Container gp = p.getParent();
- if (gp instanceof JLayeredPane) {
- Container ggp = gp.getParent();
- if (ggp instanceof JBScrollPane) {
- return (JBScrollPane)ggp;
- }
- }
- }
- return null;
- }
-
- @Override
public int getRowHeight() {
if (myRowHeightIsComputing) {
return super.getRowHeight();
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
index 1cb59a862179..532c95a52a17 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
@@ -957,6 +957,9 @@ public class JBTabsImpl extends JComponent
@NotNull
private ActionCallback removeDeferred() {
+ if (myDeferredToRemove.isEmpty()) {
+ return ActionCallback.DONE;
+ }
final ActionCallback callback = new ActionCallback();
final long executionRequest = ++myRemoveDeferredRequest;
diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
index 0f62f53dab8c..169b5d57479b 100644
--- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
+++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
@@ -753,6 +753,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
UIUtil.setLineStyleAngled(this);
}
+ @NotNull
public <T> T[] getSelectedNodes(Class<T> nodeType, @Nullable NodeFilter<T> filter) {
TreePath[] paths = getSelectionPaths();
if (paths == null) return (T[])Array.newInstance(nodeType, 0);
diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java
index f0b14d1b052c..33eade3c0d33 100644
--- a/platform/platform-api/src/com/intellij/util/Alarm.java
+++ b/platform/platform-api/src/com/intellij/util/Alarm.java
@@ -98,7 +98,7 @@ public class Alarm implements Disposable {
"You must provide parent Disposable for ThreadToUse.POOLED_THREAD and ThreadToUse.OWN_THREAD Alarm");
}
- public Alarm(@NotNull ThreadToUse threadToUse, Disposable parentDisposable) {
+ public Alarm(@NotNull ThreadToUse threadToUse, @Nullable Disposable parentDisposable) {
myThreadToUse = threadToUse;
if (threadToUse == ThreadToUse.POOLED_THREAD) {
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index 51bda4ce9e44..064b5ccc48b6 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -34,6 +34,7 @@ public class PlatformUtils {
public static final String RUBY_PREFIX = PlatformUtilsCore.RUBY_PREFIX;
public static final String PHP_PREFIX = PlatformUtilsCore.PHP_PREFIX;
public static final String WEB_PREFIX = PlatformUtilsCore.WEB_PREFIX;
+ public static final String DBE_PREFIX = PlatformUtilsCore.DBE_PREFIX;
private PlatformUtils() { }
@@ -93,11 +94,17 @@ public class PlatformUtils {
return PlatformUtilsCore.isWebStorm();
}
+ public static boolean isDatabaseIDE() {
+ return PlatformUtilsCore.isDatabaseIDE();
+ }
+
+ public static boolean isCommunityEdition() {
+ return isIdeaCommunity() || isPyCharmCommunity();
+ }
+
/** @deprecated not a common API; use DevKit's PsiUtil.isIdeaProject() when needed (to remove in IDEA 14) */
@SuppressWarnings("UnusedDeclaration")
- public static boolean isIdeaProject(@Nullable Project project) {
- return false;
- }
+ public static boolean isIdeaProject(@Nullable Project project) { return false; }
/** @deprecated use {@link #IDEA_CE_PREFIX} (to remove in IDEA 15) */
@SuppressWarnings("UnusedDeclaration")
diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java
index b6bb52c992ed..ac20c3ece2d4 100644
--- a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java
+++ b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java
@@ -66,9 +66,7 @@ import static org.apache.http.conn.ssl.SSLConnectionSocketFactory.BROWSER_COMPAT
name = "CertificateManager",
storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml")
)
-public class CertificateManager implements ApplicationComponent, PersistentStateComponent<CertificateManager.Config> {
-
- @NonNls public static final String COMPONENT_NAME = "Certificate Manager";
+public class CertificateManager implements PersistentStateComponent<CertificateManager.Config> {
@NonNls private static final String DEFAULT_PATH = FileUtil.join(PathManager.getSystemPath(), "tasks", "cacerts");
@NonNls private static final String DEFAULT_PASSWORD = "changeit";
@@ -86,7 +84,7 @@ public class CertificateManager implements ApplicationComponent, PersistentState
static final long DIALOG_VISIBILITY_TIMEOUT = 5000; // ms
public static CertificateManager getInstance() {
- return (CertificateManager)ApplicationManager.getApplication().getComponent(COMPONENT_NAME);
+ return ServiceManager.getService(CertificateManager.class);
}
private final String myCacertsPath;
@@ -108,9 +106,9 @@ public class CertificateManager implements ApplicationComponent, PersistentState
myPassword = DEFAULT_PASSWORD;
myConfig = new Config();
myTrustManager = ConfirmingTrustManager.createForStorage(myCacertsPath, myPassword);
+ initComponent();
}
- @Override
public void initComponent() {
try {
// Don't do this: protocol created this way will ignore SSL tunnels. See IDEA-115708.
@@ -125,17 +123,6 @@ public class CertificateManager implements ApplicationComponent, PersistentState
}
}
- @Override
- public void disposeComponent() {
- // empty
- }
-
- @NotNull
- @Override
- public String getComponentName() {
- return COMPONENT_NAME;
- }
-
/**
* Creates special kind of {@code SSLContext}, which X509TrustManager first checks certificate presence in
* in default system-wide trust store (usually located at {@code ${JAVA_HOME}/lib/security/cacerts} or specified by
diff --git a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
index aa48a37be5ee..c2d3d829440d 100644
--- a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
+++ b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
@@ -84,6 +84,7 @@ public class FormBuilder {
final int index = UIUtil.getDisplayMnemonicIndex(labelText);
if (index != -1) {
label.setDisplayedMnemonic(labelText.charAt(index + 1));
+ label.setDisplayedMnemonicIndex(index);
}
label.setLabelFor(component);
diff --git a/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java b/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java
index 11d9298f59e0..db8244255db7 100644
--- a/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java
+++ b/platform/platform-api/src/com/intellij/util/ui/NSScrollerHelper.java
@@ -74,14 +74,16 @@ class NSScrollerHelper {
Foundation.NSAutoreleasePool pool = new Foundation.NSAutoreleasePool();
ID delegateClass = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSObject"), "NSScrollerChangesObserver");
- if (!Foundation.addMethod(delegateClass, Foundation.createSelector("handleScrollerStyleChanged:"), APPEARANCE_CALLBACK, "v@")) {
- throw new RuntimeException("Cannot add observer method");
- }
- if (!Foundation.addMethod(delegateClass, Foundation.createSelector("handleBehaviorChanged:"), BEHAVIOR_CALLBACK, "v@")) {
- throw new RuntimeException("Cannot add observer method");
- }
+ if (!ID.NIL.equals(delegateClass)) {
+ if (!Foundation.addMethod(delegateClass, Foundation.createSelector("handleScrollerStyleChanged:"), APPEARANCE_CALLBACK, "v@")) {
+ throw new RuntimeException("Cannot add observer method");
+ }
+ if (!Foundation.addMethod(delegateClass, Foundation.createSelector("handleBehaviorChanged:"), BEHAVIOR_CALLBACK, "v@")) {
+ throw new RuntimeException("Cannot add observer method");
+ }
- Foundation.registerObjcClassPair(delegateClass);
+ Foundation.registerObjcClassPair(delegateClass);
+ }
ID delegate = invoke("NSScrollerChangesObserver", "new");
try {
diff --git a/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java b/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java
index 14c4f928ef96..56d3dad090c5 100644
--- a/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java
+++ b/platform/platform-api/src/com/intellij/util/ui/OptionsDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.util.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -48,6 +49,7 @@ public abstract class OptionsDialog extends DialogWrapper {
return OptionsDialog.this.shouldSaveOptionsOnCancel();
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return OptionsDialog.this.getDoNotShowMessage();
diff --git a/platform/platform-api/src/com/intellij/util/ui/StatusText.java b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
index 84f1e75eda5b..60f8c5c6cbc1 100644
--- a/platform/platform-api/src/com/intellij/util/ui/StatusText.java
+++ b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
@@ -26,7 +26,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
-import java.util.ArrayList;
+import java.util.*;
+import java.util.List;
public abstract class StatusText {
public static final SimpleTextAttributes DEFAULT_ATTRIBUTES = SimpleTextAttributes.GRAYED_ATTRIBUTES;
@@ -42,7 +43,8 @@ public abstract class StatusText {
private String myText = "";
protected final SimpleColoredComponent myComponent = new SimpleColoredComponent();
- private final ArrayList<ActionListener> myClickListeners = new ArrayList<ActionListener>();
+ private final List<ActionListener> myClickListeners = new ArrayList<ActionListener>();
+ private boolean myHasActiveClickListeners; // calculated field for performance optimization
protected StatusText(JComponent owner) {
this();
@@ -65,14 +67,21 @@ public abstract class StatusText {
};
myMouseMotionListener = new MouseAdapter() {
+
+ private Cursor myOriginalCursor;
+
@Override
public void mouseMoved(final MouseEvent e) {
if (isStatusVisible()) {
if (findActionListenerAt(e.getPoint()) != null) {
- myMouseTarget.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ if (myOriginalCursor == null) {
+ myOriginalCursor = myMouseTarget.getCursor();
+ myMouseTarget.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ }
}
- else {
- myMouseTarget.setCursor(Cursor.getDefaultCursor());
+ else if (myOriginalCursor != null) {
+ myMouseTarget.setCursor(myOriginalCursor);
+ myOriginalCursor = null;
}
}
}
@@ -107,7 +116,7 @@ public abstract class StatusText {
@Nullable
private ActionListener findActionListenerAt(Point point) {
- if (!isStatusVisible()) return null;
+ if (!myHasActiveClickListeners || !isStatusVisible()) return null;
point = SwingUtilities.convertPoint(myMouseTarget, point, myOwner);
@@ -147,6 +156,7 @@ public abstract class StatusText {
myText = "";
myComponent.clear();
myClickListeners.clear();
+ myHasActiveClickListeners = false;
if (myOwner != null) myOwner.repaint();
return this;
}
@@ -168,6 +178,9 @@ public abstract class StatusText {
myText += text;
myComponent.append(text, attrs);
myClickListeners.add(listener);
+ if (listener != null) {
+ myHasActiveClickListeners = true;
+ }
if (myOwner != null) myOwner.repaint();
return this;
}
diff --git a/platform/platform-impl/src/com/intellij/execution/process/ConsoleHistoryModel.java b/platform/platform-impl/src/com/intellij/execution/process/ConsoleHistoryModel.java
index a998502659bc..0e597c5089ce 100644
--- a/platform/platform-impl/src/com/intellij/execution/process/ConsoleHistoryModel.java
+++ b/platform/platform-impl/src/com/intellij/execution/process/ConsoleHistoryModel.java
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.execution.process;
import com.intellij.ide.ui.UISettings;
-import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.Nullable;
@@ -12,19 +27,16 @@ import java.util.List;
/**
* @author Gregory.Shrago
*/
-public class ConsoleHistoryModel implements ModificationTracker {
-
+public class ConsoleHistoryModel extends SimpleModificationTracker {
private int myHistoryCursor = -1;
private final LinkedList<String> myHistory = new LinkedList<String>();
- private volatile long myModificationTracker;
-
public void addToHistory(String statement) {
if (StringUtil.isEmptyOrSpaces(statement)) return;
int maxHistorySize = getMaxHistorySize();
synchronized (myHistory) {
- myModificationTracker++;
+ incModificationCount();
myHistoryCursor = -1;
myHistory.remove(statement);
@@ -42,7 +54,7 @@ public class ConsoleHistoryModel implements ModificationTracker {
public void removeFromHistory(final String statement) {
synchronized (myHistory) {
- myModificationTracker++;
+ incModificationCount();
myHistoryCursor = -1;
myHistory.remove(statement);
@@ -98,9 +110,4 @@ public class ConsoleHistoryModel implements ModificationTracker {
return myHistoryCursor;
}
}
-
- @Override
- public long getModificationCount() {
- return myModificationTracker;
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java b/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java
index 2d5d8f5e0480..fa975283d921 100644
--- a/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java
+++ b/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.LogUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditor;
@@ -24,13 +25,21 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
+import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.List;
+import java.util.Set;
+
public class FileChangedNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> {
private static final Logger LOG = Logger.getInstance(FileChangedNotificationProvider.class);
private static final Key<EditorNotificationPanel> KEY = Key.create("file.changed.notification.panel");
@@ -51,8 +60,26 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide
}
}
}, project);
+
+ MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(myProject);
+ connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
+ @Override
+ public void after(@NotNull List<? extends VFileEvent> events) {
+ if (!myProject.isDisposed() && !GeneralSettings.getInstance().isSyncOnFrameActivation()) {
+ Set<VirtualFile> openFiles = ContainerUtil.newHashSet(FileEditorManager.getInstance(myProject).getSelectedFiles());
+ EditorNotifications notifications = EditorNotifications.getInstance(myProject);
+ for (VFileEvent event : events) {
+ VirtualFile file = event.getFile();
+ if (openFiles.contains(file)) {
+ notifications.updateNotifications(file);
+ }
+ }
+ }
+ }
+ });
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
diff --git a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java
index e77e289f1740..1a6bffbcd297 100644
--- a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java
+++ b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,7 +17,6 @@ package com.intellij.ide;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Separator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
@@ -169,9 +168,7 @@ public abstract class RecentProjectsManagerBase implements ProjectManagerListene
}
/**
- * @param addClearListItem - used for detecting whether the "Clear List" action should be added
- * to the end of the returned list of actions
- * @return
+ * @param addClearListItem whether the "Clear List" action should be added to the end of the list.
*/
public AnAction[] getRecentProjectsActions(boolean addClearListItem) {
final Set<String> paths;
@@ -188,10 +185,10 @@ public abstract class RecentProjectsManagerBase implements ProjectManagerListene
paths.remove(null);
paths.removeAll(openedPaths);
- ArrayList<AnAction> actions = new ArrayList<AnAction>();
+ List<AnAction> actions = new ArrayList<AnAction>();
Set<String> duplicates = getDuplicateProjectNames(openedPaths, paths);
for (final String path : paths) {
- final String projectName = getProjectName(path);
+ String projectName = getProjectName(path);
String displayName;
synchronized (myStateLock) {
displayName = myState.names.get(path);
@@ -212,19 +209,13 @@ public abstract class RecentProjectsManagerBase implements ProjectManagerListene
return AnAction.EMPTY_ARRAY;
}
- ArrayList<AnAction> list = new ArrayList<AnAction>();
- for (AnAction action : actions) {
- list.add(action);
- }
if (addClearListItem) {
AnAction clearListAction = new DumbAwareAction(IdeBundle.message("action.clear.list")) {
+ @Override
public void actionPerformed(AnActionEvent e) {
- final int rc = Messages.showOkCancelDialog(e.getData(CommonDataKeys.PROJECT),
- "Would you like to clear the list of recent projects?",
- "Clear Recent Projects List",
- Messages.getQuestionIcon());
-
- if (rc == Messages.OK) {
+ String message = IdeBundle.message("action.clear.list.message");
+ String title = IdeBundle.message("action.clear.list.title");
+ if (Messages.showOkCancelDialog(e.getProject(), message, title, Messages.getQuestionIcon()) == Messages.OK) {
synchronized (myStateLock) {
myState.recentPaths.clear();
}
@@ -233,11 +224,11 @@ public abstract class RecentProjectsManagerBase implements ProjectManagerListene
}
};
- list.add(Separator.getInstance());
- list.add(clearListAction);
+ actions.add(Separator.getInstance());
+ actions.add(clearListAction);
}
- return list.toArray(new AnAction[list.size()]);
+ return actions.toArray(new AnAction[actions.size()]);
}
private void markPathRecent(String path) {
diff --git a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
index 569fe1220d0e..dd969f32ac04 100644
--- a/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
+++ b/platform/platform-impl/src/com/intellij/ide/SwingCleanuper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -119,9 +119,8 @@ public final class SwingCleanuper implements ApplicationComponent{
// Memory leak on javax.swing.TransferHandler$SwingDragGestureRecognizer.component
try{
- final Field recognizerField = TransferHandler.class.getDeclaredField("recognizer");
- recognizerField.setAccessible(true);
- final Object recognizerObject = recognizerField.get(null);
+ final Object recognizerObject = ReflectionUtil.getField(TransferHandler.class, null, null, "recognizer");
+
if(recognizerObject!=null){ // that is memory leak
final Method setComponentMethod = DragGestureRecognizer.class.getDeclaredMethod("setComponent", Component.class);
setComponentMethod.invoke(recognizerObject,new Object[]{null});
@@ -132,9 +131,8 @@ public final class SwingCleanuper implements ApplicationComponent{
}
try {
fixJTextComponentMemoryLeak();
- } catch(NoSuchFieldException e) {
- // JDK 1.5
- } catch(Exception e) {
+ }
+ catch(Exception e) {
// Ignore
}
@@ -256,12 +254,7 @@ public final class SwingCleanuper implements ApplicationComponent{
}
}
private static void resetStaticField(@NotNull Class aClass, @NotNull @NonNls String name) {
- try {
- Field field = aClass.getDeclaredField(name);
- ReflectionUtil.resetField(null, field);
- }
- catch (Exception ignored) {
- }
+ ReflectionUtil.resetField(aClass, null, name);
}
public final void disposeComponent(){}
@@ -273,13 +266,10 @@ public final class SwingCleanuper implements ApplicationComponent{
public final void initComponent() { }
- private static void fixJTextComponentMemoryLeak() throws NoSuchFieldException, IllegalAccessException {
- //noinspection HardCodedStringLiteral
- final Field focusedComponentField = JTextComponent.class.getDeclaredField("focusedComponent");
- focusedComponentField.setAccessible(true);
- final JTextComponent component = (JTextComponent)focusedComponentField.get(null);
+ private static void fixJTextComponentMemoryLeak() {
+ final JTextComponent component = ReflectionUtil.getField(JTextComponent.class, null, JTextComponent.class, "focusedComponent");
if (component != null && !component.isDisplayable()){
- focusedComponentField.set(null, null);
+ ReflectionUtil.resetField(JTextComponent.class, JTextComponent.class, "focusedComponent");
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
index 29ad33b8cf0b..8c41a8e30ab6 100644
--- a/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
+++ b/platform/platform-impl/src/com/intellij/ide/SystemHealthMonitor.java
@@ -62,7 +62,6 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
public void initComponent() {
checkJvm();
startDiskSpaceMonitoring();
- checkPowerSaveMode();
}
private void checkJvm() {
@@ -210,25 +209,4 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
}, 1, TimeUnit.SECONDS);
}
- private void checkPowerSaveMode() {
- if (PowerSaveMode.isEnabled()) {
- final String ignoreKey = "ignore.power.save.mode";
- String message = "Power save mode is on. Code insight and other background tasks are disabled." +
- "<br/><a href=\"ignore\">Do not show again</a>" +
- "<br/><a href=\"turnOff\">Disable Power Save Mode</a>";
-
- showNotification(ignoreKey, message, new HyperlinkAdapter() {
- @Override
- protected void hyperlinkActivated(HyperlinkEvent e) {
- final String description = e.getDescription();
- if ("ignore".equals(description)) {
- myProperties.setValue(ignoreKey, "true");
- }
- else if ("turnOff".equals(description)) {
- PowerSaveMode.setEnabled(false);
- }
- }
- });
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java
index 388a446d991c..0bc0a50e1df8 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java
@@ -20,70 +20,38 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.testFramework.LightVirtualFile;
-import org.jetbrains.annotations.NotNull;
import java.awt.datatransfer.StringSelection;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
public class CopyPathsAction extends AnAction implements DumbAware {
-
public CopyPathsAction() {
setEnabledInModalContext(true);
}
+ @Override
public void actionPerformed(AnActionEvent e) {
- final Collection<VirtualFile> files = getFiles(e);
- if (files.isEmpty()) {
- return;
+ VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext());
+ if (files != null && files.length > 0) {
+ CopyPasteManager.getInstance().setContents(new StringSelection(getPaths(files)));
}
- CopyPasteManager.getInstance().setContents(new StringSelection(getPaths(files)));
}
- private static String getPaths(Collection<VirtualFile> files) {
- final StringBuilder buf = new StringBuilder(files.size() * 64);
- boolean first = true;
+ private static String getPaths(VirtualFile[] files) {
+ StringBuilder buf = new StringBuilder(files.length * 64);
for (VirtualFile file : files) {
- if (first) {
- first = false;
- }
- else {
- buf.append("\n");
- }
+ if (buf.length() > 0) buf.append('\n');
buf.append(file.getPresentableUrl());
}
return buf.toString();
}
+ @Override
public void update(AnActionEvent event) {
- final Collection<VirtualFile> files = getFiles(event);
- final Presentation presentation = event.getPresentation();
- final boolean enabled = !files.isEmpty();
- presentation.setEnabled(enabled);
- if (ActionPlaces.isPopupPlace(event.getPlace())) {
- presentation.setVisible(enabled);
- }
- else {
- presentation.setVisible(true);
- }
- presentation.setText((files.size() == 1)
- ? IdeBundle.message("action.copy.path")
- : IdeBundle.message("action.copy.paths"));
- }
-
- @NotNull
- private static Collection<VirtualFile> getFiles(AnActionEvent e) {
- final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext());
- if (files == null || files.length == 0) return Collections.emptyList();
- final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(files.length);
- for (VirtualFile file : files) {
- if (!(file instanceof LightVirtualFile)) {
- result.add(file);
- }
- }
- return result;
+ VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(event.getDataContext());
+ int num = files != null ? files.length : 0;
+ Presentation presentation = event.getPresentation();
+ presentation.setEnabled(num > 0);
+ presentation.setVisible(num > 0 || !ActionPlaces.isPopupPlace(event.getPlace()));
+ presentation.setText(IdeBundle.message(num == 1 ? "action.copy.path" : "action.copy.paths"));
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index f1032fec66ec..9bdc5948cffe 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
+import java.util.Locale;
import static com.intellij.util.containers.ContainerUtil.newHashMap;
import static java.util.Arrays.asList;
@@ -129,9 +130,9 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
private static File prepare() throws IOException {
final String homePath = PathManager.getHomePath();
- assert homePath != null && new File(homePath).isDirectory() : "Invalid home path: '" + homePath + "'";
+ assert new File(homePath).isDirectory() : "Invalid home path: '" + homePath + "'";
final String binPath = homePath + "/bin";
- assert new File(binPath).isDirectory() : "Invalid bin/ path: '" + binPath + "'";
+ assert new File(binPath).isDirectory() : "Invalid bin path: '" + binPath + "'";
String name = ApplicationNamesInfo.getInstance().getFullProductName();
if (PlatformUtils.isIdeaCommunity()) name += " Community Edition";
@@ -160,18 +161,18 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
}
@Nullable
- private static String findScript(final String binPath) {
- final String productName = ApplicationNamesInfo.getInstance().getProductName();
+ private static String findScript(String binPath) {
+ String productName = ApplicationNamesInfo.getInstance().getProductName();
String execPath = binPath + '/' + productName + ".sh";
if (new File(execPath).canExecute()) return execPath;
- execPath = binPath + '/' + productName.toLowerCase() + ".sh";
+ execPath = binPath + '/' + productName.toLowerCase(Locale.US) + ".sh";
if (new File(execPath).canExecute()) return execPath;
- final String scriptName = ApplicationNamesInfo.getInstance().getScriptName();
- String scriptPath = binPath + '/' + scriptName + ".sh";
- if (new File(scriptPath).canExecute()) return scriptPath;
+ String scriptName = ApplicationNamesInfo.getInstance().getScriptName();
+ execPath = binPath + '/' + scriptName + ".sh";
+ if (new File(execPath).canExecute()) return execPath;
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java b/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java
index 3d1a8c14574d..0a2ac7fe1c52 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/RecentProjectsGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -28,15 +28,8 @@ import org.jetbrains.annotations.Nullable;
public class RecentProjectsGroup extends ActionGroup implements DumbAware {
public RecentProjectsGroup() {
- super();
-
- final Presentation templatePresentation = getTemplatePresentation();
- // Let's make tile more macish
- if (SystemInfo.isMac) {
- templatePresentation.setText(ActionsBundle.message("group.reopen.mac.text"));
- } else {
- templatePresentation.setText(ActionsBundle.message("group.reopen.win.text"));
- }
+ Presentation presentation = getTemplatePresentation();
+ presentation.setText(ActionsBundle.message(SystemInfo.isMac ? "group.reopen.mac.text": "group.reopen.win.text"));
}
@NotNull
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/RefCardAction.java b/platform/platform-impl/src/com/intellij/ide/actions/RefCardAction.java
index df50bb85e8fa..a6f1aded0727 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/RefCardAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/RefCardAction.java
@@ -24,7 +24,8 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.SystemInfo;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -32,17 +33,15 @@ import java.io.File;
* @author Vladimir Kondratyev
*/
public class RefCardAction extends AnAction implements DumbAware {
- @NonNls private static final String KEYMAP_URL = PathManager.getHomePath() + "/help/" + (SystemInfo.isMac ? "ReferenceCardForMac.pdf" : "ReferenceCard.pdf");
+ private static final String REF_CARD_PATH = PathManager.getHomePath() + "/help/" + (SystemInfo.isMac ? "ReferenceCardForMac.pdf" : "ReferenceCard.pdf");
public void actionPerformed(AnActionEvent e) {
- final String url = KEYMAP_URL;
- File file = new File(url);
+ File file = getRefCardFile();
if (file.isFile()) {
BrowserUtil.browse(file);
}
else {
- final ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
- String webUrl = SystemInfo.isMac ? appInfo.getMacKeymapUrl() : appInfo.getWinKeymapUrl();
+ String webUrl = getKeymapUrl();
if (webUrl != null) {
BrowserUtil.browse(webUrl);
}
@@ -50,8 +49,22 @@ public class RefCardAction extends AnAction implements DumbAware {
}
public void update(AnActionEvent e) {
- super.update(e);
+ e.getPresentation().setEnabledAndVisible(isRefCardAvailable());
boolean atWelcome = ActionPlaces.WELCOME_SCREEN.equals(e.getPlace());
e.getPresentation().setIcon(atWelcome ? AllIcons.General.DefaultKeymap : null);
}
+
+ private static boolean isRefCardAvailable() {
+ return getRefCardFile().exists() || getKeymapUrl() != null;
+ }
+
+ private static String getKeymapUrl() {
+ final ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
+ return SystemInfo.isMac ? appInfo.getMacKeymapUrl() : appInfo.getWinKeymapUrl();
+ }
+
+ @NotNull
+ private static File getRefCardFile() {
+ return new File(FileUtil.toSystemDependentName(REF_CARD_PATH));
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java
index 59fdfc24ab30..cd544e70a69b 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java
@@ -389,6 +389,7 @@ public class ShowFilePathAction extends AnAction {
return true;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.ask");
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
index 204abba30da7..d450cf454291 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
@@ -90,7 +90,7 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
});
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.add(radioButton, myColumnMode ? BorderLayout.WEST : BorderLayout.NORTH);
- final JLabel label = new JLabel(myColumnMode ? IconUtil.scale(IconUtil.cropIcon(icon, icon.getIconWidth() * 2 / 3, icon.getIconHeight() * 2 / 3), .75) : icon);
+ final JLabel label = new JLabel(myColumnMode ? IconUtil.scale(IconUtil.cropIcon(icon, icon.getIconWidth() * 2 / 3, icon.getIconHeight() * 2 / 3), .5) : icon);
label.setVerticalAlignment(SwingConstants.TOP);
label.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(label, BorderLayout.CENTER);
@@ -149,7 +149,9 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
}
Window window = SwingUtilities.getWindowAncestor(component);
if (window != null) {
- window.setBackground(new Color(UIUtil.getPanelBackground().getRGB()));
+ if (SystemInfo.isMac) {
+ window.setBackground(new Color(UIUtil.getPanelBackground().getRGB()));
+ }
SwingUtilities.updateComponentTreeUI(window);
}
if (ApplicationManager.getApplication() != null) {
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java
index 8a388650b15a..de154f249c9e 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/PluginGroups.java
@@ -177,8 +177,7 @@ class PluginGroups {
"org.jetbrains.android",
"com.intellij.android-designer")));
myTree.put("Database Tools", Pair.create("/plugins/DatabaseTools.png", Arrays.asList(
- "com.intellij.sql",
- "com.intellij.persistence.database"
+ "com.intellij.database"
)));
myTree.put("Other Tools", Pair.create("/plugins/OtherTools.png", Arrays.asList(
"ByteCodeViewer",
diff --git a/platform/platform-impl/src/com/intellij/ide/impl/ProjectNewWindowDoNotAskOption.java b/platform/platform-impl/src/com/intellij/ide/impl/ProjectNewWindowDoNotAskOption.java
index 74cbd80a7e70..ee0fc4f914c2 100644
--- a/platform/platform-impl/src/com/intellij/ide/impl/ProjectNewWindowDoNotAskOption.java
+++ b/platform/platform-impl/src/com/intellij/ide/impl/ProjectNewWindowDoNotAskOption.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,6 +18,7 @@ package com.intellij.ide.impl;
import com.intellij.CommonBundle;
import com.intellij.ide.GeneralSettings;
import com.intellij.openapi.ui.DialogWrapper;
+import org.jetbrains.annotations.NotNull;
public class ProjectNewWindowDoNotAskOption implements DialogWrapper.DoNotAskOption {
public boolean isToBeShown() {
@@ -38,6 +39,7 @@ public class ProjectNewWindowDoNotAskOption implements DialogWrapper.DoNotAskOpt
return false;
}
+ @NotNull
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.ask");
}
diff --git a/platform/platform-impl/src/com/intellij/ide/impl/TypeSafeDataProviderAdapter.java b/platform/platform-impl/src/com/intellij/ide/impl/TypeSafeDataProviderAdapter.java
index 548d2aa42eea..10772bb932c4 100644
--- a/platform/platform-impl/src/com/intellij/ide/impl/TypeSafeDataProviderAdapter.java
+++ b/platform/platform-impl/src/com/intellij/ide/impl/TypeSafeDataProviderAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TypeSafeDataProviderAdapter implements DataProvider, DataSink {
@@ -34,10 +35,11 @@ public class TypeSafeDataProviderAdapter implements DataProvider, DataSink {
private DataKey myLastKey = null;
private Object myValue = null;
- public TypeSafeDataProviderAdapter(final TypeSafeDataProvider provider) {
+ public TypeSafeDataProviderAdapter(@NotNull TypeSafeDataProvider provider) {
myProvider = provider;
}
+ @Override
@Nullable
public synchronized Object getData(@NonNls String dataId) {
myValue = null;
@@ -46,6 +48,7 @@ public class TypeSafeDataProviderAdapter implements DataProvider, DataSink {
return myValue;
}
+ @Override
public synchronized <T> void put(DataKey<T> key, T data) {
if (key == myLastKey) {
myValue = data;
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java
index 260e974fd8ad..01fef01cecb1 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/EncryptionUtil.java
@@ -19,6 +19,7 @@ import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -120,8 +121,8 @@ public class EncryptionUtil {
c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password, SECRET_KEY_ALGORITHM), CBC_SALT_KEY);
return c.doFinal(rawKey);
}
- catch (Exception e) {
- throw new IllegalStateException(ENCRYPT_KEY_ALGORITHM + " is not available", e);
+ catch (GeneralSecurityException e) {
+ throw new IllegalStateException(e.getMessage(), e);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
index c8e0e02acce4..95fba48afabe 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,9 +22,9 @@ import com.intellij.ide.passwordSafe.impl.providers.BasePasswordSafeProvider;
import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper;
import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil;
import com.intellij.ide.passwordSafe.impl.providers.masterKey.windows.WindowsCryptUtils;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
@@ -179,7 +179,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
@Override
protected byte[] key(@Nullable final Project project, @NotNull final Class requestor) throws PasswordSafeException {
- ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication();
+ Application application = ApplicationManager.getApplication();
if (!isTestMode() && application.isHeadlessEnvironment()) {
throw new MasterPasswordUnavailableException("The provider is not available in headless environment");
}
@@ -196,9 +196,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
if (result.isNull()) {
final Ref<PasswordSafeException> ex = new Ref<PasswordSafeException>();
- if (application.holdsReadLock()) {
- throw new IllegalStateException("Access from read action is not allowed, because it might lead to a deadlock.");
- }
application.invokeAndWait(new Runnable() {
public void run() {
result.set(key.get().get());
@@ -214,8 +211,8 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
else {
MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
- result.set(key.get().get());
}
+ result.set(key.get().get());
}
catch (PasswordSafeException e) {
ex.set(e);
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java
deleted file mode 100644
index 25769a38fa7d..000000000000
--- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionUninstallPlugin.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ide.plugins;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.ide.IdeBundle;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.JDOMExternalizableStringList;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * @author lloix
- */
-public class ActionUninstallPlugin extends AnAction implements DumbAware {
- final private static String promptTitle = IdeBundle.message("title.plugin.uninstall");
-
- private final PluginTable pluginTable;
- private final PluginManagerMain host;
-
- public ActionUninstallPlugin(PluginManagerMain mgr, PluginTable table) {
- super(IdeBundle.message("action.uninstall.plugin"), IdeBundle.message("action.uninstall.plugin"), AllIcons.Actions.Uninstall);
-
- pluginTable = table;
- host = mgr;
- }
-
- public void update(AnActionEvent e) {
- Presentation presentation = e.getPresentation();
- if (!pluginTable.isShowing()) {
- presentation.setEnabled(false);
- return;
- }
- IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects();
- boolean enabled = (selection != null);
-
- if (enabled) {
- for (IdeaPluginDescriptor descriptor : selection) {
- if (descriptor instanceof IdeaPluginDescriptorImpl) {
- final IdeaPluginDescriptorImpl ideaPluginDescriptor = (IdeaPluginDescriptorImpl)descriptor;
- if (ideaPluginDescriptor.isDeleted() || ideaPluginDescriptor.isBundled()) {
- enabled = false;
- break;
- }
- }
- if (descriptor instanceof PluginNode) {
- enabled = false;
- break;
- }
- }
- }
- presentation.setEnabled(enabled);
- }
-
- public void actionPerformed(AnActionEvent e) {
- uninstall(host, pluginTable);
- }
-
- public static void uninstall(PluginManagerMain host, PluginTable pluginTable) {
- String message;
- IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects();
-
- if (selection.length == 1) {
- message = IdeBundle.message("prompt.uninstall.plugin", selection[0].getName());
- }
- else {
- message = IdeBundle.message("prompt.uninstall.several.plugins", selection.length);
- }
- if (Messages.showYesNoDialog(host.getMainPanel(), message, promptTitle, Messages.getQuestionIcon()) != Messages.YES) return;
-
- for (IdeaPluginDescriptor descriptor : selection) {
- IdeaPluginDescriptorImpl pluginDescriptor = (IdeaPluginDescriptorImpl)descriptor;
-
- boolean actualDelete = true;
-
- // Get the list of plugins which depend on this one. If this list is
- // not empty - issue warning instead of simple prompt.
- ArrayList<IdeaPluginDescriptorImpl> dependant = host.getDependentList(pluginDescriptor);
- if (dependant.size() > 0) {
- message = IdeBundle.message("several.plugins.depend.on.0.continue.to.remove", pluginDescriptor.getName());
- actualDelete = (Messages.showYesNoDialog(host.getMainPanel(), message, promptTitle, Messages.getQuestionIcon()) == Messages.YES);
- }
-
- if (actualDelete) uninstallPlugin(pluginDescriptor, host, pluginTable);
- }
- }
-
- private static void uninstallPlugin(IdeaPluginDescriptorImpl descriptor, PluginManagerMain host, PluginTable pluginTable) {
- PluginId pluginId = descriptor.getPluginId();
- descriptor.setDeleted(true);
-
- try {
- PluginInstaller.prepareToUninstall(pluginId);
- final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().getInstalledPlugins();
- final String pluginIdString = pluginId.getIdString();
- while (installedPlugins.contains(pluginIdString)) {
- installedPlugins.remove(pluginIdString);
- }
- host.setRequireShutdown(descriptor.isEnabled());
- pluginTable.updateUI();
- }
- catch (IOException e1) {
- PluginManagerMain.LOG.error(e1);
- }
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
index 2d03d1621af9..62609d9ba5fc 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
@@ -21,11 +21,11 @@ import com.intellij.ide.plugins.sorters.SortByRatingAction;
import com.intellij.ide.plugins.sorters.SortByUpdatedAction;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
+import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
-import com.intellij.openapi.util.Comparing;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableUtil;
@@ -187,9 +187,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
@Override
protected boolean acceptHost(String host) {
- final String repository = ((AvailablePluginsTableModel)pluginsModel).getRepository();
- if (AvailablePluginsTableModel.ALL.equals(repository)) return true;
- return Comparing.equal(host, repository);
+ return ((AvailablePluginsTableModel)pluginsModel).isHostAccepted(host);
}
@Override
@@ -251,7 +249,8 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
@Override
public void update(AnActionEvent e) {
super.update(e);
- e.getPresentation().setVisible(!UpdateSettings.getInstance().myPluginHosts.isEmpty());
+ boolean empty = UpdateSettings.getInstance().myPluginHosts.isEmpty();
+ e.getPresentation().setVisible(!empty || ApplicationInfoEx.getInstanceEx().getBuiltinPluginsUrl() != null);
String repository = ((AvailablePluginsTableModel)pluginsModel).getRepository();
if (repository.length() > LENGTH) {
repository = repository.substring(0, LENGTH) + "...";
@@ -265,6 +264,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
final DefaultActionGroup gr = new DefaultActionGroup();
gr.add(createFilterByRepositoryAction(AvailablePluginsTableModel.ALL));
gr.add(createFilterByRepositoryAction(AvailablePluginsTableModel.JETBRAINS_REPO));
+ if (ApplicationInfoEx.getInstanceEx().getBuiltinPluginsUrl() != null) {
+ gr.add(createFilterByRepositoryAction(AvailablePluginsTableModel.BUILTIN_REPO));
+ }
for (final String host : UpdateSettings.getInstance().myPluginHosts) {
gr.add(createFilterByRepositoryAction(host));
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java
index 5ab37c12cda8..ee538453c2e1 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsTableModel.java
@@ -22,6 +22,7 @@
*/
package com.intellij.ide.plugins;
+import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ui.ColumnInfo;
@@ -45,7 +46,8 @@ public class AvailablePluginsTableModel extends PluginTableModel {
protected static final String STATUS = "Status";
- public static final String JETBRAINS_REPO = "JetBrains";
+ public static final String JETBRAINS_REPO = "JetBrains Plugin Repository";
+ public static final String BUILTIN_REPO = "Built-in Plugin Repository";
private String myRepository = ALL;
private String myVendor = null;
@@ -95,10 +97,19 @@ public class AvailablePluginsTableModel extends PluginTableModel {
}
}
- final String repositoryName = ((PluginNode)descriptor).getRepositoryName();
+ return isHostAccepted(((PluginNode)descriptor).getRepositoryName());
+ }
+
+ public boolean isHostAccepted(String repositoryName) {
if (repositoryName != null) {
- if (!ALL.equals(myRepository) && !repositoryName.equals(myRepository)) return false;
- } else {
+ if (repositoryName.equals(ApplicationInfoEx.getInstanceEx().getBuiltinPluginsUrl()) && myRepository.equals(BUILTIN_REPO)) {
+ return true;
+ }
+ else if (!ALL.equals(myRepository) && !repositoryName.equals(myRepository)) {
+ return false;
+ }
+ }
+ else {
return ALL.equals(myRepository) || JETBRAINS_REPO.equals(myRepository);
}
return true;
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java
index 44d9606bd418..dc448b52f460 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.plugins;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -73,9 +74,9 @@ public class InstalledPluginsTableModel extends PluginTableModel {
final MyPluginManagerColumnInfo infoColumn = new MyPluginManagerColumnInfo();
final EnabledPluginInfo enabledColumn = new EnabledPluginInfo();
final Spacer spacer = new Spacer();
- super.columns = SystemInfo.isMac ? new ColumnInfo[]{infoColumn, enabledColumn, spacer}
+ columns = SystemInfo.isMac ? new ColumnInfo[]{infoColumn, enabledColumn, spacer}
:new ColumnInfo[]{infoColumn, enabledColumn};
- view = new ArrayList<IdeaPluginDescriptor>(Arrays.asList(PluginManager.getPlugins()));
+ view = new ArrayList<IdeaPluginDescriptor>(Arrays.asList(PluginManagerCore.getPlugins()));
view.addAll(myInstalled);
reset(view);
@@ -91,6 +92,15 @@ public class InstalledPluginsTableModel extends PluginTableModel {
return ids != null && !ids.isEmpty();
}
+ @Nullable
+ public Set<PluginId> getRequiredPlugins(PluginId pluginId) {
+ return myDependentToRequiredListMap.get(pluginId);
+ }
+
+ public boolean isLoaded(PluginId pluginId) {
+ return myEnabled.get(pluginId) != null;
+ }
+
public boolean appendOrUpdateDescriptor(IdeaPluginDescriptor descriptor) {
final PluginId descrId = descriptor.getPluginId();
final IdeaPluginDescriptor existing = PluginManager.getPlugin(descrId);
@@ -122,11 +132,12 @@ public class InstalledPluginsTableModel extends PluginTableModel {
return 1;
}
+ @Override
public int getNameColumn() {
return 0;
}
- private void reset(final List<IdeaPluginDescriptor> list) {
+ private void reset(@NotNull List<IdeaPluginDescriptor> list) {
for (IdeaPluginDescriptor ideaPluginDescriptor : list) {
setEnabled(ideaPluginDescriptor);
}
@@ -134,13 +145,16 @@ public class InstalledPluginsTableModel extends PluginTableModel {
updatePluginDependencies();
final Runnable runnable = new Runnable() {
+ @Override
public void run() {
- ProgressManager.getInstance().run(new Task.Backgroundable(null, "Load custom plugin repositories data...") {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- updateRepositoryPlugins();
- }
- });
+ if (!ApplicationManager.getApplication().isDisposed()) {
+ ProgressManager.getInstance().run(new Task.Backgroundable(null, "Load custom plugin repositories data...") {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ updateRepositoryPlugins();
+ }
+ });
+ }
}
};
SwingUtilities.invokeLater(runnable);
@@ -168,7 +182,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
private void setEnabled(IdeaPluginDescriptor ideaPluginDescriptor,
final boolean enabled) {
- final Collection<String> disabledPlugins = PluginManager.getDisabledPlugins();
+ final Collection<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
final PluginId pluginId = ideaPluginDescriptor.getPluginId();
if (!enabled && !disabledPlugins.contains(pluginId.toString())) {
myEnabled.put(pluginId, null);
@@ -192,37 +206,40 @@ public class InstalledPluginsTableModel extends PluginTableModel {
if (descriptor instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)descriptor).isDeleted()) continue;
final Boolean enabled = myEnabled.get(pluginId);
if (enabled == null || enabled.booleanValue()) {
- PluginManager.checkDependants(descriptor, new Function<PluginId, IdeaPluginDescriptor>() {
- @Nullable
- public IdeaPluginDescriptor fun(final PluginId pluginId) {
- return PluginManager.getPlugin(pluginId);
- }
- }, new Condition<PluginId>() {
- public boolean value(final PluginId dependantPluginId) {
- final Boolean enabled = myEnabled.get(dependantPluginId);
- if ((enabled == null && !updatedPlugins.contains(dependantPluginId)) ||
- (enabled != null && !enabled.booleanValue())) {
- Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
- if (required == null) {
- required = new HashSet<PluginId>();
- myDependentToRequiredListMap.put(pluginId, required);
- }
-
- required.add(dependantPluginId);
- //return false;
- }
-
- return true;
- }
- }
+ PluginManagerCore.checkDependants(descriptor, new Function<PluginId, IdeaPluginDescriptor>() {
+ @Override
+ @Nullable
+ public IdeaPluginDescriptor fun(final PluginId pluginId) {
+ return PluginManager.getPlugin(pluginId);
+ }
+ }, new Condition<PluginId>() {
+ @Override
+ public boolean value(final PluginId dependantPluginId) {
+ final Boolean enabled = myEnabled.get(dependantPluginId);
+ if ((enabled == null && !updatedPlugins.contains(dependantPluginId)) ||
+ (enabled != null && !enabled.booleanValue())) {
+ Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
+ if (required == null) {
+ required = new HashSet<PluginId>();
+ myDependentToRequiredListMap.put(pluginId, required);
+ }
+
+ required.add(dependantPluginId);
+ //return false;
+ }
+
+ return true;
+ }
+ }
);
- if (enabled == null && !myDependentToRequiredListMap.containsKey(pluginId) && !PluginManager.isIncompatible(descriptor)) {
+ if (enabled == null && !myDependentToRequiredListMap.containsKey(pluginId) && !PluginManagerCore.isIncompatible(descriptor)) {
myEnabled.put(pluginId, true);
}
}
}
}
+ @Override
public void updatePluginsList(List<IdeaPluginDescriptor> list) {
// For each downloadable plugin we need to know whether its counterpart
// is already installed, and if yes compare the difference in versions:
@@ -277,7 +294,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
installedPlugins.add(idString);
}
final PluginManagerUISettings updateSettings = PluginManagerUISettings.getInstance();
- if (state > 0 && !PluginManager.isIncompatible(descr) && !updatedPlugins.contains(descr.getPluginId())) {
+ if (state > 0 && !PluginManagerCore.isIncompatible(descr) && !updatedPlugins.contains(descr.getPluginId())) {
NewVersions2Plugins.put(pluginId, 1);
if (!updateSettings.myOutdatedPlugins.contains(idString)) {
updateSettings.myOutdatedPlugins.add(idString);
@@ -312,6 +329,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
private void hideNotApplicablePlugins(Boolean value, final IdeaPluginDescriptor... ideaPluginDescriptors) {
if (!value && ENABLED.equals(myEnabledFilter) || (value && DISABLED.equals(myEnabledFilter))) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
for (IdeaPluginDescriptor ideaPluginDescriptor : ideaPluginDescriptors) {
view.remove(ideaPluginDescriptor);
@@ -375,10 +393,12 @@ public class InstalledPluginsTableModel extends PluginTableModel {
super("");
}
+ @Override
public Object valueOf(IdeaPluginDescriptor ideaPluginDescriptor) {
return null;
}
+ @Override
public boolean isCellEditable(final IdeaPluginDescriptor ideaPluginDescriptor) {
return false;
}
@@ -389,6 +409,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
return new DefaultTableCellRenderer();
}
+ @Override
public Class getColumnClass() {
return Spacer.class;
}
@@ -400,22 +421,27 @@ public class InstalledPluginsTableModel extends PluginTableModel {
super(/*IdeBundle.message("plugin.manager.enable.column.title")*/"");
}
+ @Override
public Boolean valueOf(IdeaPluginDescriptor ideaPluginDescriptor) {
return myEnabled.get(ideaPluginDescriptor.getPluginId());
}
+ @Override
public boolean isCellEditable(final IdeaPluginDescriptor ideaPluginDescriptor) {
return true;
}
+ @Override
public Class getColumnClass() {
return Boolean.class;
}
+ @Override
public TableCellEditor getEditor(final IdeaPluginDescriptor o) {
return new BooleanTableCellEditor();
}
+ @Override
public TableCellRenderer getRenderer(final IdeaPluginDescriptor ideaPluginDescriptor) {
return new BooleanTableCellRenderer() {
@Override
@@ -430,6 +456,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
};
}
+ @Override
public void setValue(final IdeaPluginDescriptor ideaPluginDescriptor, Boolean value) {
final PluginId currentPluginId = ideaPluginDescriptor.getPluginId();
final Boolean enabled = myEnabled.get(currentPluginId) == null ? Boolean.FALSE : value;
@@ -439,8 +466,10 @@ public class InstalledPluginsTableModel extends PluginTableModel {
hideNotApplicablePlugins(value, ideaPluginDescriptor);
}
+ @Override
public Comparator<IdeaPluginDescriptor> getComparator() {
return new Comparator<IdeaPluginDescriptor>() {
+ @Override
public int compare(final IdeaPluginDescriptor o1, final IdeaPluginDescriptor o2) {
final Boolean enabled1 = myEnabled.get(o1.getPluginId());
final Boolean enabled2 = myEnabled.get(o2.getPluginId());
@@ -486,34 +515,39 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
for (final IdeaPluginDescriptor ideaPluginDescriptor : descriptorsToCheckDependencies) {
- PluginManager.checkDependants(ideaPluginDescriptor, new Function<PluginId, IdeaPluginDescriptor>() {
- @Nullable
- public IdeaPluginDescriptor fun(final PluginId pluginId) {
- return PluginManager.getPlugin(pluginId);
- }
- }, new Condition<PluginId>() {
- public boolean value(final PluginId pluginId) {
- Boolean enabled = myEnabled.get(pluginId);
- if (enabled == null) {
- return false;
- }
- if (newVal && !enabled.booleanValue()) {
- deps.add(pluginId);
- }
-
- if (!newVal) {
- if (ideaPluginDescriptor instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)ideaPluginDescriptor).isDeleted()) return true;
- final PluginId pluginDescriptorId = ideaPluginDescriptor.getPluginId();
- for (IdeaPluginDescriptor descriptor : ideaPluginDescriptors) {
- if (pluginId.equals(descriptor.getPluginId())) {
- deps.add(pluginDescriptorId);
- break;
- }
- }
- }
- return true;
- }
- }
+ PluginManagerCore.checkDependants(ideaPluginDescriptor, new Function<PluginId, IdeaPluginDescriptor>() {
+ @Override
+ @Nullable
+ public IdeaPluginDescriptor fun(final PluginId pluginId) {
+ return PluginManager.getPlugin(pluginId);
+ }
+ }, new Condition<PluginId>() {
+ @Override
+ public boolean value(final PluginId pluginId) {
+ Boolean enabled = myEnabled.get(pluginId);
+ if (enabled == null) {
+ return false;
+ }
+ if (newVal && !enabled.booleanValue()) {
+ deps.add(pluginId);
+ }
+
+ if (!newVal) {
+ if (ideaPluginDescriptor instanceof IdeaPluginDescriptorImpl &&
+ ((IdeaPluginDescriptorImpl)ideaPluginDescriptor).isDeleted()) {
+ return true;
+ }
+ final PluginId pluginDescriptorId = ideaPluginDescriptor.getPluginId();
+ for (IdeaPluginDescriptor descriptor : ideaPluginDescriptors) {
+ if (pluginId.equals(descriptor.getPluginId())) {
+ deps.add(pluginDescriptorId);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+ }
);
}
if (!deps.isEmpty()) {
@@ -525,6 +559,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}, ", ");
final Set<IdeaPluginDescriptor> pluginDependencies = new HashSet<IdeaPluginDescriptor>();
final String listOfDependencies = StringUtil.join(deps, new Function<PluginId, String>() {
+ @Override
public String fun(final PluginId pluginId) {
final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginId);
assert pluginDescriptor != null;
@@ -564,13 +599,13 @@ public class InstalledPluginsTableModel extends PluginTableModel {
@Override
public Comparator<IdeaPluginDescriptor> getComparator() {
- final Comparator<IdeaPluginDescriptor> comparator = super.getColumnComparator();
+ final Comparator<IdeaPluginDescriptor> comparator = getColumnComparator();
return new Comparator<IdeaPluginDescriptor>() {
@Override
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
if (isSortByStatus()) {
- final boolean incompatible1 = PluginManager.isIncompatible(o1);
- final boolean incompatible2 = PluginManager.isIncompatible(o2);
+ final boolean incompatible1 = PluginManagerCore.isIncompatible(o1);
+ final boolean incompatible2 = PluginManagerCore.isIncompatible(o2);
if (incompatible1) {
if (incompatible2) return comparator.compare(o1, o2);
return -1;
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
index a697e025fef1..49b20d27a585 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationEx;
+import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
@@ -310,30 +311,43 @@ public abstract class PluginManagerMain implements Disposable {
LOG.info(e);
errorMessages.add(e.getMessage());
}
+ String builtinPluginsUrl = ApplicationInfoEx.getInstanceEx().getBuiltinPluginsUrl();
+ if (builtinPluginsUrl != null) {
+ processPluginHost(builtinPluginsUrl, true);
+ }
for (String host : UpdateSettings.getInstance().myPluginHosts) {
- if (!acceptHost(host)) continue;
- final Map<PluginId, PluginDownloader> downloaded = new HashMap<PluginId, PluginDownloader>();
- try {
- UpdateChecker.checkPluginsHost(host, downloaded, false, null);
- for (PluginDownloader downloader : downloaded.values()) {
- final PluginNode pluginNode = PluginDownloader.createPluginNode(host, downloader);
- if (pluginNode != null) {
- if (list == null) list = new ArrayList<IdeaPluginDescriptor>();
- list.add(pluginNode);
- }
+ processPluginHost(host, false);
+ }
+ return list;
+ }
+
+ void processPluginHost(@NotNull String host, boolean builtIn) {
+ if (!acceptHost(host)) return;
+ final Map<PluginId, PluginDownloader> downloaded = new HashMap<PluginId, PluginDownloader>();
+ try {
+ UpdateChecker.checkPluginsHost(host, downloaded, false, null);
+ for (PluginDownloader downloader : downloaded.values()) {
+ final PluginNode pluginNode = PluginDownloader.createPluginNode(host, downloader);
+ if (pluginNode != null) {
+ if (list == null) list = new ArrayList<IdeaPluginDescriptor>();
+ list.add(pluginNode);
}
}
- catch (ProcessCanceledException ignore) {
- }
- catch (FileNotFoundException e) {
- LOG.info(e);
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ catch (FileNotFoundException e) {
+ LOG.info(e);
+ }
+ catch (Exception e) {
+ if (builtIn) {
+ LOG.info("built-in repo failed: " + e.toString());
}
- catch (Exception e) {
+ else {
LOG.info(e);
errorMessages.add(e.getMessage());
}
}
- return list;
}
public void finished() {
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java
index a38785fd3a2e..be7fd44fb7cc 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginsTableRenderer.java
@@ -16,12 +16,16 @@
package com.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
+import com.intellij.util.Function;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.UIUtil;
@@ -30,6 +34,7 @@ import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.text.DecimalFormat;
+import java.util.Set;
/**
* @author Konstantin Bulenkov
@@ -79,6 +84,7 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (myPluginDescriptor != null) {
+ final PluginId pluginId = myPluginDescriptor.getPluginId();
myName.setText(myPluginDescriptor.getName() + " ");
final Color fg = UIUtil.getTableForeground(isSelected);
@@ -123,18 +129,22 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
myLastUpdated.setText(DateFormatUtil.formatBetweenDates(pluginNode.getDate(), System.currentTimeMillis()));
}
- final IdeaPluginDescriptor installed = PluginManager.getPlugin(myPluginDescriptor.getPluginId());
+ final IdeaPluginDescriptor installed = PluginManager.getPlugin(pluginId);
if ((pluginNode != null && PluginManagerColumnInfo.isDownloaded(pluginNode)) ||
(installed != null && InstalledPluginsTableModel.wasUpdated(installed.getPluginId()))) {
if (!isSelected) myName.setForeground(FileStatus.ADDED.getColor());
//todo[kb] set proper icon
//myStatus.setText("[Downloaded]");
myStatus.setIcon(AllIcons.Nodes.PluginRestart);
+ if (installed != null) {
+ myPanel.setToolTipText("Plugin was updated to the newest version. Changes will be available after restart");
+ } else {
+ myPanel.setToolTipText("Plugin will be activated after restart.");
+ }
//myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
//myStatus.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
}
else if (pluginNode != null && pluginNode.getStatus() == PluginNode.STATUS_INSTALLED) {
- PluginId pluginId = pluginNode.getPluginId();
final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(pluginId);
if (!isSelected) myName.setForeground(FileStatus.MODIFIED.getColor());
if (hasNewerVersion) {
@@ -147,7 +157,7 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
//myStatus.setText("v." + pluginNode.getInstalledVersion() + (hasNewerVersion ? (" -> " + pluginNode.getVersion()) : ""));
}
- if (InstalledPluginsTableModel.hasNewerVersion(myPluginDescriptor.getPluginId())) {
+ if (InstalledPluginsTableModel.hasNewerVersion(pluginId)) {
myStatus.setIcon(AllIcons.Nodes.Pluginobsolete);
if (!isSelected) {
myName.setForeground(FileStatus.MODIFIED.getColor());
@@ -156,6 +166,37 @@ public class PluginsTableRenderer extends DefaultTableCellRenderer {
if (!myPluginDescriptor.isEnabled()) {
myStatus.setIcon(IconLoader.getDisabledIcon(myStatus.getIcon()));
}
+
+ if (table.getModel() instanceof InstalledPluginsTableModel) {
+ final InstalledPluginsTableModel installedPluginsTableModel = (InstalledPluginsTableModel)table.getModel();
+ final Set<PluginId> required = installedPluginsTableModel.getRequiredPlugins(pluginId);
+ if (required != null && required.size() > 0) {
+ final StringBuilder s = new StringBuilder();
+ if (!installedPluginsTableModel.isLoaded(pluginId)) {
+ s.append("Plugin was not loaded.\n");
+ }
+
+ if (required.contains(PluginId.getId("com.intellij.modules.ultimate"))) {
+ s.append("The plugin requires IntelliJ IDEA Ultimate");
+ }
+ else {
+ s.append("Required plugin").append(required.size() == 1 ? " \"" : "s \"");
+ s.append(StringUtil.join(required, new Function<PluginId, String>() {
+ @Override
+ public String fun(final PluginId id) {
+ final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
+ return plugin == null ? id.getIdString() : plugin.getName();
+ }
+ }, ","));
+
+ s.append(required.size() == 1 ? "\" is not enabled." : "\" are not enabled.");
+
+ }
+ myPanel.setToolTipText(s.toString());
+ } else if (PluginManagerCore.isIncompatible(myPluginDescriptor)) {
+ myPanel.setToolTipText(IdeBundle.message("plugin.manager.incompatible.tooltip.warning", ApplicationNamesInfo.getInstance().getFullProductName()));
+ }
+ }
}
if (!isSelected) {
if (PluginManagerCore.isIncompatible(myPluginDescriptor)) {
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java
index 6092139d3e0f..a28be60dbf9d 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java
@@ -47,10 +47,11 @@ class RepositoryContentHandler extends DefaultHandler {
@NonNls public static final String CHNAGE_NOTES = "change-notes";
@NonNls private static final String DEPENDS = "depends";
@NonNls private static final String DOWNLOADS = "downloads";
- @NonNls public static final String DOWNLOAD_URL = "downloadUrl";
+ @NonNls private static final String DOWNLOAD_URL = "downloadUrl";
+ @NonNls private static final String DOWNLOAD_URL_NEW_STYLE = "download-url";
@NonNls private static final String SIZE = "size";
- @NonNls private static final String RATING = "rating";
+ @NonNls private static final String RATING = "rating";
@NonNls private static final String DATE = "date";
private PluginNode currentPlugin;
private final StringBuilder currentValue = new StringBuilder();
@@ -74,7 +75,10 @@ class RepositoryContentHandler extends DefaultHandler {
currentPlugin.setDownloads(atts.getValue(DOWNLOADS));
currentPlugin.setSize(atts.getValue(SIZE));
currentPlugin.setUrl(atts.getValue(URL));
- currentPlugin.setDate(atts.getValue(DATE));
+ final String dateString = atts.getValue(DATE);
+ if (dateString != null) {
+ currentPlugin.setDate(dateString);
+ }
plugins.add(currentPlugin);
}
@@ -120,7 +124,7 @@ class RepositoryContentHandler extends DefaultHandler {
else if (qName.equals(RATING)) {
currentPlugin.setRating(currentValueString);
}
- else if (qName.equals(DOWNLOAD_URL)) {
+ else if (qName.equals(DOWNLOAD_URL) || qName.equals(DOWNLOAD_URL_NEW_STYLE)) {
currentPlugin.setDownloadUrl(currentValueString);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
index e62499049da2..19d924dff777 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
@@ -16,6 +16,7 @@
package com.intellij.ide.ui.laf;
import com.intellij.CommonBundle;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.LafManagerListener;
@@ -76,9 +77,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
+import java.util.*;
import java.util.List;
/**
@@ -107,9 +106,6 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
@NonNls private static final String[] ourFileChooserTextKeys = {"FileChooser.viewMenuLabelText", "FileChooser.newFolderActionLabelText",
"FileChooser.listViewActionLabelText", "FileChooser.detailsViewActionLabelText", "FileChooser.refreshActionLabelText"};
- @NonNls private static final String[] ourOptionPaneIconKeys = {"OptionPane.errorIcon", "OptionPane.informationIcon",
- "OptionPane.warningIcon", "OptionPane.questionIcon"};
-
private static final String[] ourAlloyComponentsToPatchSelection = {"Tree", "MenuItem", "Menu", "List",
"ComboBox", "Table", "TextArea", "EditorPane", "TextPane", "FormattedTextField", "PasswordField",
"TextField", "RadioButtonMenuItem", "CheckBoxMenuItem"};
@@ -117,11 +113,12 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
private final EventListenerList myListenerList;
private final UIManager.LookAndFeelInfo[] myLaFs;
private UIManager.LookAndFeelInfo myCurrentLaf;
- private final HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>> myStoredDefaults = new HashMap<UIManager.LookAndFeelInfo, HashMap<String, Object>>();
+ private final Map<UIManager.LookAndFeelInfo, HashMap<String, Object>> myStoredDefaults = ContainerUtil.newHashMap();
private final UISettings myUiSettings;
private String myLastWarning = null;
private PropertyChangeListener myThemeChangeListener = null;
- private static final HashMap<String, String> ourLafClassesAliases = new HashMap<String, String>();
+ private static final Map<String, String> ourLafClassesAliases = ContainerUtil.newHashMap();
+
static {
ourLafClassesAliases.put("idea.dark.laf.classname", DarculaLookAndFeelInfo.CLASS_NAME);
}
@@ -141,16 +138,17 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
else {
if (isIntelliJLafEnabled()) {
lafList.add(new IntelliJLookAndFeelInfo());
- } else {
+ }
+ else {
lafList.add(new IdeaLookAndFeelInfo());
}
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
String name = laf.getName();
- if ( !"Metal".equalsIgnoreCase(name)
- && !"CDE/Motif".equalsIgnoreCase(name)
- && !"Nimbus".equalsIgnoreCase(name)
- && !"Windows Classic".equalsIgnoreCase(name)
- && !name.startsWith("JGoodies")) {
+ if (!"Metal".equalsIgnoreCase(name)
+ && !"CDE/Motif".equalsIgnoreCase(name)
+ && !"Nimbus".equalsIgnoreCase(name)
+ && !"Windows Classic".equalsIgnoreCase(name)
+ && !name.startsWith("JGoodies")) {
lafList.add(laf);
}
}
@@ -165,7 +163,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
if (!SystemInfo.isMac) {
// do not sort LaFs on mac - the order is determined as Default, Darcula.
// when we leave only system LaFs on other OSes, the order also should be determined as Default, Darcula
-
+
Arrays.sort(myLaFs, new Comparator<UIManager.LookAndFeelInfo>() {
@Override
public int compare(UIManager.LookAndFeelInfo obj1, UIManager.LookAndFeelInfo obj2) {
@@ -291,8 +289,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
Element element = new Element("state");
if (myCurrentLaf != null) {
String className = myCurrentLaf.getClassName();
- if (className != null){
- Element child=new Element(ELEMENT_LAF);
+ if (className != null) {
+ Element child = new Element(ELEMENT_LAF);
child.setAttribute(ATTRIBUTE_CLASS_NAME, className);
element.addContent(child);
}
@@ -301,12 +299,12 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
@Override
- public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels(){
+ public UIManager.LookAndFeelInfo[] getInstalledLookAndFeels() {
return myLaFs.clone();
}
@Override
- public UIManager.LookAndFeelInfo getCurrentLookAndFeel(){
+ public UIManager.LookAndFeelInfo getCurrentLookAndFeel() {
return myCurrentLaf;
}
@@ -330,11 +328,11 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
if (PlatformUtils.isRubyMine() || PlatformUtils.isPyCharm()) {
final String desktop = AccessController.doPrivileged(new GetPropertyAction("sun.desktop"));
if ("gnome".equals(desktop)) {
- UIManager.LookAndFeelInfo laf=findLaf(systemLafClassName);
+ UIManager.LookAndFeelInfo laf = findLaf(systemLafClassName);
if (laf != null) {
return laf;
}
- LOG.info("Could not find system look and feel: " + laf);
+ LOG.info("Could not find system look and feel: " + systemLafClassName);
}
}
// Default
@@ -449,14 +447,14 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
@Nullable
private static Icon getAquaMenuInvertedIcon() {
if (!UIUtil.isUnderAquaLookAndFeel()) return null;
- final Icon arrow = (Icon) UIManager.get("Menu.arrowIcon");
+ final Icon arrow = (Icon)UIManager.get("Menu.arrowIcon");
if (arrow == null) return null;
try {
final Method method = arrow.getClass().getMethod("getInvertedIcon");
if (method != null) {
method.setAccessible(true);
- return (Icon) method.invoke(arrow);
+ return (Icon)method.invoke(arrow);
}
return null;
@@ -548,7 +546,10 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
// a Java wrapper for ObjC MagicBackgroundColor class (Java RGB values ignored).
// MagicBackgroundColor always reports current Frame background.
// So we need to set frames background to exact and correct value.
- frame.setBackground(new Color(UIUtil.getPanelBackground().getRGB()));
+ if (SystemInfo.isMac) {
+ //noinspection UseJBColor
+ frame.setBackground(new Color(UIUtil.getPanelBackground().getRGB()));
+ }
updateUI(frame);
}
@@ -591,7 +592,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
private static void fixTreeWideSelection(UIDefaults uiDefaults) {
if (UIUtil.isUnderAlloyIDEALookAndFeel() || UIUtil.isUnderJGoodiesLookAndFeel()) {
final Color bg = new ColorUIResource(56, 117, 215);
- final Color fg = new ColorUIResource(Color.WHITE);
+ final Color fg = new ColorUIResource(255, 255, 255);
uiDefaults.put("info", bg);
uiDefaults.put("textHighlight", bg);
for (String key : ourAlloyComponentsToPatchSelection) {
@@ -616,7 +617,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
private static void fixPopupWeight() {
int popupWeight = OurPopupFactory.WEIGHT_MEDIUM;
String property = System.getProperty("idea.popup.weight");
- if (property != null) property = property.toLowerCase().trim();
+ if (property != null) property = property.toLowerCase(Locale.ENGLISH).trim();
if (SystemInfo.isMacOSLeopard) {
// force heavy weight popups under Leopard, otherwise they don't have shadow or any kind of border.
popupWeight = OurPopupFactory.WEIGHT_HEAVY;
@@ -656,27 +657,28 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
final SynthStyleFactory original = SynthLookAndFeel.getStyleFactory();
SynthLookAndFeel.setStyleFactory(new SynthStyleFactory() {
- @Override
- public SynthStyle getStyle(final JComponent c, final Region id) {
- final SynthStyle style = original.getStyle(c, id);
- if (id == Region.POPUP_MENU) {
- try {
- Field f = style.getClass().getDeclaredField("xThickness");
+ @Override
+ public SynthStyle getStyle(final JComponent c, final Region id) {
+ final SynthStyle style = original.getStyle(c, id);
+ if (id == Region.POPUP_MENU) {
+ try {
+ Field f = style.getClass().getDeclaredField("xThickness");
+ f.setAccessible(true);
+ final Object x = f.get(style);
+ if (x instanceof Integer && (Integer)x == 0) {
+ // workaround for Sun bug #6636964
+ f.set(style, 1);
+ f = style.getClass().getDeclaredField("yThickness");
f.setAccessible(true);
- final Object x = f.get(style);
- if (x instanceof Integer && (Integer)x == 0) {
- // workaround for Sun bug #6636964
- f.set(style, 1);
- f = style.getClass().getDeclaredField("yThickness");
- f.setAccessible(true);
- f.set(style, 3);
- }
+ f.set(style, 3);
}
- catch (Exception ignore) { }
}
- return style;
+ catch (Exception ignore) {
+ }
}
- });
+ return style;
+ }
+ });
new JBPopupMenu(); // invokes updateUI() -> updateStyle()
@@ -692,16 +694,20 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
}
- private static void patchOptionPaneIcons(final UIDefaults defaults) {
- if (UIUtil.isUnderGTKLookAndFeel() && defaults.get(ourOptionPaneIconKeys[0]) == null) {
- // GTK+ L&F keeps icons hidden in style
- final SynthStyle style = SynthLookAndFeel.getStyle(new JOptionPane(""), Region.DESKTOP_ICON);
- if (style != null) {
- for (final String key : ourOptionPaneIconKeys) {
- final Object icon = style.get(null, key);
- if (icon != null) defaults.put(key, icon);
- }
- }
+ private static void patchOptionPaneIcons(UIDefaults defaults) {
+ if (!UIUtil.isUnderGTKLookAndFeel()) return;
+
+ Map<String, Icon> map = ContainerUtil.newHashMap(
+ Arrays.asList("OptionPane.errorIcon", "OptionPane.informationIcon", "OptionPane.warningIcon", "OptionPane.questionIcon"),
+ Arrays.asList(AllIcons.General.ErrorDialog, AllIcons.General.InformationDialog, AllIcons.General.WarningDialog, AllIcons.General.QuestionDialog));
+
+ // GTK+ L&F keeps icons hidden in style
+ SynthStyle style = SynthLookAndFeel.getStyle(new JOptionPane(""), Region.DESKTOP_ICON);
+ for (String key : map.keySet()) {
+ if (defaults.get(key) != null) continue;
+
+ Object icon = style == null ? null : style.get(null, key);
+ defaults.put(key, icon instanceof Icon ? icon : map.get(key));
}
}
@@ -737,12 +743,12 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
}
- private static void updateUI(Window window){
- if(!window.isDisplayable()){
+ private static void updateUI(Window window) {
+ if (!window.isDisplayable()) {
return;
}
IJSwingUtilities.updateComponentTreeUI(window);
- Window[] children=window.getOwnedWindows();
+ Window[] children = window.getOwnedWindows();
for (Window aChildren : children) {
updateUI(aChildren);
}
@@ -752,19 +758,19 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
* Repaints all displayable window.
*/
@Override
- public void repaintUI(){
- Frame[] frames=Frame.getFrames();
+ public void repaintUI() {
+ Frame[] frames = Frame.getFrames();
for (Frame frame : frames) {
repaintUI(frame);
}
}
- private static void repaintUI(Window window){
- if(!window.isDisplayable()){
+ private static void repaintUI(Window window) {
+ if (!window.isDisplayable()) {
return;
}
window.repaint();
- Window[] children=window.getOwnedWindows();
+ Window[] children = window.getOwnedWindows();
for (Window aChildren : children) {
repaintUI(aChildren);
}
@@ -785,30 +791,30 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
@SuppressWarnings({"HardCodedStringLiteral"})
- public static void initInputMapDefaults(UIDefaults defaults){
+ public static void initInputMapDefaults(UIDefaults defaults) {
// Make ENTER work in JTrees
InputMap treeInputMap = (InputMap)defaults.get("Tree.focusInputMap");
- if(treeInputMap!=null){ // it's really possible. For example, GTK+ doesn't have such map
- treeInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"toggle");
+ if (treeInputMap != null) { // it's really possible. For example, GTK+ doesn't have such map
+ treeInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "toggle");
}
// Cut/Copy/Paste in JTextAreas
- InputMap textAreaInputMap=(InputMap)defaults.get("TextArea.focusInputMap");
- if(textAreaInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
+ InputMap textAreaInputMap = (InputMap)defaults.get("TextArea.focusInputMap");
+ if (textAreaInputMap != null) { // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
installCutCopyPasteShortcuts(textAreaInputMap, false);
}
// Cut/Copy/Paste in JTextFields
- InputMap textFieldInputMap=(InputMap)defaults.get("TextField.focusInputMap");
- if(textFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
+ InputMap textFieldInputMap = (InputMap)defaults.get("TextField.focusInputMap");
+ if (textFieldInputMap != null) { // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
installCutCopyPasteShortcuts(textFieldInputMap, false);
}
// Cut/Copy/Paste in JPasswordField
- InputMap passwordFieldInputMap=(InputMap)defaults.get("PasswordField.focusInputMap");
- if(passwordFieldInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
+ InputMap passwordFieldInputMap = (InputMap)defaults.get("PasswordField.focusInputMap");
+ if (passwordFieldInputMap != null) { // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
installCutCopyPasteShortcuts(passwordFieldInputMap, false);
}
// Cut/Copy/Paste in JTables
- InputMap tableInputMap=(InputMap)defaults.get("Table.ancestorInputMap");
- if(tableInputMap!=null){ // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
+ InputMap tableInputMap = (InputMap)defaults.get("Table.ancestorInputMap");
+ if (tableInputMap != null) { // It really can be null, for example when LAF isn't properly initialized (Alloy license problem)
installCutCopyPasteShortcuts(tableInputMap, true);
}
}
@@ -899,7 +905,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
break;
}
- catch (Exception ignored) { }
+ catch (Exception ignored) {
+ }
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java
index 8deb957d21f1..a10ff34c425c 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java
@@ -98,6 +98,23 @@ public class DarculaButtonUI extends BasicButtonUI {
}
@Override
+ protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect) {
+ Border border = c.getBorder();
+ if (border != null && isSquare(c)) {
+ int xOff = 1;
+ Insets ins = border.getBorderInsets(c);
+ int yOff = (ins.top + ins.bottom) / 4;
+ Rectangle iconRect2 = new Rectangle(iconRect);
+ iconRect2.x += xOff;
+ iconRect2.y += yOff;
+ super.paintIcon(g, c, iconRect2);
+ }
+ else {
+ super.paintIcon(g, c, iconRect);
+ }
+ }
+
+ @Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
if (c instanceof JButton && ((JButton)c).isDefaultButton() && !SystemInfo.isMac) {
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java
index b1b1d582df4c..58c6a8bae0d2 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -74,9 +74,11 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
g.fillRect(0, 0, size.width, size.height);
}
- if (b.isSelected() && b.getSelectedIcon() != null) {
+ final boolean selected = b.isSelected();
+ final boolean enabled = b.isEnabled();
+ if (selected && b.getSelectedIcon() != null) {
b.getSelectedIcon().paintIcon(b, g, iconRect.x + 4, iconRect.y + 2);
- } else if (!b.isSelected() && b.getIcon() != null) {
+ } else if (!selected && b.getIcon() != null) {
b.getIcon().paintIcon(b, g, iconRect.x + 4, iconRect.y + 2);
} else {
final int x = iconRect.x + 3;
@@ -98,15 +100,18 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
final boolean armed = b.getModel().isArmed();
if (c.hasFocus()) {
- g.setPaint(UIUtil.getGradientPaint(w/2, 1, getFocusedBackgroundColor1(armed), w/2, h, getFocusedBackgroundColor2(armed)));
- g.fillRoundRect(0, 0, w - 2, h - 2, 4, 4);
+ g.setPaint(UIUtil.getGradientPaint(w/2, 1, getFocusedBackgroundColor1(armed, selected), w/2, h, getFocusedBackgroundColor2(armed, selected)));
+ g.fillRoundRect(0, 0, w, h, 4, 4);
DarculaUIUtil.paintFocusRing(g, 1, 1, w - 2, h - 2);
} else {
- g.setPaint(UIUtil.getGradientPaint(w / 2, 1, getBackgroundColor1(), w / 2, h, getBackgroundColor2()));
- g.fillRoundRect(0, 0, w, h - 1 , 4, 4);
+ g.setPaint(UIUtil.getGradientPaint(w / 2, 1, getBackgroundColor1(enabled, selected), w / 2, h, getBackgroundColor2(enabled,
+ selected)));
+ g.fillRoundRect(0, 0, w, h , 4, 4);
- g.setPaint(UIUtil.getGradientPaint(w / 2, 1, getBorderColor1(b.isEnabled()), w / 2, h, getBorderColor2(b.isEnabled())));
+ final Color borderColor1 = getBorderColor1(enabled, selected);
+ final Color borderColor2 = getBorderColor2(enabled, selected);
+ g.setPaint(UIUtil.getGradientPaint(w / 2, 1, borderColor1, w / 2, h, borderColor2));
g.drawRoundRect(0, (UIUtil.isUnderDarcula() ? 1 : 0), w, h - 1, 4, 4);
g.setPaint(getInactiveFillColor());
@@ -114,14 +119,7 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
}
if (b.getModel().isSelected()) {
- g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
- g.setStroke(new BasicStroke(1 *2.0f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
- g.setPaint(getShadowColor(b.isEnabled()));
- g.drawLine(4, 7, 7, 11);
- g.drawLine(7, 11, w, 2);
- g.setPaint(getCheckSignColor(b.isEnabled()));
- g.drawLine(4, 5, 7, 9);
- g.drawLine(7, 9, w, 0);
+ paintCheckSign(g, enabled, w, h);
}
g.translate(-x, -y);
config.restore();
@@ -142,46 +140,57 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
}
}
+ protected void paintCheckSign(Graphics2D g, boolean enabled, int w, int h) {
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g.setStroke(new BasicStroke(1 *2.0f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
+ g.setPaint(getShadowColor(enabled, true));
+ g.drawLine(4, 7, 7, 11);
+ g.drawLine(7, 11, w, 2);
+ g.setPaint(getCheckSignColor(enabled, true));
+ g.drawLine(4, 5, 7, 9);
+ g.drawLine(7, 9, w, 0);
+ }
+
protected Color getInactiveFillColor() {
return getColor("inactiveFillColor", Gray._40.withAlpha(180));
}
- protected Color getBorderColor1(boolean enabled) {
- return enabled ? getColor("borderColor1", Gray._120.withAlpha(0x5a))
- : getColor("disabledBorderColor1", Gray._120.withAlpha(90));
+ protected Color getBorderColor1(boolean enabled, boolean selected) {
+ return enabled ? getColor("borderColor1", Gray._120.withAlpha(0x5a), selected)
+ : getColor("disabledBorderColor1", Gray._120.withAlpha(90), selected);
}
- protected Color getBorderColor2(boolean enabled) {
- return enabled ? getColor("borderColor2", Gray._105.withAlpha(90))
- : getColor("disabledBorderColor2", Gray._105.withAlpha(90));
+ protected Color getBorderColor2(boolean enabled, boolean selected) {
+ return enabled ? getColor("borderColor2", Gray._105.withAlpha(90), selected)
+ : getColor("disabledBorderColor2", Gray._105.withAlpha(90), selected);
}
- protected Color getBackgroundColor1() {
- return getColor("backgroundColor1", Gray._110);
+ protected Color getBackgroundColor1(boolean enabled, boolean selected) {
+ return getColor("backgroundColor1", Gray._110, selected);
}
- protected Color getBackgroundColor2() {
- return getColor("backgroundColor2", Gray._95);
+ protected Color getBackgroundColor2(boolean enabled, boolean selected) {
+ return getColor("backgroundColor2", Gray._95, selected);
}
- protected Color getCheckSignColor(boolean enabled) {
- return enabled ? getColor("checkSignColor", Gray._170)
- : getColor("checkSignColorDisabled", Gray._120);
+ protected Color getCheckSignColor(boolean enabled, boolean selected) {
+ return enabled ? getColor("checkSignColor", Gray._170, selected)
+ : getColor("checkSignColorDisabled", Gray._120, selected);
}
- protected Color getShadowColor(boolean enabled) {
- return enabled ? getColor("shadowColor", Gray._30)
- : getColor("shadowColorDisabled", Gray._60);
+ protected Color getShadowColor(boolean enabled, boolean selected) {
+ return enabled ? getColor("shadowColor", Gray._30, selected)
+ : getColor("shadowColorDisabled", Gray._60, selected);
}
- protected Color getFocusedBackgroundColor1(boolean armed) {
- return armed ? getColor("focusedArmed.backgroundColor1", Gray._100)
- : getColor("focused.backgroundColor1", Gray._120);
+ protected Color getFocusedBackgroundColor1(boolean armed, boolean selected) {
+ return armed ? getColor("focusedArmed.backgroundColor1", Gray._100, selected)
+ : getColor("focused.backgroundColor1", Gray._120, selected);
}
- protected Color getFocusedBackgroundColor2(boolean armed) {
- return armed ? getColor("focusedArmed.backgroundColor2", Gray._55)
- : getColor("focused.backgroundColor2", Gray._75);
+ protected Color getFocusedBackgroundColor2(boolean armed, boolean selected) {
+ return armed ? getColor("focusedArmed.backgroundColor2", Gray._55, selected)
+ : getColor("focused.backgroundColor2", Gray._75, selected);
}
protected static Color getColor(String shortPropertyName, Color defaultValue) {
@@ -189,6 +198,16 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI {
return color == null ? defaultValue : color;
}
+ protected static Color getColor(String shortPropertyName, Color defaultValue, boolean selected) {
+ if (selected) {
+ final Color color = getColor(shortPropertyName + ".selected", null);
+ if (color != null) {
+ return color;
+ }
+ }
+ return getColor(shortPropertyName, defaultValue);
+ }
+
@Override
public Icon getDefaultIcon() {
return new IconUIResource(EmptyIcon.create(20));
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextBorder.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextBorder.java
index 3c6a69d7cae2..1aeca4f4c529 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextBorder.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaTextBorder.java
@@ -70,10 +70,10 @@ public class DarculaTextBorder implements Border, UIResource {
}
private static Color getBorderColor(boolean enabled) {
+ // in sync with ComboBox's border color
if (UIUtil.isUnderDarcula()) {
return enabled ? Gray._100 : Gray._83;
}
- // disabled color is the same as ComboBox's border has
- return enabled ? Gray._100 : Gray._150;
+ return Gray._150;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/IntelliJCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/IntelliJCheckBoxUI.java
new file mode 100644
index 000000000000..e7333db456a9
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/IntelliJCheckBoxUI.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.ui.laf.intellij;
+
+import com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxUI;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class IntelliJCheckBoxUI extends DarculaCheckBoxUI {
+
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new IntelliJCheckBoxUI();
+ }
+
+ @Override
+ protected void paintCheckSign(Graphics2D g, boolean enabled, int w, int h) {
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g.setStroke(new BasicStroke(1 *2.0f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
+
+ g.setPaint(getShadowColor(enabled, true));
+ g.drawLine(5, 9, 7, 11);
+ g.drawLine(7, 11, w-3, 5);
+ g.setPaint(getCheckSignColor(enabled, true));
+ g.drawLine(5, 7, 7, 9);
+ g.drawLine(7, 9, w-3, 3);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties
index 5cfb19b01d43..f721abfdb92b 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties
@@ -88,23 +88,33 @@ ProgressBar.foreground=808080
FormattedTextField.background=ffffff
-CheckBoxUI=com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxUI
+CheckBoxUI=com.intellij.ide.ui.laf.intellij.IntelliJCheckBoxUI
CheckBox.border=com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxBorder
CheckBox.darcula.inactiveFillColor=00000000
CheckBox.darcula.borderColor1=444444
+CheckBox.darcula.borderColor1.selected=2C90FB
CheckBox.darcula.borderColor2=444444
+CheckBox.darcula.borderColor2.selected=2C90FB
CheckBox.darcula.disabledBorderColor1=969696
CheckBox.darcula.disabledBorderColor2=969696
CheckBox.darcula.backgroundColor1=ffffff
+CheckBox.darcula.backgroundColor1.selected=3B98FB
CheckBox.darcula.backgroundColor2=ffffff
+CheckBox.darcula.backgroundColor2.selected=3B98FB
CheckBox.darcula.checkSignColor=444444
+CheckBox.darcula.checkSignColor.selected=ffffff
CheckBox.darcula.checkSignColorDisabled=999999
CheckBox.darcula.shadowColor=55555530
+CheckBox.darcula.shadowColor.selected=1D7BDD
CheckBox.darcula.shadowColorDisabled=eeeeee
CheckBox.darcula.focusedArmed.backgroundColor1=ffffff
+CheckBox.darcula.focusedArmed.backgroundColor1.selected=3B98FB
CheckBox.darcula.focusedArmed.backgroundColor2=ffffff
+CheckBox.darcula.focusedArmed.backgroundColor2.selected=3B98FB
CheckBox.darcula.focused.backgroundColor1=eeeeee
+CheckBox.darcula.focused.backgroundColor1.selected=3B98FB
CheckBox.darcula.focused.backgroundColor2=eeeeee
+CheckBox.darcula.focused.backgroundColor2.selected=3B98FB
ComboBoxUI=com.intellij.ide.ui.laf.darcula.ui.DarculaComboBoxUI
ComboBox.disabledBackground=e8e8e8
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java b/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java
index e78f960d6e92..33501b503477 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/TipDialog.java
@@ -22,6 +22,7 @@ import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
@@ -72,6 +73,7 @@ public class TipDialog extends DialogWrapper{
public NextTipAction(){
super(IdeBundle.message("action.next.tip"));
putValue(DialogWrapper.DEFAULT_ACTION,Boolean.TRUE);
+ putValue(DialogWrapper.FOCUSED_ACTION,Boolean.TRUE); // myPreferredFocusedComponent
}
public void actionPerformed(ActionEvent e){
@@ -79,4 +81,10 @@ public class TipDialog extends DialogWrapper{
UsageTrigger.trigger("tips.of.the.day.next");
}
}
+
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myPreferredFocusedComponent;
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
index f8c1029e0a97..bbd52139bd51 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
@@ -92,8 +92,11 @@ public class TipUIUtil {
updateShortcuts(text);
updateImages(text, tipLoader);
String replaced = text.toString().replace("&productName;", ApplicationNamesInfo.getInstance().getFullProductName());
- replaced = replaced.replace("&majorVersion;", ApplicationInfo.getInstance().getMajorVersion());
- replaced = replaced.replace("&minorVersion;", ApplicationInfo.getInstance().getMinorVersion());
+ String major = ApplicationInfo.getInstance().getMajorVersion();
+ replaced = replaced.replace("&majorVersion;", major);
+ String minor = ApplicationInfo.getInstance().getMinorVersion();
+ replaced = replaced.replace("&minorVersion;", minor);
+ replaced = replaced.replace("&majorMinorVersion;", major + ("0".equals(minor) ? "" : ("." + minor)));
if (UIUtil.isUnderDarcula()) {
replaced = replaced.replace("css/tips.css", "css/tips_darcula.css");
}
diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
index e0a6949c543d..94b25a1b3c94 100644
--- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
+++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
@@ -56,6 +56,7 @@ import java.util.Arrays;
public class IdeaApplication {
@NonNls public static final String IDEA_IS_INTERNAL_PROPERTY = "idea.is.internal";
+ @NonNls public static final String IDEA_IS_UNIT_TEST = "idea.is.unit.test";
private static final Logger LOG = Logger.getInstance("#com.intellij.idea.IdeaApplication");
@@ -80,7 +81,8 @@ public class IdeaApplication {
ourInstance = this;
myArgs = args;
- boolean isInternal = Boolean.valueOf(System.getProperty(IDEA_IS_INTERNAL_PROPERTY)).booleanValue();
+ boolean isInternal = Boolean.getBoolean(IDEA_IS_INTERNAL_PROPERTY);
+ boolean isUnitTest = Boolean.getBoolean(IDEA_IS_UNIT_TEST);
boolean headless = Main.isHeadless();
if (!headless) {
@@ -88,7 +90,7 @@ public class IdeaApplication {
}
if (Main.isCommandLine()) {
- new CommandLineApplication(isInternal, false, headless);
+ new CommandLineApplication(isInternal, isUnitTest, headless);
}
else {
Splash splash = null;
@@ -99,7 +101,7 @@ public class IdeaApplication {
}
}
- ApplicationManagerEx.createApplication(isInternal, false, false, false, ApplicationManagerEx.IDEA_APPLICATION, splash);
+ ApplicationManagerEx.createApplication(isInternal, isUnitTest, false, false, ApplicationManagerEx.IDEA_APPLICATION, splash);
}
if (myStarter == null) {
@@ -216,7 +218,13 @@ public class IdeaApplication {
@Nullable
private SplashScreen getSplashScreen() {
- return SplashScreen.getSplashScreen();
+ try {
+ return SplashScreen.getSplashScreen();
+ }
+ catch (Throwable t) {
+ LOG.warn(t);
+ return null;
+ }
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java
index f726049f7b7b..6be8a543e48a 100644
--- a/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java
+++ b/platform/platform-impl/src/com/intellij/internal/statistic/beans/ConvertUsagesUtil.java
@@ -15,6 +15,8 @@
*/
package com.intellij.internal.statistic.beans;
+import org.jetbrains.annotations.NotNull;
+
import java.util.*;
/**
@@ -150,6 +152,22 @@ public class ConvertUsagesUtil {
return map;
}
+ /**
+ * Escapes descriptor name so it could be used in {@link #assertDescriptorName(String)}
+ *
+ * @param name name to escape
+ * @return escaped name
+ */
+ @NotNull
+ public static String escapeDescriptorName(@NotNull final String name) {
+ return name.replace(" ", "_").
+ replace(GROUP_SEPARATOR, '_').
+ replace(GROUPS_SEPARATOR, '_').
+ replace(GROUP_VALUE_SEPARATOR, '_')
+ .replace("'", " ")
+ .replace("\"", " ");
+ }
+
private static class StringPair {
public final String first;
public final String second;
@@ -164,6 +182,9 @@ public class ConvertUsagesUtil {
return s == null || s.trim().length() == 0;
}
+ /**
+ * @see #escapeDescriptorName(String)
+ */
public static void assertDescriptorName(String key) {
assert key != null;
assert key.indexOf(GROUP_SEPARATOR) == -1 : key + " contains invalid chars";
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/AbbreviationManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/AbbreviationManagerImpl.java
index 97196b75f3db..a7b2e7bc9d02 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/AbbreviationManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/AbbreviationManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -106,6 +106,12 @@ public class AbbreviationManagerImpl extends AbbreviationManager implements
final String abbrValue = abbr.getAttributeValue("name");
if (abbrValue != null) {
values.add(abbrValue);
+ List<String> actionIds = myAbbreviation2ActionId.get(abbrValue);
+ if (actionIds == null) {
+ actionIds = new ArrayList<String>();
+ myAbbreviation2ActionId.put(abbrValue, actionIds);
+ }
+ actionIds.add(actionId);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index 2856c8b601c6..308d5dbb1835 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -19,6 +19,7 @@ import com.intellij.BundleBase;
import com.intellij.CommonBundle;
import com.intellij.diagnostic.PerformanceWatcher;
import com.intellij.diagnostic.PluginException;
+import com.intellij.diagnostic.ThreadDumper;
import com.intellij.ide.*;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerCore;
@@ -80,7 +81,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"})
public class ApplicationImpl extends PlatformComponentManagerImpl implements ApplicationEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.application.impl.ApplicationImpl");
private final ModalityState MODALITY_STATE_NONE = ModalityState.NON_MODAL;
@@ -96,7 +96,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private IApplicationStore myComponentStore;
- private boolean myTestModeFlag;
+ private final boolean myTestModeFlag;
private final boolean myHeadlessMode;
private final boolean myCommandLineMode;
@@ -107,12 +107,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private volatile Runnable myExceptionalThreadWithReadAccessRunnable;
- private int myInEditorPaintCounter = 0;
- private long myStartTime = 0;
+ private int myInEditorPaintCounter; // EDT only
+ private final long myStartTime;
@Nullable
private final Splash mySplash;
private boolean myDoNotSave;
- private volatile boolean myDisposeInProgress = false;
+ private volatile boolean myDisposeInProgress;
private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last
@@ -171,7 +171,30 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private Boolean myActive;
- private static final ThreadLocal<Integer> ourEdtSafe = new ThreadLocal<Integer>();
+ private static final int IS_EDT_FLAG = 1<<30; // we don't mess with sign bit since we want to do arithmetic
+ private static final int IS_READ_LOCK_ACQUIRED_FLAG = 1<<29;
+ private static final int IS_EXCEPTIONAL_THREAD_FLAG = 1<<28;
+ private static class Status {
+ // higher three bits are for IS_* flags
+ // lower bits are for edtSafe counter
+ private int flags;
+ }
+
+ private static final ThreadLocal<Status> status = new ThreadLocal<Status>(){
+ @Override
+ protected Status initialValue() {
+ Status status = new Status();
+ status.flags = BitUtil.set(status.flags, IS_EDT_FLAG, EventQueue.isDispatchThread());
+ return status;
+ }
+ };
+ private static Status getStatus() {
+ return status.get();
+ }
+ private static void setReadLockAcquired(Status status, boolean acquired) {
+ status.flags = BitUtil.set(status.flags, IS_READ_LOCK_ACQUIRED_FLAG, acquired);
+ }
+
@NonNls private static final ModalityState ANY = new ModalityState() {
@Override
public boolean dominates(@NotNull ModalityState anotherState) {
@@ -201,7 +224,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
- public void initializeComponent(Object component, boolean service) {
+ public void initializeComponent(@NotNull Object component, boolean service) {
getStateStore().initComponent(component, service);
}
@@ -233,7 +256,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
myHeadlessMode = isHeadless;
myCommandLineMode = isCommandLine;
- myDoNotSave = myTestModeFlag || myHeadlessMode;
+ myDoNotSave = isUnitTestMode || isHeadless;
loadApplicationComponents();
@@ -290,7 +313,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
public void run() {
- if (isDisposed() || isDisposeInProgress()) {
+ if (isDisposed() || myDisposeInProgress) {
return;
}
ShutDownTracker.invokeAndWait(isUnitTestMode(), true, new Runnable() {
@@ -353,7 +376,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public boolean holdsReadLock() {
- return myLock.getReadHoldCount() != 0;
+ return holdsReadLock(getStatus());
+ }
+
+ private static boolean holdsReadLock(Status status) {
+ return BitUtil.isSet(status.flags, IS_READ_LOCK_ACQUIRED_FLAG);
}
private void loadApplicationComponents() {
@@ -367,7 +394,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
- protected synchronized Object createComponent(Class componentInterface) {
+ protected synchronized Object createComponent(@NotNull Class componentInterface) {
Object component = super.createComponent(componentInterface);
if (mySplash != null) {
mySplash.showProgress("", 0.65f + getPercentageOfComponentsLoaded() * 0.35f);
@@ -375,6 +402,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return component;
}
+ @NotNull
@Override
protected MutablePicoContainer createPicoContainer() {
return Extensions.getRootArea().getPicoContainer();
@@ -395,10 +423,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return myTestModeFlag;
}
- public void setUnitTestMode(boolean testModeFlag) {
- myTestModeFlag = testModeFlag;
- }
-
@Override
public boolean isHeadlessEnvironment() {
return myHeadlessMode;
@@ -415,6 +439,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return ourThreadExecutorsService.submit(new Runnable() {
@Override
public void run() {
+ if (isReadAccessAllowed()) {
+ assert false : describe(Thread.currentThread());
+ }
try {
action.run();
}
@@ -427,6 +454,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
finally {
//ReflectionUtil.resetThreadLocals();
Thread.interrupted(); // reset interrupted status
+ if (isReadAccessAllowed()) {
+ assert false : describe(Thread.currentThread());
+ }
}
}
});
@@ -438,6 +468,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return ourThreadExecutorsService.submit(new Callable<T>() {
@Override
public T call() {
+ if (isReadAccessAllowed()) {
+ assert false : describe(Thread.currentThread());
+ }
try {
return action.call();
}
@@ -450,17 +483,22 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
finally {
//ReflectionUtil.resetThreadLocals();
Thread.interrupted(); // reset interrupted status
+ if (isReadAccessAllowed()) {
+ assert false : describe(Thread.currentThread());
+ }
}
return null;
}
});
}
- private static Thread ourDispatchThread = null;
-
@Override
public boolean isDispatchThread() {
- return EventQueue.isDispatchThread();
+ return isDispatchThread(getStatus());
+ }
+
+ private static boolean isDispatchThread(Status status) {
+ return BitUtil.isSet(status.flags, IS_EDT_FLAG);
}
@Override
@@ -535,7 +573,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
- protected <T> T getComponentFromContainer(final Class<T> interfaceClass) {
+ protected <T> T getComponentFromContainer(@NotNull final Class<T> interfaceClass) {
if (myIsFiringLoadingEvent) {
return null;
}
@@ -567,13 +605,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
Disposer.dispose(myLastDisposable); // dispose it last
}
- private final Object lock = new Object();
- private void makeChangesVisibleToEDT() {
- synchronized (lock) {
- lock.hashCode();
- }
- }
-
@Override
public boolean runProcessWithProgressSynchronously(@NotNull final Runnable process,
@NotNull String progressTitle,
@@ -629,7 +660,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public void run() {
if (myExceptionalThreadWithReadAccessRunnable != process) {
- LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
+ LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
}
executeOnPooledThread(new Runnable() {
@@ -639,9 +670,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
}
- final boolean old = setExceptionalThreadWithReadAccessFlag(true);
- LOG.assertTrue(isReadAccessAllowed());
+ setExceptionalThreadWithReadAccessFlag(true);
try {
+ LOG.assertTrue(isReadAccessAllowed());
ProgressManager.getInstance().runProcess(process, progress);
}
catch (ProcessCanceledException e) {
@@ -653,8 +684,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
throw e;
}
finally {
- setExceptionalThreadWithReadAccessFlag(old);
- makeChangesVisibleToEDT();
+ setExceptionalThreadWithReadAccessFlag(false);
}
}
});
@@ -669,7 +699,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
finally {
myExceptionalThreadWithReadAccessRunnable = null;
- makeChangesVisibleToEDT();
}
return !progress.isCanceled();
@@ -677,12 +706,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public void invokeAndWait(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
- if (isDispatchThread()) {
+ Status status = getStatus();
+ if (isDispatchThread(status)) {
runnable.run();
return;
}
- if (!isExceptionalThreadWithReadAccess() && holdsReadLock()) {
+ if (!isExceptionalThreadWithReadAccess(status) && holdsReadLock(status)) {
LOG.error("Calling invokeAndWait from read-action leads to possible deadlock.");
}
@@ -712,13 +742,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
@NotNull
public ModalityState getDefaultModalityState() {
- if (EventQueue.isDispatchThread()) {
+ if (isDispatchThread()) {
return getCurrentModalityState();
}
- else {
- ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
- return progress == null ? getNoneModalityState() : progress.getModalityState();
- }
+ ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
+ return progress == null ? getNoneModalityState() : progress.getModalityState();
}
@Override
@@ -769,7 +797,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
private static volatile boolean exiting = false;
public void exit(final boolean force, final boolean allowListenersToCancel, final boolean restart) {
-
if (exiting) return;
exiting = true;
@@ -788,19 +815,19 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).appClosing();
myDisposeInProgress = true;
- if (!doExit(allowListenersToCancel, restart)) {
- myDisposeInProgress = false;
- }
+ doExit(allowListenersToCancel, restart);
+ myDisposeInProgress = false;
}
};
- if (!isDispatchThread()) {
- invokeLater(runnable, ModalityState.NON_MODAL);
+ if (isDispatchThread()) {
+ runnable.run();
}
else {
- runnable.run();
+ invokeLater(runnable, ModalityState.NON_MODAL);
}
- } finally {
+ }
+ finally {
exiting = false;
}
}
@@ -857,6 +884,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return "Do not ask me again";
@@ -896,13 +924,15 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public void runReadAction(@NotNull final Runnable action) {
- if (isReadAccessAllowed()) {
+ Status status = getStatus();
+ if (isReadAccessAllowed(status)) {
action.run();
}
else {
- assertReadActionAllowed();
+ assertNoPsiLock();
try {
myLock.readLock().lockInterruptibly();
+ setReadLockAcquired(status, true);
}
catch (InterruptedException e) {
throw new RuntimeInterruptedException(e);
@@ -911,70 +941,66 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
action.run();
}
finally {
+ setReadLockAcquired(status, false);
myLock.readLock().unlock();
}
}
}
@Override
public <T> T runReadAction(@NotNull final Computable<T> computation) {
- if (isReadAccessAllowed()) {
+ Status status = getStatus();
+ if (isReadAccessAllowed(status)) {
return computation.compute();
}
- else {
- assertReadActionAllowed();
- try {
- myLock.readLock().lockInterruptibly();
- }
- catch (InterruptedException e) {
- throw new RuntimeInterruptedException(e);
- }
- try {
- return computation.compute();
- }
- finally {
- myLock.readLock().unlock();
- }
+ assertNoPsiLock();
+ try {
+ myLock.readLock().lockInterruptibly();
+ setReadLockAcquired(status, true);
+ }
+ catch (InterruptedException e) {
+ throw new RuntimeInterruptedException(e);
+ }
+ try {
+ return computation.compute();
+ }
+ finally {
+ setReadLockAcquired(status, false);
+ myLock.readLock().unlock();
}
}
@Override
public <T, E extends Throwable> T runReadAction(@NotNull ThrowableComputable<T, E> computation) throws E {
- if (isReadAccessAllowed()) {
+ Status status = getStatus();
+ if (isReadAccessAllowed(status)) {
return computation.compute();
}
- else {
- assertReadActionAllowed();
- try {
- myLock.readLock().lockInterruptibly();
- }
- catch (InterruptedException e) {
- throw new RuntimeInterruptedException(e);
- }
- try {
- return computation.compute();
- }
- finally {
- myLock.readLock().unlock();
- }
+ assertNoPsiLock();
+ try {
+ myLock.readLock().lockInterruptibly();
+ setReadLockAcquired(status, true);
+ }
+ catch (InterruptedException e) {
+ throw new RuntimeInterruptedException(e);
+ }
+ try {
+ return computation.compute();
+ }
+ finally {
+ setReadLockAcquired(status, false);
+ myLock.readLock().unlock();
}
}
- private static final ThreadLocal<Boolean> exceptionalThreadWithReadAccessFlag = new ThreadLocal<Boolean>();
-
- private static boolean isExceptionalThreadWithReadAccess() {
- Boolean flag = exceptionalThreadWithReadAccessFlag.get();
- return flag == Boolean.TRUE;
+ private static boolean isExceptionalThreadWithReadAccess(Status status) {
+ return BitUtil.isSet(status.flags, IS_EXCEPTIONAL_THREAD_FLAG);
}
- public static boolean setExceptionalThreadWithReadAccessFlag(boolean flag) {
- boolean old = isExceptionalThreadWithReadAccess();
- if (flag) {
- exceptionalThreadWithReadAccessFlag.set(Boolean.TRUE);
- }
- else {
- exceptionalThreadWithReadAccessFlag.remove();
- }
- return old;
+ public static void setExceptionalThreadWithReadAccessFlag(boolean flag) {
+ Status status = getStatus();
+ assert !isDispatchThread(status) : "exceptional thread must not be EDT";
+ assert flag != isReadAccessAllowed(status) : "must not start exceptional thread from inside read action";
+ status.flags = BitUtil.set(status.flags, IS_EXCEPTIONAL_THREAD_FLAG, flag);
}
@Override
@@ -1012,7 +1038,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public boolean hasWriteAction(@Nullable Class<?> actionClass) {
- assertCanRunWriteAction();
+ assertCanRunWriteAction(getStatus());
for (int i = myWriteActionsStack.size() - 1; i >= 0; i--) {
Class action = myWriteActionsStack.get(i);
@@ -1023,12 +1049,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public void assertReadAccessAllowed() {
- if (myHeadlessMode) return;
if (!isReadAccessAllowed()) {
LOG.error(
"Read access is allowed from event dispatch thread or inside read-action only" +
" (see com.intellij.openapi.application.Application.runReadAction())",
- "Current thread: " + describe(Thread.currentThread()), "Our dispatch thread:" + describe(ourDispatchThread),
+ "Current thread: " + describe(Thread.currentThread()), "; dispatch thread: " + EventQueue.isDispatchThread() +"; isDispatchThread(): "+isDispatchThread(),
"SystemEventQueueThread: " + describe(getEventQueueThread()));
}
}
@@ -1039,7 +1064,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
return o + " " + System.identityHashCode(o);
}
- @Nullable
private static Thread getEventQueueThread() {
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
try {
@@ -1047,63 +1071,63 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
method.setAccessible(true);
return (Thread)method.invoke(eventQueue);
}
- catch (Exception e1) {
- // ok
+ catch (Exception e) {
+ throw new RuntimeException(e);
}
- return null;
}
@Override
public boolean isReadAccessAllowed() {
- Thread currentThread = Thread.currentThread();
- return ourDispatchThread == currentThread ||
- isExceptionalThreadWithReadAccess() ||
- holdsReadLock() ||
- isDispatchThread();
+ return isReadAccessAllowed(getStatus());
}
- private static void assertCanRunWriteAction() {
- assertIsDispatchThread("Write access is allowed from event dispatch thread only");
+ private static boolean isReadAccessAllowed(Status status) {
+ return (status.flags & (IS_EDT_FLAG | IS_EXCEPTIONAL_THREAD_FLAG | IS_READ_LOCK_ACQUIRED_FLAG)) != 0;
+ }
+
+ private static void assertCanRunWriteAction(Status status) {
+ assertIsDispatchThread(status, "Write access is allowed from event dispatch thread only");
}
@Override
public void assertIsDispatchThread() {
- if (ShutDownTracker.isShutdownHookRunning()) return;
- Integer safeCounter = ourEdtSafe.get();
- if (safeCounter != null && safeCounter > 0) return;
- assertIsDispatchThread("Access is allowed from event dispatch thread only.");
+ assertIsDispatchThread(getStatus());
}
- private static void assertIsDispatchThread(@NotNull String message) {
- final Thread currentThread = Thread.currentThread();
- if (ourDispatchThread == currentThread) return;
-
- if (EventQueue.isDispatchThread()) {
- ourDispatchThread = currentThread;
+ private static void assertIsDispatchThread(Status status) {
+ if (isDispatchThread(status)) return;
+ if (ShutDownTracker.isShutdownHookRunning()) return;
+ int safeCounter = getSafeCounter(status);
+ if (safeCounter == 0) {
+ assertIsDispatchThread(status, "Access is allowed from event dispatch thread only.");
}
- if (ourDispatchThread == currentThread) return;
+ }
+ private static int getSafeCounter(Status status) {
+ return status.flags & 0x1fffffff;
+ }
+
+ private static void assertIsDispatchThread(Status status, @NotNull String message) {
+ if (isDispatchThread(status)) return;
LOG.error(message,
+ "EventQueue.isDispatchThread()="+EventQueue.isDispatchThread(),
+ "isDispatchThread()="+isDispatchThread(getStatus()),
+ "Toolkit.getEventQueue()="+Toolkit.getDefaultToolkit().getSystemEventQueue(),
"Current thread: " + describe(Thread.currentThread()),
- "Our dispatch thread:" + describe(ourDispatchThread),
- "SystemEventQueueThread: " + describe(getEventQueueThread()));
+ "SystemEventQueueThread: " + describe(getEventQueueThread()) +"\n"+ ThreadDumper.dumpThreadsToString()+"\n-----------");
}
@Override
public void runEdtSafeAction(@NotNull Runnable runnable) {
- Integer value = ourEdtSafe.get();
- if (value == null) {
- value = 0;
- }
-
- ourEdtSafe.set(value + 1);
+ Status status = getStatus();
+ LOG.assertTrue(getSafeCounter(status) < 1<<26);
+ status.flags++;
try {
runnable.run();
}
finally {
- int newValue = ourEdtSafe.get() - 1;
- ourEdtSafe.set(newValue >= 1 ? newValue : null);
+ status.flags--;
}
}
@@ -1111,19 +1135,19 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
public void assertIsDispatchThread(@Nullable final JComponent component) {
if (component == null) return;
- Thread curThread = Thread.currentThread();
- if (ourDispatchThread == curThread) {
+ Status status = getStatus();
+ if (isDispatchThread(status)) {
return;
}
if (Boolean.TRUE.equals(component.getClientProperty(WAS_EVER_SHOWN))) {
- assertIsDispatchThread();
+ assertIsDispatchThread(status);
}
else {
final JRootPane root = component.getRootPane();
if (root != null) {
component.putClientProperty(WAS_EVER_SHOWN, Boolean.TRUE);
- assertIsDispatchThread();
+ assertIsDispatchThread(status);
}
}
}
@@ -1136,14 +1160,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public boolean tryRunReadAction(@NotNull Runnable action) {
- //if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
- boolean mustAcquire = !isReadAccessAllowed();
+ Status status = getStatus();
+ //if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
+ boolean mustAcquire = !isReadAccessAllowed(status);
if (mustAcquire) {
- LOG.assertTrue(myTestModeFlag || !Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
+ assertNoPsiLock();
try {
// timed version of tryLock() respects fairness unlike the no-args method
if (!myLock.readLock().tryLock(0, TimeUnit.MILLISECONDS)) return false;
+ setReadLockAcquired(status, true);
}
catch (InterruptedException e) {
throw new RuntimeInterruptedException(e);
@@ -1155,6 +1181,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
finally {
if (mustAcquire) {
+ setReadLockAcquired(status, false);
myLock.readLock().unlock();
}
}
@@ -1167,7 +1194,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
if (frame instanceof IdeFrame) {
final IdeFrame ideFrame = (IdeFrame)frame;
if (isActive() != active) {
- myActive = Boolean.valueOf(active);
+ myActive = active;
System.setProperty("idea.active", myActive.toString());
ApplicationActivationListener publisher = getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC);
if (active) {
@@ -1198,10 +1225,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@NotNull
@Override
public AccessToken acquireReadActionLock() {
+ Status status = getStatus();
// if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
- if (isReadAccessAllowed()) return AccessToken.EMPTY_ACCESS_TOKEN;
+ if (isReadAccessAllowed(status)) return AccessToken.EMPTY_ACCESS_TOKEN;
- return new ReadAccessToken();
+ return new ReadAccessToken(status);
}
@NotNull
@@ -1215,13 +1243,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
public WriteAccessToken(Class _clazz) {
clazz = _clazz;
- assertCanRunWriteAction();
+ assertCanRunWriteAction(getStatus());
ActivityTracker.getInstance().inc();
fireBeforeWriteActionStart(_clazz);
final AtomicBoolean stopped = new AtomicBoolean(false);
- LOG.assertTrue(isWriteAccessAllowed() || !Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing writeAction");
+ if (!isWriteAccessAllowed()) {
+ assertNoPsiLock();
+ }
+
try {
if (!myLock.writeLock().tryLock()) {
if (ourDumpThreadsOnLongWriteActionWaiting > 0) {
@@ -1304,10 +1335,14 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
private class ReadAccessToken extends AccessToken {
- private ReadAccessToken() {
- assertReadActionAllowed();
+ private final Status myStatus;
+
+ private ReadAccessToken(Status status) {
+ myStatus = status;
+ assertNoPsiLock();
try {
myLock.readLock().lockInterruptibly();
+ setReadLockAcquired(myStatus, true);
acquired();
}
catch (InterruptedException e) {
@@ -1317,13 +1352,18 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public void finish() {
+ setReadLockAcquired(myStatus, false);
myLock.readLock().unlock();
released();
}
}
- private static void assertReadActionAllowed() {
- LOG.assertTrue(!Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
+ private final boolean myExtraChecks = isUnitTestMode();
+
+ private void assertNoPsiLock() {
+ if (myExtraChecks) {
+ LOG.assertTrue(!Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
+ }
}
@Override
@@ -1334,12 +1374,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
@Override
public boolean isWriteAccessAllowed() {
- return myLock.writeLock().isHeldByCurrentThread();
+ return myLock.isWriteLockedByCurrentThread();
}
@Override
public boolean isWriteActionInProgress() {
- return myLock.writeLock().getHoldCount() != 0;
+ return myLock.getWriteHoldCount() != 0;
}
public void editorPaintStart() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java
index c76ee8cd25d2..67416f98f470 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,149 +15,19 @@
*/
package com.intellij.openapi.command.impl;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.*;
+import com.intellij.openapi.command.AbnormalCommandTerminationException;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.EmptyRunnable;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-import java.util.Stack;
-
-public class CommandProcessorImpl extends CommandProcessorEx {
- private static class CommandDescriptor {
- public final Runnable myCommand;
- public final Project myProject;
- public String myName;
- public Object myGroupId;
- public final Document myDocument;
- public final UndoConfirmationPolicy myUndoConfirmationPolicy;
-
- public CommandDescriptor(Runnable command,
- Project project,
- String name,
- Object groupId,
- UndoConfirmationPolicy undoConfirmationPolicy,
- Document document) {
- myCommand = command;
- myProject = project;
- myName = name;
- myGroupId = groupId;
- myUndoConfirmationPolicy = undoConfirmationPolicy;
- myDocument = document;
- }
-
- @Override
- public String toString() {
- return "'" + myName + "', group: '" + myGroupId + "'";
- }
- }
-
- private CommandDescriptor myCurrentCommand = null;
- private final Stack<CommandDescriptor> myInterruptedCommands = new Stack<CommandDescriptor>();
-
-// private HashMap myStatisticsMap = new HashMap(); // command name --> count
-
- // private HashMap myStatisticsMap = new HashMap(); // command name --> count
-
- private final List<CommandListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
-
- private int myUndoTransparentCount = 0;
-
- @Override
- public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) {
- executeCommand(null, runnable, name, groupId);
- }
-
- @Override
- public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) {
- executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT);
- }
-
- @Override
- public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) {
- executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document);
- }
-
- @Override
- public void executeCommand(Project project,
- @NotNull final Runnable command,
- final String name,
- final Object groupId,
- @NotNull UndoConfirmationPolicy confirmationPolicy) {
- executeCommand(project, command, name, groupId, confirmationPolicy, null);
- }
-
- @Override
- public void executeCommand(Project project,
- @NotNull final Runnable command,
- final String name,
- final Object groupId,
- @NotNull UndoConfirmationPolicy confirmationPolicy,
- Document document) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- if (project != null && project.isDisposed()) return;
-
- if (CommandLog.LOG.isDebugEnabled()) {
- CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId);
- }
-
- if (myCurrentCommand != null) {
- command.run();
- return;
- }
- Throwable throwable = null;
- try {
- myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document);
- fireCommandStarted();
- command.run();
- }
- catch (Throwable th) {
- throwable = th;
- }
- finally {
- finishCommand(project, myCurrentCommand, throwable);
- }
- }
-
- @Override
- @Nullable
- public Object startCommand(final Project project,
- @Nls final String name,
- final Object groupId,
- final UndoConfirmationPolicy undoConfirmationPolicy) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- if (project != null && project.isDisposed()) return null;
-
- if (CommandLog.LOG.isDebugEnabled()) {
- CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId);
- }
-
- if (myCurrentCommand != null) {
- return null;
- }
-
- Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null;
- myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document);
- fireCommandStarted();
- return myCurrentCommand;
- }
+class CommandProcessorImpl extends CoreCommandProcessor {
@Override
public void finishCommand(final Project project, final Object command, final Throwable throwable) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress");
if (myCurrentCommand != command) return;
final boolean failed;
try {
@@ -181,7 +51,7 @@ public class CommandProcessorImpl extends CommandProcessorEx {
}
}
finally {
- fireCommandFinished();
+ super.finishCommand(project, command, throwable);
}
if (failed) {
if (project != null) {
@@ -195,150 +65,6 @@ public class CommandProcessorImpl extends CommandProcessorEx {
}
}
- private void fireCommandFinished() {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandDescriptor currentCommand = myCurrentCommand;
- CommandEvent event = new CommandEvent(this, currentCommand.myCommand,
- currentCommand.myName,
- currentCommand.myGroupId,
- currentCommand.myProject,
- currentCommand.myUndoConfirmationPolicy,
- currentCommand.myDocument);
- try {
- for (CommandListener listener : myListeners) {
- try {
- listener.beforeCommandFinished(event);
- }
- catch (Throwable e) {
- CommandLog.LOG.error(e);
- }
- }
- }
- finally {
- myCurrentCommand = null;
- for (CommandListener listener : myListeners) {
- try {
- listener.commandFinished(event);
- }
- catch (Throwable e) {
- CommandLog.LOG.error(e);
- }
- }
- }
- }
-
- @Override
- public void enterModal() {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandDescriptor currentCommand = myCurrentCommand;
- myInterruptedCommands.push(currentCommand);
- if (currentCommand != null) {
- fireCommandFinished();
- }
- }
-
- @Override
- public void leaveModal() {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand));
-
- myCurrentCommand = myInterruptedCommands.pop();
- if (myCurrentCommand != null) {
- fireCommandStarted();
- }
- }
-
- @Override
- public void setCurrentCommandName(String name) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandDescriptor currentCommand = myCurrentCommand;
- CommandLog.LOG.assertTrue(currentCommand != null);
- currentCommand.myName = name;
- }
-
- @Override
- public void setCurrentCommandGroupId(Object groupId) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandDescriptor currentCommand = myCurrentCommand;
- CommandLog.LOG.assertTrue(currentCommand != null);
- currentCommand.myGroupId = groupId;
- }
-
- @Override
- @Nullable
- public Runnable getCurrentCommand() {
- CommandDescriptor currentCommand = myCurrentCommand;
- return currentCommand != null ? currentCommand.myCommand : null;
- }
-
- @Override
- @Nullable
- public String getCurrentCommandName() {
- CommandDescriptor currentCommand = myCurrentCommand;
- if (currentCommand != null) return currentCommand.myName;
- if (!myInterruptedCommands.isEmpty()) {
- final CommandDescriptor command = myInterruptedCommands.peek();
- return command != null ? command.myName : null;
- }
- return null;
- }
-
- @Override
- @Nullable
- public Object getCurrentCommandGroupId() {
- CommandDescriptor currentCommand = myCurrentCommand;
- if (currentCommand != null) return currentCommand.myGroupId;
- if (!myInterruptedCommands.isEmpty()) {
- final CommandDescriptor command = myInterruptedCommands.peek();
- return command != null ? command.myGroupId : null;
- }
- return null;
- }
-
- @Override
- @Nullable
- public Project getCurrentCommandProject() {
- CommandDescriptor currentCommand = myCurrentCommand;
- return currentCommand != null ? currentCommand.myProject : null;
- }
-
- @Override
- public void addCommandListener(@NotNull CommandListener listener) {
- myListeners.add(listener);
- }
-
- @Override
- public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) {
- addCommandListener(listener);
- Disposer.register(parentDisposable, new Disposable() {
- @Override
- public void dispose() {
- removeCommandListener(listener);
- }
- });
- }
-
- @Override
- public void removeCommandListener(@NotNull CommandListener listener) {
- myListeners.remove(listener);
- }
-
- @Override
- public void runUndoTransparentAction(@NotNull Runnable action) {
- if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted();
- try {
- action.run();
- }
- finally {
- if (--myUndoTransparentCount == 0) fireUndoTransparentFinished();
- }
- }
-
- @Override
- public boolean isUndoTransparentActionInProgress() {
- return myUndoTransparentCount > 0;
- }
-
@Override
public void markCurrentCommandAsGlobal(Project project) {
getUndoManager(project).markCurrentCommandAsGlobal();
@@ -357,46 +83,4 @@ public class CommandProcessorImpl extends CommandProcessorEx {
public void addAffectedFiles(Project project, @NotNull VirtualFile... files) {
getUndoManager(project).addAffectedFiles(files);
}
-
- private void fireCommandStarted() {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CommandDescriptor currentCommand = myCurrentCommand;
- CommandEvent event = new CommandEvent(this,
- currentCommand.myCommand,
- currentCommand.myName,
- currentCommand.myGroupId,
- currentCommand.myProject,
- currentCommand.myUndoConfirmationPolicy,
- currentCommand.myDocument);
- for (CommandListener listener : myListeners) {
- try {
- listener.commandStarted(event);
- }
- catch (Throwable e) {
- CommandLog.LOG.error(e);
- }
- }
- }
-
- private void fireUndoTransparentStarted() {
- for (CommandListener listener : myListeners) {
- try {
- listener.undoTransparentActionStarted();
- }
- catch (Throwable e) {
- CommandLog.LOG.error(e);
- }
- }
- }
-
- private void fireUndoTransparentFinished() {
- for (CommandListener listener : myListeners) {
- try {
- listener.undoTransparentActionFinished();
- }
- catch (Throwable e) {
- CommandLog.LOG.error(e);
- }
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
index 22ecc747e70e..1d1fa59530f0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
@@ -27,11 +27,14 @@ import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.reference.SoftReference;
import com.intellij.util.containers.WeakKeyWeakValueHashMap;
import com.intellij.util.containers.WeakValueHashMap;
import com.intellij.util.io.fs.FilePath;
import org.jetbrains.annotations.NotNull;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -40,7 +43,8 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
private static final Key<List<VirtualFile>> DELETED_FILES = Key.create(DocumentReferenceManagerImpl.class.getName() + ".DELETED_FILES");
private final Map<Document, DocumentReference> myDocToRef = new WeakKeyWeakValueHashMap<Document, DocumentReference>();
- private final Map<VirtualFile, DocumentReference> myFileToRef = new WeakKeyWeakValueHashMap<VirtualFile, DocumentReference>();
+
+ private static final Key<Reference<DocumentReference>> FILE_TO_REF_KEY = Key.create("FILE_TO_REF_KEY");
private final Map<FilePath, DocumentReference> myDeletedFilePathToRef = new WeakValueHashMap<FilePath, DocumentReference>();
@Override
@@ -57,7 +61,7 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
VirtualFile f = event.getFile();
DocumentReference ref = myDeletedFilePathToRef.remove(new FilePath(f.getUrl()));
if (ref != null) {
- myFileToRef.put(f, ref);
+ f.putUserData(FILE_TO_REF_KEY, new WeakReference<DocumentReference>(ref));
((DocumentReferenceByVirtualFile)ref).update(f);
}
}
@@ -76,7 +80,8 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
assert files != null : f;
for (VirtualFile each : files) {
- DocumentReference ref = myFileToRef.remove(each);
+ DocumentReference ref = SoftReference.dereference(each.getUserData(FILE_TO_REF_KEY));
+ each.putUserData(FILE_TO_REF_KEY, null);
if (ref != null) {
myDeletedFilePathToRef.put(new FilePath(each.getUrl()), ref);
}
@@ -128,10 +133,10 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
assertInDispatchThread();
assert file.isValid() : "file is invalid: " + file;
- DocumentReference result = myFileToRef.get(file);
+ DocumentReference result = SoftReference.dereference(file.getUserData(FILE_TO_REF_KEY));
if (result == null) {
result = new DocumentReferenceByVirtualFile(file);
- myFileToRef.put(file, result);
+ file.putUserData(FILE_TO_REF_KEY, new WeakReference<DocumentReference>(result));
}
return result;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java
index 641208bf4477..0b302d11f9c1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java
@@ -190,5 +190,10 @@ public class ServiceManagerImpl implements BaseComponent {
public String getAssignableToClassName() {
return myDescriptor.getInterface();
}
+
+ @Override
+ public String toString() {
+ return "ServiceComponentAdapter[" + myDescriptor.getInterface() + "]: implementation=" + myDescriptor.getImplementation() + ", plugin=" + myPluginDescriptor;
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
index 42a24c490db2..923072d4fb1d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
@@ -51,39 +52,31 @@ import java.util.List;
public class FileBasedStorage extends XmlElementStorage {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage");
+ private static boolean ourConfigDirectoryRefreshed = false;
+
private final String myFilePath;
private final IFile myFile;
- protected final String myRootElementName;
-
- private static boolean myConfigDirectoryRefreshed = false;
+ private final String myRootElementName;
private volatile VirtualFile myCachedVirtualFile;
public FileBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroManager,
StreamProvider streamProvider,
- final String filePath,
- final String fileSpec,
+ String filePath,
+ String fileSpec,
String rootElementName,
@NotNull Disposable parentDisposable,
PicoContainer picoContainer,
- ComponentRoamingManager componentRoamingManager, ComponentVersionProvider localComponentVersionProvider) {
- super(pathMacroManager, parentDisposable, rootElementName, streamProvider, fileSpec, componentRoamingManager, localComponentVersionProvider);
- Application app = ApplicationManager.getApplication();
+ ComponentRoamingManager componentRoamingManager,
+ ComponentVersionProvider componentVersionProvider) {
+ super(pathMacroManager, parentDisposable, rootElementName, streamProvider, fileSpec, componentRoamingManager, componentVersionProvider);
- if (!myConfigDirectoryRefreshed && (app.isUnitTestMode() || app.isDispatchThread())) {
- try {
- syncRefreshPathRecursively(PathManager.getConfigPath(), "componentVersions");
- }
- finally {
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- myConfigDirectoryRefreshed = true;
- }
- }
+ refreshConfigDirectoryOnce();
myRootElementName = rootElementName;
myFilePath = filePath;
myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath);
- VirtualFileTracker virtualFileTracker = (VirtualFileTracker)picoContainer.getComponentInstanceOfType(VirtualFileTracker.class);
+ VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class);
MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class);
if (virtualFileTracker != null && messageBus != null) {
final String path = myFile.getAbsolutePath();
@@ -111,21 +104,25 @@ public class FileBasedStorage extends XmlElementStorage {
}
}
- private static void syncRefreshPathRecursively(@NotNull String configDirectoryPath, @Nullable final String excludeDir) {
- VirtualFile configDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(configDirectoryPath);
- if (configDir != null) {
- requestAllChildren(configDir, excludeDir);
- VfsUtil.markDirtyAndRefresh(false, true, false, configDir);
- }
- }
-
- private static void requestAllChildren(final VirtualFile configDir, @Nullable final String excludeDir) {
- VfsUtilCore.visitChildrenRecursively(configDir, new VirtualFileVisitor() {
- @Override
- public boolean visitFile(@NotNull VirtualFile file) {
- return excludeDir == null || !excludeDir.equals(file.getName());
+ private static void refreshConfigDirectoryOnce() {
+ Application app = ApplicationManager.getApplication();
+ if (!ourConfigDirectoryRefreshed && (app.isUnitTestMode() || app.isDispatchThread())) {
+ try {
+ VirtualFile configDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManager.getConfigPath());
+ if (configDir != null) {
+ VfsUtilCore.visitChildrenRecursively(configDir, new VirtualFileVisitor() {
+ @Override
+ public boolean visitFile(@NotNull VirtualFile file) {
+ return !"componentVersions".equals(file.getName());
+ }
+ });
+ VfsUtil.markDirtyAndRefresh(false, true, false, configDir);
+ }
+ }
+ finally {
+ ourConfigDirectoryRefreshed = true;
}
- });
+ }
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
index 650419f6381a..b028676168d5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 @@ import gnu.trove.TObjectLongHashMap;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.filter.ElementFilter;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,7 +40,7 @@ import java.util.*;
public abstract class XmlElementStorage implements StateStorage, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.XmlElementStorage");
- @NonNls private static final String ATTR_NAME = "name";
+ private static final String ATTR_NAME = "name";
private static final String VERSION_FILE_SUFFIX = ".ver";
protected TrackingPathMacroSubstitutor myPathMacroSubstitutor;
@@ -56,7 +55,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
protected int myProviderUpToDateHash = -1;
private boolean mySavingDisabled = false;
- private final Map<String, Object> myStorageComponentStates = new THashMap<String, Object>(); // at loading we store Element, on setState Integer of hash// at loading we store Element, on setState Integer of hash
+ private final Map<String, Object> myStorageComponentStates = new THashMap<String, Object>(); // at load we store Element, on setState Integer of hash
private final ComponentVersionProvider myLocalVersionProvider;
protected final RemoteComponentVersionProvider myRemoteVersionProvider;
@@ -75,7 +74,8 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
@NotNull String rootElementName,
@Nullable StreamProvider streamProvider,
String fileSpec,
- ComponentRoamingManager componentRoamingManager, ComponentVersionProvider localComponentVersionsProvider) {
+ ComponentRoamingManager componentRoamingManager,
+ ComponentVersionProvider componentVersionProvider) {
myPathMacroSubstitutor = pathMacroSubstitutor;
myRootElementName = rootElementName;
myStreamProvider = streamProvider;
@@ -83,7 +83,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
myComponentRoamingManager = componentRoamingManager;
Disposer.register(parentDisposable, this);
- myLocalVersionProvider = localComponentVersionsProvider;
+ myLocalVersionProvider = componentVersionProvider;
myRemoteVersionProvider = streamProvider == null || !streamProvider.isVersioningRequired() ? null : new RemoteComponentVersionProvider();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
index 19b1493c5cb5..5f169146145c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
@@ -142,6 +142,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
private final DiffTool myParentTool;
private EditorNotificationPanel myTopMessageDiffPanel;
private final VisibleAreaListener myVisibleAreaListener;
+ private final int myDiffDividerPolygonsOffset;
public DiffPanelImpl(final Window owner,
Project project,
@@ -164,6 +165,8 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
myLeftSide.becomeMaster();
myDiffUpdater = new Rediffers(this);
+ myDiffDividerPolygonsOffset = diffDividerPolygonsOffset;
+
myData = createDiffPanelState(this);
if (horizontal) {
@@ -220,7 +223,11 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
protected DiffPanelState createDiffPanelState(@NotNull Disposable parentDisposable) {
- return new DiffPanelState(this, myProject, parentDisposable);
+ return new DiffPanelState(this, myProject, getDiffDividerPolygonsOffset(), parentDisposable);
+ }
+
+ public int getDiffDividerPolygonsOffset() {
+ return myDiffDividerPolygonsOffset;
}
public boolean isHorisontal() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java
index 9e4411120361..33245989c5b3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffPanelState.java
@@ -21,15 +21,20 @@ import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.impl.ContentChangeListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
public class DiffPanelState extends SimpleDiffPanelState {
- public DiffPanelState(ContentChangeListener changeListener, Project project, @NotNull Disposable parentDisposable) {
- super(project,changeListener, parentDisposable);
+ protected final int myDiffDividerPolygonsOffset;
+
+ public DiffPanelState(ContentChangeListener changeListener,
+ Project project,
+ int diffDividerPolygonsOffset,
+ @NotNull Disposable parentDisposable) {
+ super(project, changeListener, parentDisposable);
+ myDiffDividerPolygonsOffset = diffDividerPolygonsOffset;
}
public void setContents(final DiffContent content1, final DiffContent content2) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java
index 14cc9fa604b7..b179b7d4dd0a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java
@@ -88,11 +88,10 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
drawCurved(gr, 0, r.y, TornLineParams.ourLight, points, width + editorWidth, true,width);
int j = points.size() - 1;
- final int finalX = width + editorWidth + width;
+ final int finalX = width + editorWidth;
for (; j > 0; j--) {
if (points.get(j).getFirst() >= finalX) break;
}
- j = j == 0 ? 0 : j - 1;
myOffsetsConsumer.consume(points.get(j).getSecond());
} else {
@@ -101,8 +100,7 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
gr.setColor(getColor().darker());
drawCurved(gr, 0, r.y, TornLineParams.ourLight, points, 0, false,0);
- int i = getLastPointInBeforeGutter(width, points);
- myOffsetsConsumer.consume(points.get(i).getSecond());
+ myOffsetsConsumer.consume(points.get(0).getSecond());
}
} finally {
gr.dispose();
@@ -142,8 +140,7 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
private int getLastPointInBeforeGutter(int width, List<Couple<Integer>> points) {
int i = 0;
for (; i < points.size(); i++) {
- Couple<Integer> integerIntegerPair = points.get(i);
- if (integerIntegerPair.getFirst() >= width) break;
+ if (points.get(i).getFirst() >= width) break;
}
i = i == 0 ? 0 : i - 1;
return i;
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java
index 3efb946fc0e1..2ceffb5651c5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentedDiffPanelState.java
@@ -52,8 +52,12 @@ public class FragmentedDiffPanelState extends DiffPanelState {
private final NumberedFragmentHighlighter myFragmentHighlighter;
private FragmentSeparatorsPositionConsumer mySeparatorsPositionConsumer;
- public FragmentedDiffPanelState(ContentChangeListener changeListener, Project project, boolean drawNumber, @NotNull Disposable parentDisposable) {
- super(changeListener, project, parentDisposable);
+ public FragmentedDiffPanelState(ContentChangeListener changeListener,
+ Project project,
+ int diffDividerPolygonsOffset,
+ boolean drawNumber,
+ @NotNull Disposable parentDisposable) {
+ super(changeListener, project, diffDividerPolygonsOffset, parentDisposable);
myFragmentHighlighter = new NumberedFragmentHighlighter(myAppender1, myAppender2, drawNumber);
mySeparatorsPositionConsumer = new FragmentSeparatorsPositionConsumer();
}
@@ -68,7 +72,7 @@ public class FragmentedDiffPanelState extends DiffPanelState {
private LineBlocks addMarkup(final List<LineFragment> lines) {
myFragmentHighlighter.precalculateNumbers(lines);
- for (Iterator<LineFragment> iterator = lines.iterator(); iterator.hasNext();) {
+ for (Iterator<LineFragment> iterator = lines.iterator(); iterator.hasNext(); ) {
LineFragment line = iterator.next();
myFragmentHighlighter.setIsLast(!iterator.hasNext());
line.highlight(myFragmentHighlighter);
@@ -106,8 +110,9 @@ public class FragmentedDiffPanelState extends DiffPanelState {
for (int i = 0; i < myRanges.size(); i++) {
final BeforeAfter<Integer> start = lineStarts(i);
final BeforeAfter<Integer> end = i == myRanges.size() - 1 ?
- new BeforeAfter<Integer>(myAppender1.getDocument().getTextLength(), myAppender2.getDocument().getTextLength()) :
- lineStarts(i + 1);
+ new BeforeAfter<Integer>(myAppender1.getDocument().getTextLength(),
+ myAppender2.getDocument().getTextLength()) :
+ lineStarts(i + 1);
ranges.add(new BeforeAfter<TextRange>(new TextRange(start.getBefore(), end.getBefore()),
new TextRange(start.getAfter(), end.getAfter())));
@@ -145,19 +150,19 @@ public class FragmentedDiffPanelState extends DiffPanelState {
private BeforeAfter<Integer> lineStarts(int i) {
return new BeforeAfter<Integer>(myAppender1.getDocument().getLineStartOffset(myRanges.get(i).getBefore()),
- myAppender2.getDocument().getLineStartOffset(myRanges.get(i).getAfter()));
+ myAppender2.getDocument().getLineStartOffset(myRanges.get(i).getAfter()));
}
public void setRanges(List<BeforeAfter<Integer>> ranges) {
myRanges = new ArrayList<BeforeAfter<Integer>>();
- if (! ranges.isEmpty()) {
+ if (!ranges.isEmpty()) {
if (ranges.get(0).getAfter() != 0 && ranges.get(0).getBefore() != 0) {
- myRanges.add(new BeforeAfter<Integer>(0,0));
+ myRanges.add(new BeforeAfter<Integer>(0, 0));
}
}
myRanges.addAll(ranges);
}
-
+
public List<Integer> getLeftLines() {
return myFragmentHighlighter.getLeftLines();
}
@@ -188,38 +193,78 @@ public class FragmentedDiffPanelState extends DiffPanelState {
final Graphics g = gr.create();
try {
- ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Map.Entry<Integer, FragmentSeparatorsPositionConsumer.TornSeparator> entry : left.entrySet()) {
final FragmentSeparatorsPositionConsumer.TornSeparator tornSeparator = entry.getValue();
if (tornSeparator.getLeftLine() >= startLeft || tornSeparator.getRightLine() >= startRight) {
final int leftOffset = tornSeparator.getLeftOffset();
- int leftBaseY = myAppender1.getEditor().logicalPositionToXY(new LogicalPosition(tornSeparator.getLeftLine(), 0)).y - lineHeight/2 -
- leftScrollOffset;
+ int leftBaseY =
+ myAppender1.getEditor().logicalPositionToXY(new LogicalPosition(tornSeparator.getLeftLine(), 0)).y - lineHeight / 2 -
+ leftScrollOffset + myDiffDividerPolygonsOffset;
final int rightOffset = tornSeparator.getRightOffset();
- int rightBaseY = myAppender2.getEditor().logicalPositionToXY(new LogicalPosition(tornSeparator.getRightLine(), 0)).y - lineHeight/2 -
- rightScrollOffset;
-
- g.setColor(FragmentBoundRenderer.darkerBorder());
- g.drawLine(0,leftBaseY + leftOffset + TornLineParams.ourDark - 1, width, rightBaseY + rightOffset + TornLineParams.ourDark + 1);
- g.drawLine(0,leftBaseY + leftOffset + TornLineParams.ourDark + 1, width, rightBaseY + rightOffset + TornLineParams.ourDark - 1);
- g.drawLine(0,leftBaseY + leftOffset - TornLineParams.ourDark - 1, width, rightBaseY + rightOffset - TornLineParams.ourDark + 1);
- g.drawLine(0,leftBaseY + leftOffset - TornLineParams.ourDark + 1, width, rightBaseY + rightOffset - TornLineParams.ourDark - 1);
-
- g.setColor(FragmentBoundRenderer.darkerBorder().darker());
- // +- 2
- g.drawLine(0,leftBaseY + leftOffset + TornLineParams.ourDark, width, rightBaseY + rightOffset + TornLineParams.ourDark);
- g.drawLine(0, leftBaseY + leftOffset - TornLineParams.ourDark, width, rightBaseY + rightOffset - TornLineParams.ourDark);
+ int rightBaseY =
+ myAppender2.getEditor().logicalPositionToXY(new LogicalPosition(tornSeparator.getRightLine(), 0)).y - lineHeight / 2 -
+ rightScrollOffset + myDiffDividerPolygonsOffset;
+
+ int x1 = 0;
+ int x2 = width;
+ int y1 = leftBaseY + leftOffset;
+ int y2 = rightBaseY + rightOffset;
+
+ if (Math.abs(x2 - x1) < Math.abs(y2 - y1)) {
+ int dx = TornLineParams.ourDark;
+ int dy = TornLineParams.ourLight;
+ if (y2 < y1) {
+ g.setColor(FragmentBoundRenderer.darkerBorder());
+ g.drawLine(x1 + dx, y1 - dy + TornLineParams.ourDark, x2, y2 + TornLineParams.ourDark);
+ g.drawLine(x1, y1 - TornLineParams.ourDark, x2 - dx, y2 + dy - TornLineParams.ourDark);
+
+ g.drawLine(x1, y1 + TornLineParams.ourDark, x1 + dx, y1 - dy + TornLineParams.ourDark);
+ g.drawLine(x2, y2 - TornLineParams.ourDark, x2 - dx, y2 + dy - TornLineParams.ourDark);
+
+ g.setColor(FragmentBoundRenderer.darkerBorder().darker());
+ g.drawLine(x1 + dx, y1 - dy + TornLineParams.ourLight, x2, y2 + TornLineParams.ourLight);
+ g.drawLine(x1, y1 - TornLineParams.ourLight, x2 - dx, y2 + dy - TornLineParams.ourLight);
+
+ g.drawLine(x1, y1 + TornLineParams.ourLight, x1 + dx, y1 - dy + TornLineParams.ourLight);
+ g.drawLine(x2, y2 - TornLineParams.ourLight, x2 - dx, y2 + dy - TornLineParams.ourLight);
+ } else {
+ g.setColor(FragmentBoundRenderer.darkerBorder());
+ g.drawLine(x1, y1 + TornLineParams.ourDark, x2 - dx, y2 - dy + TornLineParams.ourDark);
+ g.drawLine(x1 + dx, y1 + dy - TornLineParams.ourDark, x2, y2 - TornLineParams.ourDark);
+
+ g.drawLine(x2, y2 + TornLineParams.ourDark, x2 - dx, y2 - dy + TornLineParams.ourDark);
+ g.drawLine(x1, y1 - TornLineParams.ourDark, x1 + dx, y1 + dy - TornLineParams.ourDark);
+
+ g.setColor(FragmentBoundRenderer.darkerBorder().darker());
+ g.drawLine(x1, y1 + TornLineParams.ourLight, x2 - dx, y2 - dy + TornLineParams.ourLight);
+ g.drawLine(x1 + dx, y1 + dy - TornLineParams.ourLight, x2, y2 - TornLineParams.ourLight);
+
+ g.drawLine(x2, y2 + TornLineParams.ourLight, x2 - dx, y2 - dy + TornLineParams.ourLight);
+ g.drawLine(x1, y1 - TornLineParams.ourLight, x1 + dx, y1 + dy - TornLineParams.ourLight);
+ }
+
+ } else {
+ g.setColor(FragmentBoundRenderer.darkerBorder());
+ g.drawLine(x1, y1 + TornLineParams.ourDark, x2, y2 + TornLineParams.ourDark);
+ g.drawLine(x1, y1 - TornLineParams.ourDark, x2, y2 - TornLineParams.ourDark);
+
+ g.setColor(FragmentBoundRenderer.darkerBorder().darker());
+ g.drawLine(x1, y1 + TornLineParams.ourLight, x2, y2 + TornLineParams.ourLight);
+ g.drawLine(x1, y1 - TornLineParams.ourLight, x2, y2 - TornLineParams.ourLight);
+ }
}
}
- } finally {
+ }
+ finally {
g.dispose();
}
}
private int getStartVisibleLine(final Editor editor) {
int offset = editor.getScrollingModel().getVerticalScrollOffset();
- LogicalPosition logicalPosition = editor.xyToLogicalPosition(new Point(0, offset));
- return logicalPosition.line;
+ LogicalPosition logicalPosition = editor.xyToLogicalPosition(new Point(0, offset));
+ return logicalPosition.line;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java
index 4b5201e2c9ea..13d2cf7bb43e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java
@@ -28,7 +28,12 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.openapi.util.TextRange;
+
+import java.util.Collections;
+import java.util.List;
public class DeleteLineAction extends TextComponentEditorAction {
public DeleteLineAction() {
@@ -36,51 +41,70 @@ public class DeleteLineAction extends TextComponentEditorAction {
}
private static class Handler extends EditorWriteActionHandler {
- public Handler() {
- super(true);
- }
-
@Override
- public void executeWriteAction(Editor editor, DataContext dataContext) {
+ public void executeWriteAction(final Editor editor, Caret caret, DataContext dataContext) {
CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP);
CopyPasteManager.getInstance().stopKillRings();
- SelectionModel selectionModel = editor.getSelectionModel();
- Document document = editor.getDocument();
+ final Document document = editor.getDocument();
+
+ final List<Caret> carets = caret == null ? editor.getCaretModel().getAllCarets() : Collections.singletonList(caret);
+
+ editor.getCaretModel().runBatchCaretOperation(new Runnable() {
+ @Override
+ public void run() {
+ int[] caretColumns = new int[carets.size()];
+ int caretIndex = carets.size() - 1;
+ TextRange range = getRangeToDelete(editor, carets.get(caretIndex));
+
+ while (caretIndex >= 0) {
+ int currentCaretIndex = caretIndex;
+ TextRange currentRange = range;
+ // find carets with overlapping line ranges
+ while (--caretIndex >= 0) {
+ range = getRangeToDelete(editor, carets.get(caretIndex));
+ if (range.getEndOffset() < currentRange.getStartOffset()) {
+ break;
+ }
+ currentRange = new TextRange(range.getStartOffset(), currentRange.getEndOffset());
+ }
- if (selectionModel.hasSelection()) {
- int selectionStart = selectionModel.getSelectionStart();
- int selectionEnd = selectionModel.getSelectionEnd();
- selectionModel.removeSelection();
- int lineStartOffset = document.getLineStartOffset(document.getLineNumber(selectionStart));
- int nextLine = document.getLineNumber(selectionEnd);
- if (document.getLineStartOffset(nextLine) != selectionEnd) {
- // There is a possible case that selection ends at the line start, i.e. something like below ([...] denotes selected text,
- // '|' is a line start):
- // |line 1
- // |[line 2
- // |]line 3
- // We don't want to delete line 3 here. However, the situation below is different:
- // |line 1
- // |[line 2
- // |line] 3
- // Line 3 must be removed here.
- nextLine++;
+ for (int i = caretIndex + 1; i <= currentCaretIndex; i++) {
+ caretColumns[i] = carets.get(i).getVisualPosition().column;
+ }
+ int targetLine = editor.offsetToVisualPosition(currentRange.getStartOffset()).line;
+
+ document.deleteString(currentRange.getStartOffset(), currentRange.getEndOffset());
+
+ for (int i = caretIndex + 1; i <= currentCaretIndex; i++) {
+ carets.get(i).moveToVisualPosition(new VisualPosition(targetLine, caretColumns[i]));
+ }
+ }
}
- int nextLineStartOffset = nextLine == document.getLineCount()
- ? document.getTextLength()
- : Math.min(document.getTextLength(), document.getLineStartOffset(nextLine));
- document.deleteString(lineStartOffset, nextLineStartOffset);
- return;
- }
- VisualPosition position = editor.getCaretModel().getVisualPosition();
- selectionModel.selectLineAtCaret();
- boolean removeLastSymbol = selectionModel.getSelectionEnd() == document.getTextLength() && document.getLineCount() > 1;
- EditorModificationUtil.deleteSelectedText(editor);
- if (removeLastSymbol) {
- document.deleteString(document.getTextLength() - 1, document.getTextLength());
- position = new VisualPosition(position.line - 1, position.column);
- }
- editor.getCaretModel().moveToVisualPosition(position);
+ });
+ }
+ }
+
+ private static TextRange getRangeToDelete(Editor editor, Caret caret) {
+ int selectionStart = caret.getSelectionStart();
+ int selectionEnd = caret.getSelectionEnd();
+ int startOffset = EditorUtil.getNotFoldedLineStartOffset(editor, selectionStart);
+ // There is a possible case that selection ends at the line start, i.e. something like below ([...] denotes selected text,
+ // '|' is a line start):
+ // |line 1
+ // |[line 2
+ // |]line 3
+ // We don't want to delete line 3 here. However, the situation below is different:
+ // |line 1
+ // |[line 2
+ // |line] 3
+ // Line 3 must be removed here.
+ int endOffset = EditorUtil.getNotFoldedLineEndOffset(editor, selectionEnd > 0 && selectionEnd != selectionStart ? selectionEnd - 1 : selectionEnd);
+ if (endOffset < editor.getDocument().getTextLength()) {
+ endOffset++;
+ }
+ else if (startOffset > 0) {
+ startOffset--;
}
+ return new TextRange(startOffset, endOffset);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java
index 788ff8e9271b..9a977ae6493f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EscapeAction.java
@@ -17,10 +17,7 @@
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.editor.Caret;
-import com.intellij.openapi.editor.CaretModel;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.ex.EditorEx;
@@ -44,8 +41,12 @@ public class EscapeAction extends EditorAction {
editorEx.setStickySelection(false);
}
}
+ boolean scrollNeeded = editor.getCaretModel().getCaretCount() > 1;
retainOldestCaret(editor.getCaretModel());
editor.getSelectionModel().removeSelection();
+ if (scrollNeeded) {
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
}
private static void retainOldestCaret(CaretModel caretModel) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java
index 182884b25020..be2628f6741c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftOrRightHandler.java
@@ -36,7 +36,7 @@ class MoveCaretLeftOrRightHandler extends EditorActionHandler {
}
@Override
- public void execute(Editor editor, DataContext dataContext) {
+ public void doExecute(Editor editor, Caret caret, DataContext dataContext) {
final SelectionModel selectionModel = editor.getSelectionModel();
final CaretModel caretModel = editor.getCaretModel();
ScrollingModel scrollingModel = editor.getScrollingModel();
@@ -62,12 +62,15 @@ class MoveCaretLeftOrRightHandler extends EditorActionHandler {
else {
caretModel.moveToOffset(myDirection == Direction.RIGHT ? end : start);
}
- scrollingModel.scrollToCaret(ScrollType.RELATIVE);
+ if (caret == editor.getCaretModel().getPrimaryCaret()) {
+ scrollingModel.scrollToCaret(ScrollType.RELATIVE);
+ }
return;
}
}
}
- final boolean scrollToCaret = !(editor instanceof EditorImpl) || ((EditorImpl)editor).isScrollToCaret();
+ final boolean scrollToCaret = (!(editor instanceof EditorImpl) || ((EditorImpl)editor).isScrollToCaret())
+ && caret == editor.getCaretModel().getPrimaryCaret();
caretModel.moveCaretRelatively(myDirection == Direction.RIGHT ? 1 : -1, 0, false, false, scrollToCaret);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java
index 1bdeaf548d6d..9a41b40d16db 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretLeftWithSelectionAction.java
@@ -25,6 +25,7 @@
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
@@ -40,9 +41,10 @@ public class MoveCaretLeftWithSelectionAction extends EditorAction {
}
@Override
- public void execute(Editor editor, DataContext dataContext) {
+ public void doExecute(Editor editor, Caret caret, DataContext dataContext) {
int columnShift = -1;
- editor.getCaretModel().moveCaretRelatively(columnShift, 0, true, editor.isColumnMode(), true);
+ editor.getCaretModel().moveCaretRelatively(columnShift, 0, true, editor.isColumnMode(),
+ caret == editor.getCaretModel().getPrimaryCaret());
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java
index 19d729fa7fe5..09150d6ae013 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretRightWithSelectionAction.java
@@ -25,6 +25,7 @@
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
@@ -40,8 +41,9 @@ public class MoveCaretRightWithSelectionAction extends EditorAction {
}
@Override
- public void execute(Editor editor, DataContext dataContext) {
- editor.getCaretModel().moveCaretRelatively(1, 0, true, editor.isColumnMode(), true);
+ public void doExecute(Editor editor, Caret caret, DataContext dataContext) {
+ editor.getCaretModel().moveCaretRelatively(1, 0, true, editor.isColumnMode(),
+ caret == editor.getCaretModel().getPrimaryCaret());
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java
index 0f4ba21a227f..590fe8b83b8c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java
@@ -73,6 +73,8 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
public boolean RENAME_VARIABLES_INPLACE = true;
public boolean PRESELECT_RENAME = true;
+ public boolean SHOW_INLINE_DIALOG = true;
+
public boolean REFRAIN_FROM_SCROLLING = false;
public boolean SHOW_REFORMAT_DIALOG = true;
@@ -522,4 +524,14 @@ public class EditorSettingsExternalizable implements NamedJDOMExternalizable, Ex
public void setPreselectRename(final boolean val) {
myOptions.PRESELECT_RENAME = val;
}
+
+ public boolean isShowInlineLocalDialog() {
+ return myOptions.SHOW_INLINE_DIALOG;
+ }
+
+ public void setShowInlineLocalDialog(final boolean val) {
+ myOptions.SHOW_INLINE_DIALOG = val;
+ }
+
+
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
index caadfc8ae744..216429557cea 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
@@ -488,8 +488,6 @@ public final class EditorUtil {
}
if (editor == null || useOptimization) {
- int shift = 0;
-
Document document = editor == null ? null : editor.getDocument();
if (document != null && start < offset-1 && document.getLineNumber(start) != document.getLineNumber(offset-1)) {
String editorInfo = editor instanceof EditorImpl ? ". Editor info: " + ((EditorImpl)editor).dumpState() : "";
@@ -504,6 +502,7 @@ public final class EditorUtil {
LOG, "detected incorrect offset -> column number calculation",
"start: " + start + ", given offset: " + offset+", given tab size: " + tabSize + ". "+documentInfo+ editorInfo);
}
+ int shift = 0;
if (hasTabs) {
for (int i = start; i < offset; i++) {
char c = text.charAt(i);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
index b0f5935da344..068f25e16565 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
@@ -45,6 +45,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
+import java.util.List;
public class CaretImpl extends UserDataHolderBase implements Caret {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.CaretImpl");
@@ -185,7 +186,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
final LogicalPosition logicalPosition = myEditor.offsetToLogicalPosition(offset);
CaretEvent event = moveToLogicalPosition(logicalPosition, locateBeforeSoftWrap, null, false);
final LogicalPosition positionByOffsetAfterMove = myEditor.offsetToLogicalPosition(myOffset);
- if (!myEditor.getCaretModel().myIgnoreWrongMoves && !positionByOffsetAfterMove.equals(logicalPosition)) {
+ if (!positionByOffsetAfterMove.equals(logicalPosition)) {
StringBuilder debugBuffer = new StringBuilder();
moveToLogicalPosition(logicalPosition, locateBeforeSoftWrap, debugBuffer, true);
int textStart = Math.max(0, Math.min(offset, myOffset) - 1);
@@ -436,7 +437,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
boolean fireListeners) {
assertIsDispatchThread();
if (debugBuffer != null) {
- debugBuffer.append("Start moveToLogicalPosition(). Locate before soft wrap: " + locateBeforeSoftWrap + ", position: " + pos + "\n");
+ debugBuffer.append("Start moveToLogicalPosition(). Locate before soft wrap: ").append(locateBeforeSoftWrap).append(", position: ")
+ .append(pos).append("\n");
}
myDesiredX = -1;
validateCallContext();
@@ -473,7 +475,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
else if (line > lineCount - 1) {
if (debugBuffer != null) {
- debugBuffer.append("Resetting target logical line (" + line + ") to " + (lineCount - 1) + " as it is greater than total document lines number\n");
+ debugBuffer.append("Resetting target logical line (").append(line).append(") to ").append(lineCount - 1)
+ .append(" as it is greater than total document lines number\n");
}
line = lineCount - 1;
softWrapLinesBefore = 0;
@@ -493,10 +496,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
softWrapColumns -= column - lineEndColumnNumber;
}
if (debugBuffer != null) {
- debugBuffer.append(
- "Resetting target logical column (" + oldColumn + ") to " + lineEndColumnNumber +
- " because caret is not allowed to be located after line end (offset: " +lineEndOffset + ", "
- + "logical position: " + endLinePosition+ "). Current soft wrap columns value: " + softWrapColumns+ "\n");
+ debugBuffer.append("Resetting target logical column (").append(oldColumn).append(") to ").append(lineEndColumnNumber)
+ .append(" because caret is not allowed to be located after line end (offset: ").append(lineEndOffset).append(", ")
+ .append("logical position: ").append(endLinePosition).append("). Current soft wrap columns value: ").append(softWrapColumns)
+ .append("\n");
}
}
}
@@ -518,8 +521,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
setCurrentLogicalCaret(logicalPositionToUse);
final int offset = myEditor.logicalPositionToOffset(myLogicalCaret);
if (debugBuffer != null) {
- debugBuffer.append("Resulting logical position to use: " + myLogicalCaret+
- ". It's mapped to offset " + offset+ "\n");
+ debugBuffer.append("Resulting logical position to use: ").append(myLogicalCaret).append(". It's mapped to offset ").append(offset).append("\n");
}
FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(offset);
@@ -552,7 +554,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
updateOffsetsFromLogicalPosition();
if (debugBuffer != null) {
- debugBuffer.append("Storing offset " + myOffset + " (mapped from logical position " + myLogicalCaret + ")\n");
+ debugBuffer.append("Storing offset ").append(myOffset).append(" (mapped from logical position ").append(myLogicalCaret).append(")\n");
}
LOG.assertTrue(myOffset >= 0 && myOffset <= myEditor.getDocument().getTextLength());
@@ -561,12 +563,12 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
myEditor.updateCaretCursor();
requestRepaint(oldInfo);
- if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(myEditor)) {
+ if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(this)) {
int lineToUse = myVisibleCaret.line - 1;
if (lineToUse >= 0) {
final VisualPosition visualPosition = new VisualPosition(lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse));
if (debugBuffer != null) {
- debugBuffer.append("Adjusting caret position by moving it before soft wrap. Moving to visual position "+ visualPosition+"\n");
+ debugBuffer.append("Adjusting caret position by moving it before soft wrap. Moving to visual position ").append(visualPosition).append("\n");
}
final LogicalPosition logicalPosition = myEditor.visualToLogicalPosition(visualPosition);
final int tmpOffset = myEditor.logicalPositionToOffset(logicalPosition);
@@ -814,7 +816,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
int y = myEditor.visualPositionToXY(visualPosition).y;
int lineHeight = myEditor.getLineHeight();
int height = lineHeight;
- java.util.List<? extends SoftWrap> softWraps = myEditor.getSoftWrapModel().getSoftWrapsForRange(startOffset, endOffset);
+ List<? extends SoftWrap> softWraps = myEditor.getSoftWrapModel().getSoftWrapsForRange(startOffset, endOffset);
for (SoftWrap softWrap : softWraps) {
height += StringUtil.countNewLines(softWrap.getText()) * lineHeight;
}
@@ -1451,6 +1453,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset;
}
+ public EditorImpl getEditor() {
+ return myEditor;
+ }
+
/**
* Encapsulates information about target vertical range info - its <code>'y'</code> coordinate and height in pixels.
*/
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
index a2f44fc821fe..a18d45472454 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
@@ -51,7 +51,6 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
private TextAttributes myTextAttributes;
- boolean myIgnoreWrongMoves = false;
boolean myIsInUpdate;
boolean isDocumentChanged;
@@ -122,10 +121,6 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
}
- public void setIgnoreWrongMoves(boolean ignoreWrongMoves) {
- myIgnoreWrongMoves = ignoreWrongMoves;
- }
-
public void updateVisualPosition() {
for (CaretImpl caret : myCarets) {
caret.updateVisualPosition();
@@ -337,19 +332,26 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
@Override
public void runForEachCaret(@NotNull final CaretAction action) {
+ runForEachCaret(action, false);
+ }
+
+ @Override
+ public void runForEachCaret(@NotNull final CaretAction action, final boolean reverseOrder) {
myEditor.assertIsDispatchThread();
if (!supportsMultipleCarets()) {
action.perform(getPrimaryCaret());
return;
}
if (myCurrentCaret != null) {
- action.perform(myCurrentCaret);
- return;
+ throw new IllegalStateException("Current caret is defined, cannot operate on other ones");
}
doWithCaretMerging(new Runnable() {
public void run() {
try {
- Collection<Caret> sortedCarets = getAllCarets();
+ List<Caret> sortedCarets = getAllCarets();
+ if (reverseOrder) {
+ Collections.reverse(sortedCarets);
+ }
for (Caret caret : sortedCarets) {
myCurrentCaret = (CaretImpl)caret;
action.perform(caret);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
index 2b4832c4bcf0..fc1f9048d31f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHeaderComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,6 +18,7 @@ package com.intellij.openapi.editor.impl;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -32,25 +33,30 @@ public class EditorHeaderComponent extends JPanel {
}
@Override
- public void paint(Graphics g) {
- final Graphics2D g2 = (Graphics2D)g;
+ public void paint(@NotNull Graphics g) {
+ Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
super.paint(g);
}
@Override
- protected void paintComponent(Graphics g) {
+ protected void paintComponent(@NotNull Graphics g) {
super.paintComponent(g);
paintGradient(g, this);
}
- public static void paintGradient(Graphics g, JComponent c) {
- Color GRADIENT_C1 = new JBColor(c.getBackground(), JBColor.background());
+ @NotNull
+ protected JBColor getBaseBackgroundColor() {
+ return new JBColor(getBackground(), JBColor.background());
+ }
+
+ private void paintGradient(Graphics g, JComponent c) {
+ Color GRADIENT_C1 = getBaseBackgroundColor();
Color GRADIENT_C2 = new JBColor(new Color(Math.max(0, GRADIENT_C1.getRed() - 0x18), Math.max(0, GRADIENT_C1.getGreen() - 0x18),
Math.max(0, GRADIENT_C1.getBlue() - 0x18)), Gray._75);
- final Graphics2D g2d = (Graphics2D)g;
+ Graphics2D g2d = (Graphics2D)g;
if (!UIUtil.isUnderGTKLookAndFeel()) {
g2d.setPaint(UIUtil.getGradientPaint(0, 0, GRADIENT_C1, 0, c.getHeight(), GRADIENT_C2));
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index 83bb738ca263..e37ad8f968ad 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -83,6 +83,7 @@ import com.intellij.util.ui.ButtonlessScrollBarUI;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
+import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntFunction;
@@ -879,9 +880,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
repaintLines(caretLine, caretLine);
}
fireFocusGained();
- if (myGutterNeedsUpdate) {
- updateGutterSize();
- }
}
@Override
@@ -895,6 +893,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
});
+ new UiNotifyConnector(myEditorComponent, new Activatable.Adapter(){
+ @Override
+ public void showNotify() {
+ if (myGutterNeedsUpdate) {
+ updateGutterSize();
+ }
+ }
+ });
+
try {
final DropTarget dropTarget = myEditorComponent.getDropTarget();
if (dropTarget != null) { // might be null in headless environment
@@ -2075,7 +2082,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void paintComposedTextDecoration(@NotNull Graphics2D g) {
- if (myInputMethodRequestsHandler != null && myInputMethodRequestsHandler.composedText != null) {
+ if (myInputMethodRequestsHandler != null
+ && myInputMethodRequestsHandler.composedText != null
+ && myInputMethodRequestsHandler.composedTextRange != null) {
VisualPosition visStart =
offsetToVisualPosition(Math.min(myInputMethodRequestsHandler.composedTextRange.getStartOffset(), myDocument.getTextLength()));
int y = visibleLineToY(visStart.line) + getAscent() + 1;
@@ -3884,12 +3893,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return calcColumnNumber(offset, lineIndex, true, myDocument.getImmutableCharSequence());
}
- public int calcColumnNumber(int offset, int lineIndex, boolean softWrapAware, CharSequence documentCharSequence) {
+ public int calcColumnNumber(int offset, int lineIndex, boolean softWrapAware, @NotNull CharSequence documentCharSequence) {
if (myDocument.getTextLength() == 0) return 0;
- int start = myDocument.getLineStartOffset(lineIndex);
- if (start == offset) return 0;
- int column = EditorUtil.calcColumnNumber(this, documentCharSequence, start, offset, EditorUtil.getTabSize(this));
+ int lineStartOffset = myDocument.getLineStartOffset(lineIndex);
+ if (lineStartOffset == offset) return 0;
+ int column = EditorUtil.calcColumnNumber(this, documentCharSequence, lineStartOffset, offset);
if (softWrapAware) {
int line = offsetToLogicalLine(offset, false);
@@ -4767,21 +4776,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
- private static final Field decrButtonField;
- private static final Field incrButtonField;
-
- static {
- try {
- decrButtonField = BasicScrollBarUI.class.getDeclaredField("decrButton");
- decrButtonField.setAccessible(true);
-
- incrButtonField = BasicScrollBarUI.class.getDeclaredField("incrButton");
- incrButtonField.setAccessible(true);
- }
- catch (NoSuchFieldException e) {
- throw new IllegalStateException(e);
- }
- }
+ private static final Field decrButtonField = ReflectionUtil.getDeclaredField(BasicScrollBarUI.class, "decrButton");
+ private static final Field incrButtonField = ReflectionUtil.getDeclaredField(BasicScrollBarUI.class, "incrButton");
class MyScrollBar extends JBScrollBar implements IdeGlassPane.TopComponent {
@NonNls private static final String APPLE_LAF_AQUA_SCROLL_BAR_UI_CLASS = "apple.laf.AquaScrollBarUI";
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java
index 680ed70bc405..46db15c333dc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java
@@ -91,7 +91,7 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
@Override
public boolean isValid() {
- return super.isValid() && intervalStart() + 1 < intervalEnd();
+ return super.isValid() && intervalStart() < intervalEnd();
}
public void setExpandedInternal(boolean toExpand) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java
index 0621ff4afb76..694bc75a5751 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java
@@ -529,12 +529,11 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
}
@Override
- public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, @Nullable FoldingGroup group,
- boolean neverExpands)
- {
- if (startOffset + 1 >= endOffset) {
- LOG.error("Invalid offsets: ("+startOffset+", "+endOffset+")");
- }
+ public FoldRegion createFoldRegion(int startOffset,
+ int endOffset,
+ @NotNull String placeholder,
+ @Nullable FoldingGroup group,
+ boolean neverExpands) {
FoldRegionImpl region = new FoldRegionImpl(myEditor, startOffset, endOffset, placeholder, group, neverExpands);
LOG.assertTrue(region.isValid());
return region;
@@ -551,7 +550,6 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
});
}
-
private void notifyListenersOnFoldRegionStateChange(@NotNull FoldRegion foldRegion) {
for (FoldingListener listener : myListeners) {
listener.onFoldRegionStateChange(foldRegion);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
index 9bec057faec2..cccf86c5f98e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
@@ -34,6 +34,7 @@ import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
import java.awt.*;
import java.beans.PropertyChangeEvent;
@@ -697,7 +698,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
}
}
- // for testing purposes
+ @TestOnly
public void setSoftWrapPainter(SoftWrapPainter painter) {
myPainter = painter;
myApplianceManager.setSoftWrapPainter(painter);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapHelper.java
index a3dd31e80a53..baf9477d1e9f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapHelper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,9 +15,9 @@
*/
package com.intellij.openapi.editor.impl.softwrap;
-import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.SoftWrap;
import com.intellij.openapi.editor.SoftWrapModel;
+import com.intellij.openapi.editor.impl.CaretImpl;
import com.intellij.openapi.editor.impl.EditorImpl;
/**
@@ -48,18 +48,18 @@ public class SoftWrapHelper {
* @return <code>true</code> if caret offset of the given editor points to visual position that belongs to
* visual line where soft wrap end is located
*/
- public static boolean isCaretAfterSoftWrap(EditorImpl editor) {
- CaretModel caretModel = editor.getCaretModel();
- if (!caretModel.isUpToDate()) {
+ public static boolean isCaretAfterSoftWrap(CaretImpl caret) {
+ if (!caret.isUpToDate()) {
return false;
}
+ EditorImpl editor = caret.getEditor();
SoftWrapModel softWrapModel = editor.getSoftWrapModel();
- int offset = caretModel.getOffset();
+ int offset = caret.getOffset();
SoftWrap softWrap = softWrapModel.getSoftWrap(offset);
if (softWrap == null) {
return false;
}
- return editor.offsetToVisualLine(offset) == caretModel.getVisualPosition().line;
+ return editor.offsetToVisualLine(offset) == caret.getVisualPosition().line;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java
index c5000628bcd4..08bf0211dbc8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java
@@ -465,21 +465,12 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
|| (beforeLast.visualLine + 1 == last.visualLine && last.startOffset - beforeLast.endOffset > 1)
|| last.startOffset > myEditor.getDocument().getTextLength())
{
- CharSequence editorState = "";
- if (myEditor instanceof EditorImpl) {
- editorState = ((EditorImpl)myEditor).dumpState();
- }
- LOG.error(
- "Detected invalid soft wraps cache update",
- String.format(
- "Event: %s, normal: %b.%n%nTail cache entries: %s%n%nAffected by change cache entries: %s%n%nBefore change state: %s%n%n"
- + "After change state: %s%n%nEditor state: %s",
- event, normal, myNotAffectedByUpdateTailCacheEntries, myAffectedByUpdateCacheEntries,
- myBeforeChangeState, myAfterChangeState, editorState
- )
- );
+ logInvalidUpdate(event, normal);
}
}
+ if (!myCache.isEmpty() && myEditor.getDocument().getTextLength() == 0) {
+ logInvalidUpdate(event, normal);
+ }
myAffectedByUpdateCacheEntries.clear();
myNotAffectedByUpdateTailCacheEntries.clear();
@@ -492,6 +483,22 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw
myBeforeChangeState.cacheShouldBeUpdated = false;
}
+ private void logInvalidUpdate(@NotNull IncrementalCacheUpdateEvent event, boolean normal) {
+ CharSequence editorState = "";
+ if (myEditor instanceof EditorImpl) {
+ editorState = ((EditorImpl)myEditor).dumpState();
+ }
+ LOG.error(
+ "Detected invalid soft wraps cache update",
+ String.format(
+ "Event: %s, normal: %b.%n%nTail cache entries: %s%n%nAffected by change cache entries: %s%n%nBefore change state: %s%n%n"
+ + "After change state: %s%n%nEditor state: %s",
+ event, normal, myNotAffectedByUpdateTailCacheEntries, myAffectedByUpdateCacheEntries,
+ myBeforeChangeState, myAfterChangeState, editorState
+ )
+ );
+ }
+
@Override
public void reset() {
myCache.clear();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
index a617ce9b68ed..549cd1833779 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
@@ -38,6 +38,7 @@ import com.intellij.openapi.util.text.StringUtil;
import org.intellij.lang.annotations.JdkConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
@@ -1027,7 +1028,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
return dumpState();
}
- // for testing purposes
+ @TestOnly
public void setSoftWrapPainter(SoftWrapPainter painter) {
myPainter = painter;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java
index e0b60607439b..17dd75359357 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapPainter;
import gnu.trove.TIntIntHashMap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
import java.util.ArrayList;
import java.util.List;
@@ -100,7 +101,7 @@ public class SoftWrapAwareVisualSizeManager extends SoftWrapAwareDocumentParsing
}
}
- // for testing purposes
+ @TestOnly
public void setSoftWrapPainter(SoftWrapPainter painter) {
myPainter = painter;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
index 4b3ba40849ca..ac415f5f9409 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
@@ -199,6 +199,11 @@ public class TextComponentCaretModel implements CaretModel {
}
@Override
+ public void runForEachCaret(@NotNull CaretAction action, boolean reverseOrder) {
+ action.perform(myCaret);
+ }
+
+ @Override
public void runBatchCaretOperation(@NotNull Runnable runnable) {
runnable.run();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/actions/GotoDesktopDirAction.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/actions/GotoDesktopDirAction.java
new file mode 100644
index 000000000000..ed84615ca1cd
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/actions/GotoDesktopDirAction.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.fileChooser.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileChooser.FileSystemTree;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.SystemProperties;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public class GotoDesktopDirAction extends FileChooserAction {
+ @Override
+ protected void actionPerformed(final FileSystemTree tree, AnActionEvent e) {
+ final VirtualFile dir = getDesktopDirectory();
+ if (dir != null) {
+ tree.select(dir, new Runnable() {
+ @Override
+ public void run() {
+ tree.expand(dir, null);
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void update(FileSystemTree tree, AnActionEvent e) {
+ VirtualFile dir = getDesktopDirectory();
+ e.getPresentation().setEnabled(dir != null && tree.isUnderRoots(dir));
+ }
+
+ @Nullable
+ private static VirtualFile getDesktopDirectory() {
+ File file = new File(SystemProperties.getUserHome(), "Desktop");
+ return file.isDirectory() ? LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file) : null;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java
index 1ba468baeaa5..8d33d80a525f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java
@@ -49,6 +49,7 @@ import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.tree.TreeUtil;
+import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -76,7 +77,7 @@ public class FileSystemTreeImpl implements FileSystemTree {
private final List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final MyExpansionListener myExpansionListener = new MyExpansionListener();
- private Map<VirtualFile, VirtualFile> myEverExpanded = new WeakHashMap<VirtualFile, VirtualFile>();
+ private final Set<VirtualFile> myEverExpanded = new THashSet<VirtualFile>();
public FileSystemTreeImpl(@Nullable final Project project, final FileChooserDescriptor descriptor) {
this(project, descriptor, new Tree(), null, null, null);
@@ -455,11 +456,11 @@ public class FileSystemTreeImpl implements FileSystemTree {
final FileElement fileDescriptor = nodeDescriptor.getElement();
final VirtualFile virtualFile = fileDescriptor.getFile();
if (virtualFile != null) {
- if (!myEverExpanded.containsKey(virtualFile)) {
+ if (!myEverExpanded.contains(virtualFile)) {
if (virtualFile instanceof NewVirtualFile) {
((NewVirtualFile)virtualFile).markDirty();
}
- myEverExpanded.put(virtualFile, virtualFile);
+ myEverExpanded.add(virtualFile);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
index 1b990b56e88c..860ba3211c4b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
@@ -652,7 +652,7 @@ public class EditorWindow {
if (myTabbedPane == null) {
myPanel.removeAll ();
myPanel.add (new TCompForTablessMode(this, editor), BorderLayout.CENTER);
- myPanel.revalidate ();
+ myOwner.validate();
return;
}
@@ -686,7 +686,7 @@ public class EditorWindow {
}
myOwner.setCurrentWindow(this, false);
}
- myPanel.revalidate();
+ myOwner.validate();
}
private boolean splitAvailable() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
index c46684ac4d74..b1f9ec0c2b93 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
@@ -833,6 +833,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
});
final EditorWindow window = windowRef.get();
LOG.assertTrue(window != null);
+ VirtualFile focusedFile = null;
for (int i = 0; i < fileElements.size(); i++) {
final Element file = fileElements.get(i);
@@ -845,6 +846,9 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
final boolean isCurrentInTab = Boolean.valueOf(file.getAttributeValue(CURRENT_IN_TAB)).booleanValue();
Boolean pin = Boolean.valueOf(file.getAttributeValue(PINNED));
fileEditorManager.openFileImpl4(window, entry.myFile, entry, isCurrentInTab, isCurrentInTab, pin, i);
+ if (isCurrentInTab) {
+ focusedFile = entry.myFile;
+ }
if (document != null) {
// This is just to make sure document reference is kept on stack till this point
// so that document is available for folding state deserialization in HistoryEntry constructor
@@ -859,6 +863,9 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
}
}
+ if (focusedFile != null) {
+ getManager().addSelectionRecord(focusedFile, window);
+ }
return window.myPanel;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index 6f8a2d0c4750..e36a120d609b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -851,10 +851,20 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
// Notify editors about selection changes
window.getOwner().setCurrentWindow(window, focusEditor);
window.getOwner().afterFileOpen(file);
+ addSelectionRecord(file, window);
composite.getSelectedEditor().selectNotify();
- final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject);
+ // Transfer focus into editor
+ if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) {
+ if (focusEditor) {
+ //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer);
+ window.setAsCurrentWindow(true);
+ ToolWindowManager.getInstance(myProject).activateEditorComponent();
+ IdeFocusManager.getInstance(myProject).toFront(window.getOwner());
+ }
+ }
+
if (newEditor) {
if (window.isShowing()) {
window.setPaintBlocked(true);
@@ -875,16 +885,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
// previously here was incorrect call to fireSelectionChanged() with a side-effect
((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(myProject)).onSelectionChanged();
- // Transfer focus into editor
- if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) {
- if (focusEditor) {
- //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer);
- window.setAsCurrentWindow(true);
- ToolWindowManager.getInstance(myProject).activateEditorComponent();
- focusManager.toFront(window.getOwner());
- }
- }
-
// Update frame and tab title
updateFileName(file);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
index 75432f4c2a2f..69a91ec31970 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.fileEditor.impl;
import com.intellij.ProjectTopics;
+import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.impl.stores.IProjectStore;
@@ -113,7 +114,10 @@ public class NonProjectFileWritingAccessProvider extends WritingAccessProvider {
if (deniedFiles.isEmpty()) return Collections.emptyList();
+ final int savedEventCount = IdeEventQueue.getInstance().getEventCount();
UnlockOption unlockOption = askToUnlock(deniedFiles);
+ IdeEventQueue.getInstance().setEventCount(savedEventCount);
+
if (unlockOption == null) return deniedFiles;
switch (unlockOption) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index a3c1d37ae726..198ed907a8d9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -77,7 +77,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
private static final Key<FileType> FILE_TYPE_KEY = Key.create("FILE_TYPE_KEY");
private static final Key<FileType> DETECTED_FROM_CONTENT_FILE_TYPE_KEY = Key.create("DETECTED_FROM_CONTENT_FILE_TYPE_KEY");
private static final int DETECT_BUFFER_SIZE = 8192; // the number of bytes to read from the file to feed to the file type detector
-
+ private boolean RE_DETECT_ASYNC = !ApplicationManager.getApplication().isUnitTestMode();
private final Set<FileType> myDefaultTypes = new THashSet<FileType>();
private final List<FileTypeIdentifiableByVirtualFile> mySpecialFileTypes = new ArrayList<FileTypeIdentifiableByVirtualFile>();
@@ -255,7 +255,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
}
});
files.remove(null);
- if (!files.isEmpty()) {
+ if (!files.isEmpty() && RE_DETECT_ASYNC) {
reDetectQueue.offer(files);
}
}
@@ -274,6 +274,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
public void drainReDetectQueue() {
reDetectQueue.drain();
}
+ @TestOnly
+ public void reDetectAsync(boolean enable) {
+ RE_DETECT_ASYNC = enable;
+ }
private void reDetect(@NotNull Collection<VirtualFile> files) {
final List<VirtualFile> changed = new ArrayList<VirtualFile>();
@@ -287,7 +291,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
}
}
}
- if (!changed.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
+ if (!changed.isEmpty()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
index dd2fb73e18b0..ed72e27e8c22 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -76,7 +76,7 @@ public class ConfigurableWrapper implements SearchableConfigurable {
private final ConfigurableEP myEp;
- private ConfigurableWrapper(ConfigurableEP ep) {
+ private ConfigurableWrapper(@NotNull ConfigurableEP ep) {
myEp = ep;
}
@@ -98,6 +98,13 @@ public class ConfigurableWrapper implements SearchableConfigurable {
return myEp.getDisplayName();
}
+ public String getInstanceClass() {
+ return myEp.instanceClass;
+ }
+ public String getProviderClass() {
+ return myEp.providerClass;
+ }
+
@Nullable
@Override
public String getHelpTopic() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
index ab79216dd361..80144d230eaf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
@@ -54,7 +54,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
Configurable configurable,
@NonNls String dimensionKey,
final boolean showApplyButton,
- final IdeModalityType ideModalityType) {
+ @NotNull IdeModalityType ideModalityType) {
super(project, true, ideModalityType);
myDimensionKey = dimensionKey;
myShowApplyButton = showApplyButton;
@@ -96,7 +96,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
this(parent, configurable, dimensionServiceKey, showApplyButton, IdeModalityType.IDE);
}
- public SingleConfigurableEditor(@Nullable Project project, Configurable configurable, @NonNls String dimensionKey, IdeModalityType ideModalityType) {
+ public SingleConfigurableEditor(@Nullable Project project, Configurable configurable, @NonNls String dimensionKey, @NotNull IdeModalityType ideModalityType) {
this(project, configurable, dimensionKey, true, ideModalityType);
}
@@ -108,7 +108,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
this(parent, configurable, dimensionServiceKey, true);
}
- public SingleConfigurableEditor(@Nullable Project project, Configurable configurable, IdeModalityType ideModalityType) {
+ public SingleConfigurableEditor(@Nullable Project project, Configurable configurable, @NotNull IdeModalityType ideModalityType) {
this(project, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), ideModalityType);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
index 41a0f691b56c..6ee4a1b947ef 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
@@ -20,6 +20,7 @@ import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.internal.statistic.UsageTrigger;
+import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
@@ -776,7 +777,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
for (Configurable each : modified) {
try {
each.apply();
- UsageTrigger.trigger("ide.settings." + each.getDisplayName().replace(" ", "_"));
+ UsageTrigger.trigger("ide.settings." + ConvertUsagesUtil.escapeDescriptorName(each.getDisplayName()));
if (!each.isModified()) {
getContext().fireModifiedRemoved(each, null);
}
@@ -803,8 +804,8 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return History.KEY.is(dataId) ? myHistory : null;
}
- public JTree getPreferredFocusedComponent() {
- return myTree.getTree();
+ public JComponent getPreferredFocusedComponent() {
+ return mySearch;//myTree.getTree();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
index 6f963eb2e546..bd843131e16a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
@@ -465,14 +465,10 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final Configurable[] kids = eachGroup.getConfigurables();
if (kids.length > 0) {
for (Configurable eachKid : kids) {
- if (isInvisibleNode(eachKid)) {
- result.addAll(OptionsTree.this.buildChildren(eachKid, this, eachGroup));
- }
- else {
+ if (!isInvisibleNode(eachKid)) {
result.add(new EditorNode(this, eachKid, eachGroup));
}
}
-
}
return sort(result);
}
@@ -502,9 +498,6 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final Configurable[] kids = ((Configurable.Composite)configurable).getConfigurables();
final List<EditorNode> result = new ArrayList<EditorNode>(kids.length);
for (Configurable child : kids) {
- if (isInvisibleNode(child)) {
- result.addAll(buildChildren(child, parent, group));
- }
result.add(new EditorNode(parent, child, group));
myContext.registerKid(configurable, child);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/BackgroundableProcessIndicator.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/BackgroundableProcessIndicator.java
index 30ddb76d1f5f..5b06c79a3ad2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/BackgroundableProcessIndicator.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/BackgroundableProcessIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -55,10 +55,12 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
if (myDumbModeAction == DumbModeAction.CANCEL) {
task.getProject().getMessageBus().connect(this).subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
+ @Override
public void enteredDumbMode() {
cancel();
}
+ @Override
public void exitDumbMode() {
}
});
@@ -69,6 +71,7 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
super(info.isCancellable(), true, project, info.getCancelText());
if (project != null) {
final ProjectManagerAdapter myListener = new ProjectManagerAdapter() {
+ @Override
public void projectClosing(Project closingProject) {
if (isRunning()) {
cancel();
@@ -107,23 +110,28 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
@Nls final String cancelButtonText,
@Nls final String backgroundStopTooltip, final boolean cancellable) {
this(project, new TaskInfo() {
+ @Override
public String getProcessId() {
return "<unknown>";
}
+ @Override
@NotNull
public String getTitle() {
return progressTitle;
}
+ @Override
public String getCancelText() {
return cancelButtonText;
}
+ @Override
public String getCancelTooltipText() {
return backgroundStopTooltip;
}
+ @Override
public boolean isCancellable() {
return cancellable;
}
@@ -134,6 +142,7 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
return myDumbModeAction;
}
+ @Override
protected void showDialog() {
if (myDisposed) return;
@@ -144,6 +153,7 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
super.showDialog();
}
+ @Override
public void background() {
if (myDisposed) return;
@@ -158,6 +168,7 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
}
}
+ @Override
public void dispose() {
super.dispose();
myDisposed = true;
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
index c1475d988c01..a393d937dcfb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
@@ -38,12 +38,9 @@ import com.intellij.ui.SystemNotifications;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -502,29 +499,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
if (myCheckCancelledFuture != null) myCheckCancelledFuture.cancel(false);
}
- @TestOnly
- @SuppressWarnings({"UnusedDeclaration"})
- public static String isCanceledThread(@NotNull Thread thread) {
- try {
- Field th = Thread.class.getDeclaredField("threadLocals");
- th.setAccessible(true);
- Object tLocalMap = th.get(thread);
- if (tLocalMap == null) return null;
- Method getEntry = tLocalMap.getClass().getDeclaredMethod("getEntry", ThreadLocal.class);
- getEntry.setAccessible(true);
- Object entry = getEntry.invoke(tLocalMap, myThreadIndicator);
- if (entry == null) return null;
- Field value = entry.getClass().getDeclaredField("value");
- value.setAccessible(true);
- ProgressIndicator indicator = (ProgressIndicator)value.get(entry);
- if (indicator ==null) return null;
- return String.valueOf(indicator.isCanceled());
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
private static void maybeSleep() {
final int debugProgressTime = Registry.intValue("ide.debug.minProgressTime");
if (debugProgressTime > 0) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java
index 0460a713d905..fd6484747dec 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -668,6 +668,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
}
}
+ @NotNull
@Override
protected DialogWrapperPeer createPeer(@NotNull final Component parent, final boolean canBeParent) {
if (System.getProperty("vintage.progress") == null) {
@@ -683,11 +684,13 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
}
}
+ @NotNull
@Override
protected DialogWrapperPeer createPeer(final boolean canBeParent, final boolean applicationModalIfPossible) {
return createPeer(null, canBeParent, applicationModalIfPossible);
}
+ @NotNull
@Override
protected DialogWrapperPeer createPeer(final Window owner, final boolean canBeParent, final boolean applicationModalIfPossible) {
if (System.getProperty("vintage.progress") == null) {
@@ -703,6 +706,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
}
}
+ @NotNull
@Override
protected DialogWrapperPeer createPeer(final Project project, final boolean canBeParent) {
if (System.getProperty("vintage.progress") == null) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java
index 25c312a08131..9d6aa539a277 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.project;
+import com.intellij.ide.IdeBundle;
import com.intellij.ide.caches.CacheUpdater;
import com.intellij.ide.caches.FileContent;
import com.intellij.openapi.application.Application;
@@ -40,7 +41,7 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
-public class CacheUpdateRunner {
+public class CacheUpdateRunner extends DumbModeTask {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.CacheUpdateRunner");
private static final Key<Boolean> FAILED_TO_INDEX = Key.create("FAILED_TO_INDEX");
private static final int PROC_COUNT = Runtime.getRuntime().availableProcessors();
@@ -58,15 +59,11 @@ public class CacheUpdateRunner {
return new ArrayList<CacheUpdater>(myUpdaters).toString();
}
- public int queryNeededFiles(@NotNull ProgressIndicator indicator) {
+ private int queryNeededFiles(@NotNull ProgressIndicator indicator) {
// can be queried twice in DumbService
return getSession(indicator).getFilesToUpdate().size();
}
- public int getNumberOfPendingUpdateJobs(@NotNull ProgressIndicator indicator) {
- return getSession(indicator).getNumberOfPendingUpdateJobs();
- }
-
@NotNull
private CacheUpdateSession getSession(@NotNull ProgressIndicator indicator) {
CacheUpdateSession session = mySession;
@@ -76,7 +73,7 @@ public class CacheUpdateRunner {
return session;
}
- public void processFiles(@NotNull final ProgressIndicator indicator, boolean processInReadAction) {
+ private void processFiles(@NotNull final ProgressIndicator indicator, boolean processInReadAction) {
try {
Collection<VirtualFile> files = mySession.getFilesToUpdate();
@@ -134,7 +131,7 @@ public class CacheUpdateRunner {
}
}
- public void updatingDone() {
+ private void updatingDone() {
try {
mySession.updatingDone();
}
@@ -217,6 +214,21 @@ public class CacheUpdateRunner {
return false;
}
+ @Override
+ public void performInDumbMode(@NotNull ProgressIndicator indicator) {
+ indicator.checkCanceled();
+ indicator.setIndeterminate(true);
+ indicator.setText(IdeBundle.message("progress.indexing.scanning"));
+ int count = queryNeededFiles(indicator);
+
+ indicator.setIndeterminate(false);
+ indicator.setText(IdeBundle.message("progress.indexing.updating"));
+ if (count > 0) {
+ processFiles(indicator, true);
+ }
+ updatingDone();
+ }
+
private static class MyRunnable implements Runnable {
private final ProgressIndicatorBase myInnerIndicator;
private final FileContentQueue myQueue;
@@ -313,12 +325,12 @@ public class CacheUpdateRunner {
return ApplicationManager.getApplication().isReadAccessAllowed() ? new Runnable() {
@Override
public void run() {
- boolean old = ApplicationImpl.setExceptionalThreadWithReadAccessFlag(true);
+ ApplicationImpl.setExceptionalThreadWithReadAccessFlag(true);
try {
process.run();
}
finally {
- ApplicationImpl.setExceptionalThreadWithReadAccessFlag(old);
+ ApplicationImpl.setExceptionalThreadWithReadAccessFlag(false);
}
}
} : process;
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
index f71eb5fef698..a20df87718cc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
@@ -17,8 +17,6 @@ package com.intellij.openapi.project;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.caches.CacheUpdater;
-import com.intellij.ide.caches.FileContent;
-import com.intellij.ide.util.DelegatingProgressIndicator;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
@@ -29,40 +27,47 @@ import com.intellij.openapi.progress.*;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.ShutDownTracker;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.AppIconScheme;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.openapi.wm.ex.StatusBarEx;
+import com.intellij.psi.impl.DebugUtil;
import com.intellij.ui.AppIcon;
import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Queue;
import com.intellij.util.io.storage.HeavyProcessLatch;
-import com.intellij.util.messages.MessageBus;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
+import java.util.Map;
-public class DumbServiceImpl extends DumbService {
+public class DumbServiceImpl extends DumbService implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.DumbServiceImpl");
private volatile boolean myDumb = false;
private final DumbModeListener myPublisher;
- private final Queue<IndexUpdateRunnable> myUpdatesQueue = new Queue<IndexUpdateRunnable>(5);
+ private final Queue<DumbModeTask> myUpdatesQueue = new Queue<DumbModeTask>(5);
+
+ /**
+ * Per-task progress indicators. Modified from EDT only.
+ * The task is removed from this map after it's finished or when the project is disposed.
+ */
+ private final Map<DumbModeTask, ProgressIndicatorEx> myProgresses = ContainerUtil.newConcurrentMap();
+
private final Queue<Runnable> myRunWhenSmartQueue = new Queue<Runnable>(5);
private final Project myProject;
- private final CacheUpdateRunner NULL_ACTION;
+
+ public DumbServiceImpl(Project project) {
+ myProject = project;
+ myPublisher = project.getMessageBus().syncPublisher(DUMB_MODE);
+ }
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"})
public static DumbServiceImpl getInstance(@NotNull Project project) {
@@ -70,46 +75,28 @@ public class DumbServiceImpl extends DumbService {
}
@Override
- public void queueTask(final DumbModeTask task) {
- CacheUpdater wrapper = new CacheUpdater() {
- @Override
- public int getNumberOfPendingUpdateJobs() {
- return 0;
- }
-
- @NotNull
- @Override
- public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
- task.performInDumbMode(indicator);
- return new VirtualFile[0];
- }
-
- @Override
- public void processFile(@NotNull FileContent fileContent) {
-
- }
-
- @Override
- public void updatingDone() {
- }
-
- @Override
- public void canceled() {
-
- }
+ public void queueTask(@NotNull final DumbModeTask task) {
+ scheduleCacheUpdate(task, true);
+ }
- @Override
- public String toString() {
- return task.toString();
- }
- };
- queueCacheUpdateInDumbMode(Arrays.asList(wrapper));
+ @Override
+ public void cancelTask(@NotNull DumbModeTask task) {
+ if (ApplicationManager.getApplication().isInternal()) LOG.info("cancel " + task + "\n" + DebugUtil.currentStackTrace());
+ ProgressIndicatorEx indicator = myProgresses.get(task);
+ if (indicator != null) {
+ indicator.cancel();
+ }
}
- public DumbServiceImpl(Project project, MessageBus bus) {
- myProject = project;
- myPublisher = bus.syncPublisher(DUMB_MODE);
- NULL_ACTION = new CacheUpdateRunner(project, Collections.<CacheUpdater>emptyList());
+ @Override
+ public void dispose() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ myUpdatesQueue.clear();
+ myRunWhenSmartQueue.clear();
+ for (DumbModeTask task : new ArrayList<DumbModeTask>(myProgresses.keySet())) {
+ cancelTask(task);
+ Disposer.dispose(task);
+ }
}
@Override
@@ -145,87 +132,58 @@ public class DumbServiceImpl extends DumbService {
}
}
+ @SuppressWarnings("deprecation")
public void queueCacheUpdate(@NotNull Collection<CacheUpdater> updaters) {
- scheduleCacheUpdate(updaters, false);
+ scheduleCacheUpdate(new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters)), false);
}
+ @SuppressWarnings("deprecation")
public void queueCacheUpdateInDumbMode(@NotNull Collection<CacheUpdater> updaters) {
- scheduleCacheUpdate(updaters, true);
+ scheduleCacheUpdate(new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters)), true);
}
- private void scheduleCacheUpdate(@NotNull Collection<CacheUpdater> updaters, boolean forceDumbMode) {
- // prevent concurrent modifications
- final CacheUpdateRunner runner = new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters));
-
+ private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) {
+ if (ApplicationManager.getApplication().isInternal()) LOG.info("schedule " + task);
final Application application = ApplicationManager.getApplication();
- if (application.isUnitTestMode() || application.isHeadlessEnvironment()) {
- // no dumb mode for tests
- EmptyProgressIndicator i = new EmptyProgressIndicator();
- final int size = runner.queryNeededFiles(i);
+ if (application.isUnitTestMode() ||
+ application.isHeadlessEnvironment() ||
+ !forceDumbMode && !myDumb && application.isReadAccessAllowed()) {
+ final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (indicator != null) {
+ indicator.pushState();
+ }
try {
HeavyProcessLatch.INSTANCE.processStarted();
- if (size > 0) {
- runner.processFiles(i, false);
- }
- runner.updatingDone();
+ task.performInDumbMode(indicator != null ? indicator : new EmptyProgressIndicator());
}
finally {
HeavyProcessLatch.INSTANCE.processFinished();
- }
- return;
- }
-
- if (!forceDumbMode && !myDumb && application.isReadAccessAllowed()) {
- // if there are not so many files to process, process them on the spot without entering dumb mode
- final ProgressIndicator currentIndicator = ProgressManager.getInstance().getProgressIndicator();
- final ProgressIndicator indicator;
- if (currentIndicator != null) {
- indicator = currentIndicator;
- currentIndicator.pushState();
- }
- else {
- indicator = new EmptyProgressIndicator();
- }
- try {
- final int size = runner.queryNeededFiles(indicator);
- if (size + runner.getNumberOfPendingUpdateJobs(indicator) < 50) {
- // If not that many files found, process them on the spot, avoiding entering dumb mode
- // Consider number of pending tasks as well, because they may take noticeable time to process even if the number of files is small
- try {
- HeavyProcessLatch.INSTANCE.processStarted();
- if (size > 0) {
- runner.processFiles(indicator, false);
- }
- runner.updatingDone();
- }
- finally {
- HeavyProcessLatch.INSTANCE.processFinished();
- }
- return;
- }
- }
- finally {
- if (currentIndicator != null) {
- currentIndicator.popState();
+ if (indicator != null) {
+ indicator.popState();
}
+ Disposer.dispose(task);
}
+ return;
}
-
- final IndexUpdateRunnable updateRunnable = new IndexUpdateRunnable(runner);
-
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
@Override
public void run() {
if (myProject.isDisposed()) {
return;
}
+ final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
+ myProgresses.put(task, indicator);
+ Disposer.register(task, new Disposable() {
+ @Override
+ public void dispose() {
+ application.assertIsDispatchThread();
+ myProgresses.remove(task);
+ }
+ });
// ok to test and set the flag like this, because the change is always done from dispatch thread
- if (myDumb) {
- myUpdatesQueue.addLast(updateRunnable);
- }
- else {
+ if (!myDumb) {
// always change dumb status inside write action.
// This will ensure all active read actions are completed before the app goes dumb
boolean startSuccess =
@@ -239,14 +197,13 @@ public class DumbServiceImpl extends DumbService {
catch (Throwable e) {
LOG.error(e);
}
- finally {
- try {
- updateRunnable.run();
- }
- catch (Throwable e) {
- LOG.error("Failed to start background index update task", e);
- return false;
- }
+
+ try {
+ startBackgroundProcess(task, indicator);
+ }
+ catch (Throwable e) {
+ LOG.error("Failed to start background index update task", e);
+ return false;
}
return true;
}
@@ -255,6 +212,9 @@ public class DumbServiceImpl extends DumbService {
updateFinished();
}
}
+ else {
+ myUpdatesQueue.addLast(task);
+ }
}
});
}
@@ -365,140 +325,99 @@ public class DumbServiceImpl extends DumbService {
}, modalityState, myProject.getDisposed());
}
- private class IndexUpdateRunnable implements Runnable {
- private final CacheUpdateRunner myAction;
+ private void startBackgroundProcess(@NotNull final DumbModeTask task, @NotNull final ProgressIndicatorEx indicator) {
+ ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
- public IndexUpdateRunnable(@NotNull CacheUpdateRunner action) {
- myAction = action;
- }
+ @Override
+ public void run(@NotNull final ProgressIndicator visibleIndicator) {
+ if (ApplicationManager.getApplication().isInternal()) LOG.info("Running dumb mode task: " + task);
+
+ final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance();
+ final Thread self = Thread.currentThread();
+ try {
+ HeavyProcessLatch.INSTANCE.processStarted();
+ shutdownTracker.registerStopperThread(self);
- @Override
- public void run() {
- ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
+ indicator.checkCanceled();
- @Override
- public void run(@NotNull final ProgressIndicator indicator) {
- if (indicator instanceof ProgressIndicatorEx) {
- ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
- double lastFraction;
+ if (visibleIndicator instanceof ProgressIndicatorEx) {
+ indicator.addStateDelegate((ProgressIndicatorEx)visibleIndicator);
+ ((ProgressIndicatorEx)visibleIndicator).addStateDelegate(new AppIconProgress());
+ }
- @Override
- public void setFraction(final double fraction) {
- if (fraction - lastFraction < 0.01d) return;
- lastFraction = fraction;
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- AppIcon.getInstance().setProgress(myProject, "indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
- }
- });
- }
+ indicator.setIndeterminate(true);
+ indicator.setText(IdeBundle.message("progress.indexing.scanning"));
- @Override
- public void finish(@NotNull TaskInfo task) {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- AppIcon appIcon = AppIcon.getInstance();
- if (appIcon.hideProgress(myProject, "indexUpdate")) {
- appIcon.requestAttention(myProject, false);
- appIcon.setOkBadge(myProject, true);
- }
- }
- });
- }
- });
- }
+ task.performInDumbMode(indicator);
+ }
+ catch (ProcessCanceledException ignored) {
+ }
+ catch (Throwable unexpected) {
+ LOG.error(unexpected);
+ }
+ finally {
+ shutdownTracker.unregisterStopperThread(self);
+ HeavyProcessLatch.INSTANCE.processFinished();
+ taskFinished(task);
+ }
+ }
+ });
+ }
- final ProgressIndicator proxy = new DelegatingProgressIndicator(indicator);
+ private void taskFinished(@NotNull final DumbModeTask prevTask) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (myProject.isDisposed()) return;
+ Disposer.dispose(prevTask);
- final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance();
- final Thread self = Thread.currentThread();
- try {
- HeavyProcessLatch.INSTANCE.processStarted();
- shutdownTracker.registerStopperThread(self);
- runAction(proxy, myAction);
- }
- catch (RuntimeException e) {
- LOG.error(e);
- throw e;
- }
- finally {
- shutdownTracker.unregisterStopperThread(self);
- HeavyProcessLatch.INSTANCE.processFinished();
+ while (true) {
+ if (myUpdatesQueue.isEmpty()) {
+ updateFinished();
+ return;
}
- }
- private void runAction(ProgressIndicator indicator, CacheUpdateRunner updateRunner) {
- while (updateRunner != null) {
- try {
- if (ApplicationManager.getApplication().isInternal()) LOG.info("Running dumb mode task: " + updateRunner);
- indicator.checkCanceled();
- indicator.setIndeterminate(true);
- indicator.setText(IdeBundle.message("progress.indexing.scanning"));
- int count = updateRunner.queryNeededFiles(indicator);
-
- indicator.setIndeterminate(false);
- indicator.setText(IdeBundle.message("progress.indexing.updating"));
- if (count > 0) {
- updateRunner.processFiles(indicator, true);
- }
- updateRunner.updatingDone();
- }
- catch (ProcessCanceledException ignored) {
- }
- catch (Throwable unexpected) {
- LOG.error(unexpected);
- }
- updateRunner = getNextUpdateRunner();
+ DumbModeTask queuedTask = myUpdatesQueue.pullFirst();
+ ProgressIndicatorEx indicator = myProgresses.get(queuedTask);
+ if (indicator.isCanceled()) {
+ Disposer.dispose(queuedTask);
+ continue;
}
+
+ startBackgroundProcess(queuedTask, indicator);
+ return;
}
+ }
+ });
+ }
- @Nullable
- private CacheUpdateRunner getNextUpdateRunner() {
- final BlockingQueue<CacheUpdateRunner> actionQueue = new LinkedBlockingQueue<CacheUpdateRunner>();
- UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
- @Override
- public void run() {
- IndexUpdateRunnable nextRunnable = getNextUpdateFromQueue();
- try {
- actionQueue.offer(nextRunnable == null ? NULL_ACTION : nextRunnable.myAction);
- }
- finally {
- if (nextRunnable == null) {
- updateFinished();
- }
- }
- }
- });
-
- // try to obtain the next action or terminate if no actions left
- while (!myProject.isDisposed()) {
- try {
- CacheUpdateRunner ref = actionQueue.poll(500L, TimeUnit.MILLISECONDS);
- if (ref != null) {
- return ref == NULL_ACTION ? null : ref;
- }
- }
- catch (InterruptedException e) {
- LOG.info(e);
- }
- }
- return null;
+ private class AppIconProgress extends ProgressIndicatorBase {
+ double lastFraction;
+
+ @Override
+ public void setFraction(final double fraction) {
+ if (fraction - lastFraction < 0.01d) return;
+ lastFraction = fraction;
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ AppIcon.getInstance().setProgress(myProject, "indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
}
+ });
+ }
- @Nullable
- private IndexUpdateRunnable getNextUpdateFromQueue() {
- try {
- return myUpdatesQueue.isEmpty()? null : myUpdatesQueue.pullFirst();
- }
- catch (Throwable e) {
- LOG.info(e);
- return null;
+ @Override
+ public void finish(@NotNull TaskInfo task) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ AppIcon appIcon = AppIcon.getInstance();
+ if (appIcon.hideProgress(myProject, "indexUpdate")) {
+ appIcon.requestAttention(myProject, false);
+ appIcon.setOkBadge(myProject, true);
}
}
});
}
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/AbstractDialog.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/AbstractDialog.java
index ad6f92ae54d8..757077c892ce 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/AbstractDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/AbstractDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,6 +18,7 @@ package com.intellij.openapi.ui.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.FocusTrackback;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -82,9 +83,10 @@ interface AbstractDialog extends Disposable {
void setResizable(boolean resizable);
+ @NotNull
Point getLocation();
- void setLocation(Point p);
+ void setLocation(@NotNull Point p);
void setLocation(int x, int y);
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java
index 349272acaa8c..9a5f67a433f7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerFactoryImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,15 +25,19 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class DialogWrapperPeerFactoryImpl extends DialogWrapperPeerFactory {
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent) {
return new DialogWrapperPeerImpl(wrapper, project, canBeParent);
}
- public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType) {
+ @NotNull
+ @Override
+ public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, @NotNull DialogWrapper.IdeModalityType ideModalityType) {
return new DialogWrapperPeerImpl(wrapper, project, canBeParent, ideModalityType);
}
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, boolean canBeParent) {
return new DialogWrapperPeerImpl(wrapper, canBeParent);
@@ -42,27 +46,32 @@ public class DialogWrapperPeerFactoryImpl extends DialogWrapperPeerFactory {
/**
* {@inheritDoc}
*/
+ @NotNull
@Deprecated
@Override
public DialogWrapperPeer createPeer(@NotNull final DialogWrapper wrapper, final boolean canBeParent, final boolean applicationModalIfPossible) {
return new DialogWrapperPeerImpl(wrapper, null, canBeParent, applicationModalIfPossible);
}
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull final DialogWrapper wrapper, final Window owner, final boolean canBeParent, final boolean applicationModalIfPossible) {
return new DialogWrapperPeerImpl(wrapper, owner, canBeParent, applicationModalIfPossible);
}
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent) {
return new DialogWrapperPeerImpl(wrapper, parent, canBeParent);
}
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType) {
return new DialogWrapperPeerImpl(wrapper, (Window)null, canBeParent, ideModalityType);
}
+ @NotNull
@Override
public DialogWrapperPeer createPeer(@NotNull DialogWrapper wrapper,
Window owner,
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
index dc9821ec9836..6ffa084931b4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -78,7 +78,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
private final ActionCallback myTypeAheadDone = new ActionCallback("DialogTypeAheadDone");
private ActionCallback myTypeAheadCallback;
- protected DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType) {
+ protected DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, @NotNull DialogWrapper.IdeModalityType ideModalityType) {
myWrapper = wrapper;
myTypeAheadCallback = myWrapper.isTypeAheadEnabled() ? new ActionCallback() : null;
myWindowManager = null;
@@ -237,7 +237,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
myDialog.addKeyListener(listener);
}
- private void createDialog(@Nullable Window owner, boolean canBeParent, DialogWrapper.IdeModalityType ideModalityType) {
+ private void createDialog(@Nullable Window owner, boolean canBeParent, @NotNull DialogWrapper.IdeModalityType ideModalityType) {
if (isHeadless()) {
myDialog = new HeadlessDialog();
return;
@@ -407,13 +407,14 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
myDialog.setResizable(resizable);
}
+ @NotNull
@Override
public Point getLocation() {
return myDialog.getLocation();
}
@Override
- public void setLocation(Point p) {
+ public void setLocation(@NotNull Point p) {
myDialog.setLocation(p);
}
@@ -744,6 +745,16 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
@Override
public void windowOpened(WindowEvent e) {
+ if (!isModal()) {
+ DialogWrapper wrapper = getDialogWrapper();
+ if (wrapper != null) {
+ JComponent component = wrapper.getPreferredFocusedComponent();
+ if (component != null) {
+ // request focus for non-modal dialog (i.e. TipDialog)
+ IdeFocusManager.findInstance().requestFocus(component, true);
+ }
+ }
+ }
if (!SystemInfo.isMacOSLion) return;
Window window = e.getWindow();
if (window instanceof Dialog) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java
index 0c83d3932b6f..3a72b600a269 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -29,6 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.DialogWrapperDialog;
import com.intellij.openapi.ui.DialogWrapperPeer;
+import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
@@ -40,7 +41,6 @@ import com.intellij.openapi.wm.impl.IdeGlassPaneEx;
import com.intellij.ui.FocusTrackback;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.components.JBLayeredPane;
-import com.intellij.ui.popup.StackingPopupDispatcherImpl;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -129,7 +129,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
}
private void createDialog(final Window owner) throws GlasspanePeerUnavailableException {
- Window active = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ Window active = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
if (!(active instanceof JDialog) && owner instanceof IdeFrame) {
final JFrame frame = (JFrame) owner;
final JComponent glassPane = (JComponent) frame.getGlassPane();
@@ -141,6 +141,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
}
}
+ @Override
public FocusTrackback getFocusTrackback() {
if (myDialog != null) {
return myDialog.getFocusTrackback();
@@ -148,30 +149,37 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return null;
}
+ @Override
public void setUndecorated(final boolean undecorated) {
LOG.assertTrue(undecorated, "Decorated dialogs are not supported!");
}
+ @Override
public void addMouseListener(final MouseListener listener) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public void addMouseListener(final MouseMotionListener listener) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public void addKeyListener(final KeyListener listener) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public void toFront() {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public void toBack() {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public void dispose() {
LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only");
@@ -183,18 +191,22 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
}
}
+ @Override
public Container getContentPane() {
return myDialog.getContentPane();
}
+ @Override
public Window getOwner() {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @Override
public Window getWindow() {
return null;
}
+ @Override
public JRootPane getRootPane() {
if (myDialog == null) {
return null;
@@ -203,18 +215,22 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return myDialog.getRootPane();
}
+ @Override
public Dimension getSize() {
return myDialog.getSize();
}
+ @Override
public String getTitle() {
return "";
}
+ @Override
public Dimension getPreferredSize() {
return myDialog.getPreferredSize();
}
+ @Override
public void setModal(final boolean modal) {
LOG.assertTrue(modal, "Can't be non modal!");
}
@@ -224,38 +240,48 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return true;
}
+ @Override
public boolean isVisible() {
return myDialog != null && myDialog.isVisible();
}
+ @Override
public boolean isShowing() {
return myDialog != null && myDialog.isShowing();
}
+ @Override
public void setSize(final int width, final int height) {
myDialog.setSize(width, height);
}
+ @Override
public void setTitle(final String title) {
myTitle = title;
}
// TODO: WTF?! VOID?!!!
+ @Override
public void isResizable() {
}
+ @Override
public void setResizable(final boolean resizable) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
+ @NotNull
+ @Override
public Point getLocation() {
return myDialog.getLocation();
}
- public void setLocation(final Point p) {
+ @Override
+ public void setLocation(@NotNull final Point p) {
setLocation(p.x, p.y);
}
+ @Override
public void setLocation(final int x, final int y) {
if (myDialog == null || !myDialog.isShowing()) {
return;
@@ -281,6 +307,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
myDialog.setLocation(_x, _y);
}
+ @Override
public ActionCallback show() {
LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only");
@@ -291,16 +318,19 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return new ActionCallback.Done();
}
+ @Override
public void setContentPane(final JComponent content) {
myDialog.setContentPane(content);
}
+ @Override
public void centerInParent() {
if (myDialog != null) {
myDialog.center();
}
}
+ @Override
public void validate() {
if (myDialog != null) {
myDialog.resetSizeCache();
@@ -308,15 +338,18 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
}
}
+ @Override
public void repaint() {
if (myDialog != null) {
myDialog.repaint();
}
}
+ @Override
public void pack() {
}
+ @Override
public void setAppIcons() {
throw new UnsupportedOperationException("Not implemented in " + getClass().getCanonicalName());
}
@@ -331,11 +364,12 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
private void hidePopupsIfNeeded() {
if (!SystemInfo.isMac) return;
- StackingPopupDispatcherImpl.getInstance().hidePersistentPopups();
+ StackingPopupDispatcher.getInstance().hidePersistentPopups();
Disposer.register(myDialog, new Disposable() {
+ @Override
public void dispose() {
- StackingPopupDispatcherImpl.getInstance().restorePersistentPopups();
+ StackingPopupDispatcher.getInstance().restorePersistentPopups();
}
});
}
@@ -551,11 +585,13 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
}
}
+ @Override
public void dispose() {
remove(getContentPane());
repaint();
final Runnable disposer = new Runnable() {
+ @Override
public void run() {
setVisible(false);
}
@@ -586,14 +622,17 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return myContentPane;
}
+ @Override
public JRootPane getRootPane() {
return myRootPane;
}
+ @Override
public DialogWrapper getDialogWrapper() {
return myDialogWrapper.get();
}
+ @Override
public Object getData(@NonNls final String dataId) {
final DialogWrapper wrapper = myDialogWrapper.get();
if (wrapper instanceof DataProvider) {
@@ -605,6 +644,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
return null;
}
+ @Override
public void setSize(int width, int height) {
Point location = getLocation();
Rectangle rect = new Rectangle(location.x, location.y, width, height);
@@ -616,6 +656,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
super.setSize(rect.width, rect.height);
}
+ @Override
public FocusTrackback getFocusTrackback() {
return null;
}
@@ -651,6 +692,7 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc
myDialog = dialog;
}
+ @Override
protected JLayeredPane createLayeredPane() {
JLayeredPane p = new JBLayeredPane();
p.setName(this.getName()+".layeredPane");
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/HeadlessDialog.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/HeadlessDialog.java
index ebbe98d2f4b4..de8f2234fd00 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/HeadlessDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/HeadlessDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.openapi.ui.impl;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.FocusTrackback;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -29,104 +30,135 @@ import java.awt.event.MouseMotionListener;
*/
@SuppressWarnings("ConstantConditions")
class HeadlessDialog implements AbstractDialog {
+ @Override
public void setUndecorated(boolean undecorated) {
}
+ @Override
public void addMouseListener(MouseListener listener) {
}
+ @Override
public void addMouseMotionListener(MouseMotionListener listener) {
}
+ @Override
public void addKeyListener(KeyListener listener) {
}
+ @Override
public void setModal(boolean b) {
}
+ @Override
public void toFront() {
}
+ @Override
public void setContentPane(Container content) {
}
+ @Override
public void centerInParent() {
}
+ @Override
public void toBack() {
}
+ @Override
public JRootPane getRootPane() {
return null;
}
+ @Override
public void remove(Component root) {
}
+ @Override
public Container getContentPane() {
return null;
}
+ @Override
public void validate() {
}
+ @Override
public void repaint() {
}
+ @Override
public Window getOwner() {
return null;
}
+ @Override
public JDialog getWindow() {
return null;
}
+ @Override
public Dimension getSize() {
return null;
}
+ @Override
public String getTitle() {
return null;
}
+ @Override
public void pack() {
}
+ @Override
public Dimension getPreferredSize() {
return null;
}
+ @Override
public boolean isVisible() {
return false;
}
+ @Override
public boolean isShowing() {
return false;
}
+ @Override
public void setSize(int width, int height) {
}
+ @Override
public void setTitle(String title) {
}
+ @Override
public boolean isResizable() {
return false;
}
+ @Override
public void setResizable(boolean resizable) {
}
+ @NotNull
+ @Override
public Point getLocation() {
- return null;
+ return new Point(0,0);
}
- public void setLocation(Point p) {
+ @Override
+ public void setLocation(@NotNull Point p) {
}
+ @Override
public void setLocation(int x, int y) {
}
+ @Override
public boolean isModal() {
return false;
}
@@ -140,17 +172,21 @@ class HeadlessDialog implements AbstractDialog {
return null;
}
+ @Override
public void show() {
}
+ @Override
public IdeFocusManager getFocusManager() {
return null;
}
+ @Override
public FocusTrackback getFocusTrackback() {
return null;
}
+ @Override
public void dispose() {
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
index 6401fbb2490c..1f331d7f9232 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
@@ -29,6 +29,6 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(AnActionEvent e) {
- UpdateChecker.updateAndShowResult(e.getData(CommonDataKeys.PROJECT), false, null, UpdateSettings.getInstance());
+ UpdateChecker.updateAndShowResult(e.getData(CommonDataKeys.PROJECT), false, UpdateSettings.getInstance());
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
index a6641bb0cea4..9739d75be7e7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
@@ -18,11 +18,8 @@ package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.*;
import com.intellij.ide.startup.StartupActionScriptManager;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -47,9 +44,7 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
-import java.net.URLEncoder;
import java.util.List;
-import java.util.UUID;
/**
* @author anna
@@ -98,6 +93,10 @@ public class PluginDownloader {
}
public boolean prepareToInstall(@Nullable ProgressIndicator pi, @Nullable BuildNumber forBuildNumber) throws IOException {
+ if (myFile != null) {
+ return true;
+ }
+
IdeaPluginDescriptor descriptor = null;
if (!Boolean.getBoolean(StartupActionScriptManager.STARTUP_WIZARD_MODE) && PluginManager.isPluginInstalled(PluginId.getId(myPluginId))) {
//store old plugins file
@@ -386,22 +385,9 @@ public class PluginDownloader {
}
public static PluginDownloader createDownloader(IdeaPluginDescriptor descriptor) throws UnsupportedEncodingException {
- String url = null;
- if (descriptor instanceof PluginNode) {
- url = ((PluginNode)descriptor).getDownloadUrl();
- }
- if (url == null) {
- String uuid = ApplicationManager.getApplication() == null ?
- UUID.randomUUID().toString() :
- UpdateChecker.getInstallationUID(PropertiesComponent.getInstance());
- String buildNumber = ApplicationManager.getApplication() != null
- ? ApplicationInfo.getInstance().getApiVersion()
- : ApplicationInfoImpl.getShadowInstance().getBuild().asString();
- url = RepositoryHelper.getDownloadUrl() + URLEncoder.encode(descriptor.getPluginId().getIdString(), "UTF8") +
- "&build=" + buildNumber + "&uuid=" + URLEncoder.encode(uuid, "UTF8");
- }
-
- PluginDownloader downloader = new PluginDownloader(descriptor.getPluginId().getIdString(), url, descriptor.getVersion(), null, descriptor.getName());
+ PluginDownloader downloader = new PluginDownloader(descriptor.getPluginId().getIdString(),
+ UpdateChecker.getDownloadUrl(descriptor),
+ descriptor.getVersion(), null, descriptor.getName());
downloader.setDescriptor(descriptor);
return downloader;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java
index 162c91a50ff7..02e9af1b4118 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java
@@ -16,9 +16,13 @@
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
-import com.intellij.ide.plugins.PluginManagerConfigurable;
-import com.intellij.openapi.ui.Messages;
+import com.intellij.ide.plugins.PluginManagerMain;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.util.Ref;
import com.intellij.ui.TableUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -61,20 +65,46 @@ class PluginUpdateInfoDialog extends AbstractUpdateDialog {
@Override
protected void doOKAction() {
- if (downloadPlugins() && toRestart()) {
- restart();
- }
-
super.doOKAction();
- }
+ final Ref<Boolean> result = new Ref<Boolean>();
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ UpdateChecker.saveDisabledToUpdatePlugins();
+ result.set(UpdateChecker.install(myUploadedPlugins));
+ }
+ };
+
+ final String progressTitle = "Download plugins...";
+ if (downloadModal()) {
+ ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, progressTitle, true, null);
+ } else {
+ ProgressManager.getInstance().run(new Task.Backgroundable(null, progressTitle, true) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ runnable.run();
+ }
- protected boolean toRestart() {
- return PluginManagerConfigurable.showRestartIDEADialog() == Messages.YES;
+ @Override
+ public void onSuccess() {
+ final Boolean installed = result.get();
+ if (installed != null && installed.booleanValue()) {
+ final String pluginName;
+ if (myUploadedPlugins.size() == 1) {
+ final PluginDownloader firstItem = ContainerUtil.getFirstItem(myUploadedPlugins);
+ pluginName = firstItem != null ? firstItem.getPluginName() : null;
+ }
+ else {
+ pluginName = null;
+ }
+ PluginManagerMain.notifyPluginsWereInstalled(pluginName, null);
+ }
+ }
+ });
+ }
}
- private boolean downloadPlugins() {
- UpdateChecker.saveDisabledToUpdatePlugins();
- return UpdateChecker.install(myUploadedPlugins);
+ protected boolean downloadModal() {
+ return false;
}
private class PluginUpdateInfoPanel {
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
index 7510c7758800..9dd3dd21f879 100755
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
@@ -75,7 +76,7 @@ import java.util.concurrent.TimeoutException;
public final class UpdateChecker {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.updateSettings.impl.UpdateChecker");
- private static final Map<String, String> ourUpdatedPlugins = new HashMap<String, String>();
+ private static final Map<String, PluginDownloader> ourUpdatedPlugins = new HashMap<String, PluginDownloader>();
public enum DownloadPatchResult {
SUCCESS, FAILED, CANCELED
@@ -118,7 +119,7 @@ public final class UpdateChecker {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
- doUpdateAndShowResult(null, true, false, null, UpdateSettings.getInstance(), null, callback);
+ doUpdateAndShowResult(null, true, false, UpdateSettings.getInstance(), null, callback);
}
});
return callback;
@@ -127,13 +128,12 @@ public final class UpdateChecker {
// for manual update checks (Help | Check for Updates)
public static void updateAndShowResult(final @Nullable Project project,
final boolean fromSettings,
- final @Nullable PluginHostsConfigurable hostsConfigurable,
final UpdateSettings settings) {
ProgressManager.getInstance().run(new Task.Backgroundable(project, IdeBundle.message("updates.checking.progress"), true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
- doUpdateAndShowResult(project, !fromSettings, true, hostsConfigurable, settings, indicator, null);
+ doUpdateAndShowResult(project, !fromSettings, true, settings, indicator, null);
}
@Override
@@ -151,7 +151,6 @@ public final class UpdateChecker {
private static void doUpdateAndShowResult(final @Nullable Project project,
final boolean enableLink,
final boolean manualCheck,
- final @Nullable PluginHostsConfigurable hostsConfigurable,
final UpdateSettings updateSettings,
final @Nullable ProgressIndicator indicator,
final @Nullable ActionCallback callback) {
@@ -177,7 +176,7 @@ public final class UpdateChecker {
}
}
final Collection<IdeaPluginDescriptor> incompatiblePlugins = buildNumber != null ? new HashSet<IdeaPluginDescriptor>() : null;
- final Collection<PluginDownloader> updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, incompatiblePlugins, hostsConfigurable, indicator, buildNumber);
+ final Collection<PluginDownloader> updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, incompatiblePlugins, indicator, buildNumber);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
@@ -192,12 +191,11 @@ public final class UpdateChecker {
public static Collection<PluginDownloader> updatePlugins(boolean manualCheck,
@Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
- @Nullable PluginHostsConfigurable hostsConfigurable,
@Nullable ProgressIndicator indicator,
@Nullable BuildNumber buildNumber) {
final Map<PluginId, PluginDownloader> downloaded = new HashMap<PluginId, PluginDownloader>();
final Set<String> failed = new HashSet<String>();
- for (String host : getPluginHosts(hostsConfigurable)) {
+ for (String host : getPluginHosts()) {
try {
checkPluginsHost(host, downloaded, incompatiblePlugins, true, indicator, buildNumber);
}
@@ -243,25 +241,12 @@ public final class UpdateChecker {
if (!toUpdate.isEmpty()) {
try {
final List<IdeaPluginDescriptor> process = RepositoryHelper.loadPluginsFromRepository(indicator);
- final List<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
for (IdeaPluginDescriptor loadedPlugin : process) {
final PluginId pluginId = loadedPlugin.getPluginId();
final String idString = pluginId.getIdString();
if (!toUpdate.containsKey(idString)) continue;
- final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
- if (installedPlugin == null) {
- prepareToInstall(downloaded, loadedPlugin, indicator, buildNumber);
- } else {
- final String newVersion = loadedPlugin.getVersion();
- if (PluginDownloader.compareVersionsSkipBroken(installedPlugin, newVersion) > 0) {
- updateSettings.myOutdatedPlugins.add(idString);
- if (isReadyToUpdate(idString, newVersion) && !disabledPlugins.contains(idString)) {
- prepareToInstall(downloaded, loadedPlugin, indicator, buildNumber);
- }
- }
- if (!downloaded.containsKey(pluginId)) {
- collectIncompatible(incompatiblePlugins, buildNumber, installedPlugin);
- }
+ if (!downloaded.containsKey(pluginId)) {
+ prepareToInstall(PluginDownloader.createDownloader(loadedPlugin), buildNumber, downloaded, incompatiblePlugins, true, indicator);
}
}
}
@@ -281,29 +266,52 @@ public final class UpdateChecker {
}
private static boolean isReadyToUpdate(String idString, String newVersion) {
- final String oldVersion = ourUpdatedPlugins.put(idString, newVersion);
- return oldVersion == null || StringUtil.compareVersionNumbers(newVersion, oldVersion) > 0;
- }
+ final PluginDownloader oldPlugin = ourUpdatedPlugins.get(idString);
+ return oldPlugin == null || StringUtil.compareVersionNumbers(newVersion, oldPlugin.getPluginVersion()) > 0;
+ }
+
+ private static void prepareToInstall(PluginDownloader downloader,
+ BuildNumber buildNumber,
+ Map<PluginId, PluginDownloader> downloaded,
+ Collection<IdeaPluginDescriptor> incompatiblePlugins,
+ boolean collectToUpdate,
+ ProgressIndicator indicator) throws IOException {
+ final String pluginId = downloader.getPluginId();
+ final String pluginVersion = downloader.getPluginVersion();
+ if (collectToUpdate && PluginManagerCore.getDisabledPlugins().contains(pluginId)) return;
+ final IdeaPluginDescriptor installedPlugin = PluginManager.getPlugin(PluginId.getId(pluginId));
+ if (installedPlugin == null || pluginVersion == null ||
+ PluginDownloader.compareVersionsSkipBroken(installedPlugin, pluginVersion) > 0) {
+
+ IdeaPluginDescriptor descriptor = null;
+ if (isReadyToUpdate(pluginId, pluginVersion)) {
+ descriptor = downloader.getDescriptor();
+ if (descriptor == null) {
+ if (downloader.prepareToInstall(indicator, buildNumber)) {
+ descriptor = downloader.getDescriptor();
+ }
+ ourUpdatedPlugins.put(pluginId, downloader);
+ }
+ } else {
+ final PluginDownloader oldDownloader = ourUpdatedPlugins.get(pluginId);
+ if (oldDownloader != null) {
+ downloader = oldDownloader;
+ descriptor = oldDownloader.getDescriptor();
+ }
+ }
- private static void prepareToInstall(Map<PluginId, PluginDownloader> downloaded,
- IdeaPluginDescriptor loadedPlugin,
- @Nullable ProgressIndicator indicator,
- @Nullable BuildNumber buildNumber) throws IOException {
- final PluginId pluginId = loadedPlugin.getPluginId();
- //prefer plugins from plugin hosts
- if (!downloaded.containsKey(pluginId)) {
- final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin);
- if (downloader.prepareToInstall(indicator, buildNumber)) {
- downloaded.put(pluginId, downloader);
+ if (descriptor != null &&
+ !PluginManagerCore.isIncompatible(descriptor, buildNumber) &&
+ !InstalledPluginsTableModel.wasUpdated(descriptor.getPluginId())) {
+ downloaded.put(PluginId.getId(pluginId), downloader);
}
}
- }
- private static void collectIncompatible(Collection<IdeaPluginDescriptor> incompatiblePlugins,
- BuildNumber buildNumber,
- IdeaPluginDescriptor descriptor) {
- if (incompatiblePlugins != null && descriptor != null && descriptor.isEnabled() && PluginManagerCore.isIncompatible(descriptor, buildNumber)) {
- incompatiblePlugins.add(descriptor);
+ //collect plugins which were not updated and would be incompatible with new version
+ if (incompatiblePlugins != null &&
+ installedPlugin != null && installedPlugin.isEnabled() && !downloaded.containsKey(installedPlugin.getPluginId()) &&
+ PluginManagerCore.isIncompatible(installedPlugin, buildNumber)) {
+ incompatiblePlugins.add(installedPlugin);
}
}
@@ -321,14 +329,10 @@ public final class UpdateChecker {
}
}
- private static List<String> getPluginHosts(@Nullable PluginHostsConfigurable hostsConfigurable) {
- final ArrayList<String> hosts = new ArrayList<String>();
- if (hostsConfigurable != null) {
- hosts.addAll(hostsConfigurable.getPluginsHosts());
- }
- else {
- hosts.addAll(UpdateSettings.getInstance().myPluginHosts);
- }
+ private static List<String> getPluginHosts() {
+ ArrayList<String> hosts = new ArrayList<String>();
+ hosts.addAll(UpdateSettings.getInstance().myPluginHosts);
+ ContainerUtil.addIfNotNull(ApplicationInfoEx.getInstanceEx().getBuiltinPluginsUrl(), hosts);
final String pluginHosts = System.getProperty("idea.plugin.hosts");
if (pluginHosts != null) {
ContainerUtil.addAll(hosts, pluginHosts.split(";"));
@@ -356,7 +360,7 @@ public final class UpdateChecker {
final Map<PluginId, PluginDownloader> downloaded,
final @Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
final boolean collectToUpdate,
- @Nullable ProgressIndicator indicator,
+ final @Nullable ProgressIndicator indicator,
final BuildNumber buildNumber) throws Exception {
InputStream inputStream = loadVersionInfo(host);
if (inputStream == null) return false;
@@ -373,7 +377,8 @@ public final class UpdateChecker {
final List<IdeaPluginDescriptor> descriptors = RepositoryHelper.loadPluginsFromDescription(inputStream, indicator);
for (IdeaPluginDescriptor descriptor : descriptors) {
((PluginNode)descriptor).setRepositoryName(host);
- downloaded.put(descriptor.getPluginId(), PluginDownloader.createDownloader(descriptor));
+ prepareToInstall(PluginDownloader.createDownloader(descriptor), buildNumber, downloaded, incompatiblePlugins, collectToUpdate,
+ indicator);
}
boolean success = true;
@@ -420,17 +425,8 @@ public final class UpdateChecker {
if (progressIndicator != null) {
progressIndicator.setText2(finalPluginUrl);
}
- final PluginDownloader downloader = new PluginDownloader(pluginId, finalPluginUrl, pluginVersion);
- final IdeaPluginDescriptor loadedPlugin = PluginManager.getPlugin(PluginId.getId(pluginId));
- if (loadedPlugin == null || pluginVersion == null ||
- PluginDownloader.compareVersionsSkipBroken(loadedPlugin, pluginVersion) > 0) {
- if (isReadyToUpdate(pluginId, pluginVersion) && downloader.prepareToInstall(progressIndicator, buildNumber)) {
- downloaded.put(PluginId.getId(pluginId), downloader);
- }
- }
- if (loadedPlugin != null && !downloaded.containsKey(loadedPlugin.getPluginId())) {
- collectIncompatible(incompatiblePlugins, buildNumber, loadedPlugin);
- }
+ final PluginDownloader downloader = new PluginDownloader(pluginId, finalPluginUrl, pluginVersion, null, null);
+ prepareToInstall(downloader, buildNumber, downloaded, incompatiblePlugins, collectToUpdate, indicator);
}
catch (IOException e) {
LOG.info(e);
@@ -710,17 +706,19 @@ public final class UpdateChecker {
boolean installed = false;
for (PluginDownloader downloader : downloaders) {
if (getDisabledToUpdatePlugins().contains(downloader.getPluginId())) continue;
- final IdeaPluginDescriptor descriptor = downloader.getDescriptor();
- if (descriptor != null) {
- try {
- InstalledPluginsTableModel.updateExistingPlugin(descriptor, PluginManager.getPlugin(descriptor.getPluginId()));
- downloader.install();
- installed = true;
- }
- catch (IOException e) {
- LOG.info(e);
+ try {
+ if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
+ final IdeaPluginDescriptor descriptor = downloader.getDescriptor();
+ if (descriptor != null) {
+ InstalledPluginsTableModel.updateExistingPlugin(descriptor, PluginManager.getPlugin(descriptor.getPluginId()));
+ downloader.install();
+ installed = true;
+ }
}
}
+ catch (IOException e) {
+ LOG.info(e);
+ }
}
return installed;
}
@@ -877,4 +875,33 @@ public final class UpdateChecker {
}
}
}
+
+ static String getDownloadUrl(IdeaPluginDescriptor descriptor) throws UnsupportedEncodingException {
+ String url = null;
+ if (descriptor instanceof PluginNode) {
+ url = ((PluginNode)descriptor).getDownloadUrl();
+ if (url != null) {
+ final String repositoryName = ((PluginNode)descriptor).getRepositoryName();
+ if (repositoryName != null) {
+ final VirtualFile pluginFile = PluginDownloader.findPluginFile(url, repositoryName);
+ if (pluginFile != null) {
+ url = getPluginUrl(pluginFile);
+ }
+ }
+ }
+ }
+
+ if (url == null) {
+ String uuid = ApplicationManager.getApplication() == null ?
+ UUID.randomUUID().toString() :
+ getInstallationUID(PropertiesComponent.getInstance());
+ String buildNumber = ApplicationManager.getApplication() != null
+ ? ApplicationInfo.getInstance().getApiVersion()
+ : ApplicationInfoImpl.getShadowInstance().getBuild().asString();
+ url = RepositoryHelper.getDownloadUrl() + URLEncoder.encode(descriptor.getPluginId().getIdString(), "UTF8") +
+ "&build=" + buildNumber + "&uuid=" + URLEncoder.encode(uuid, "UTF8");
+ }
+ return url;
+ }
+
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java
index cbace7534322..e3ee04111e95 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java
@@ -144,7 +144,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
if (myUpdatedPlugins != null && !myUpdatedPlugins.isEmpty()) {
new PluginUpdateInfoDialog(getContentPanel(), myUpdatedPlugins, true){
@Override
- protected boolean toRestart() {
+ protected boolean downloadModal() {
return true;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java
index b042f9f206c6..d7a386a5fd3b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java
@@ -127,7 +127,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
UpdateSettings settings = new UpdateSettings();
settings.loadState(UpdateSettings.getInstance().getState());
settings.UPDATE_CHANNEL_TYPE = getSelectedChannelType().getCode();
- UpdateChecker.updateAndShowResult(project, true, null, settings); //todo load configured hosts on the fly
+ UpdateChecker.updateAndShowResult(project, true, settings); //todo load configured hosts on the fly
updateLastCheckedLabel();
}
});
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
index 18c5f76b670a..394dec20f4ef 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -52,6 +52,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
myNotifications = notifications;
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
@@ -59,7 +60,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
@Nullable
@Override
- public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() != PlainTextFileType.INSTANCE) return null;
final String extension = file.getExtension();
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
index 65a04b96b9bf..722865c2ff07 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
@@ -34,13 +34,13 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.jdom.Element;
@@ -65,13 +65,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement
private final Project myProject;
private boolean myNative2AsciiForPropertiesFiles;
private Charset myDefaultCharsetForPropertiesFiles;
- private volatile long myModificationCount;
- private final ModificationTracker myModificationTracker = new ModificationTracker() {
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
- };
+ private final SimpleModificationTracker myModificationTracker = new SimpleModificationTracker();
public EncodingProjectManagerImpl(Project project, PsiDocumentManager documentManager) {
myProject = project;
@@ -136,7 +130,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement
myNative2AsciiForPropertiesFiles = Boolean.parseBoolean(element.getAttributeValue("native2AsciiForPropertiesFiles"));
myDefaultCharsetForPropertiesFiles = CharsetToolkit.forName(element.getAttributeValue("defaultCharsetForPropertiesFiles"));
- myModificationCount++;
+ myModificationTracker.incModificationCount();
}
@Override
@@ -176,7 +170,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement
}
if (!Comparing.equal(oldCharset, charset)) {
- myModificationCount++;
+ myModificationTracker.incModificationCount();
if (virtualFileOrDir != null) {
virtualFileOrDir.setCharset(virtualFileOrDir.getBOM() == null ? charset : null);
}
@@ -294,7 +288,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement
});
}
- myModificationCount++;
+ myModificationTracker.incModificationCount();
}
private static Processor<VirtualFile> createChangeCharsetProcessor() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java
index e3821821b8a7..dbf848942634 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,9 +15,8 @@
*/
package com.intellij.openapi.vfs.impl;
-import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
@@ -25,7 +24,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -42,7 +41,7 @@ class FilePointerPartNode {
volatile int useCount;
private int pointersUnder = 1; // number of alive pointers in this node plus all nodes beneath
- private static volatile boolean DEBUG = ApplicationManager.getApplication().isUnitTestMode();
+ private static final VirtualFileManager ourFileManager = VirtualFileManager.getInstance();
FilePointerPartNode(@NotNull String part, FilePointerPartNode parent, Pair<VirtualFile,String> fileAndUrl) {
this.part = part;
@@ -56,8 +55,71 @@ class FilePointerPartNode {
return part + (children.length == 0 ? "" : " -> "+children.length);
}
+ // returns the node and length of matched characters in that node, or null if there is no match
+ int position(@Nullable VirtualFile parent, boolean separator, @NotNull CharSequence childName, @NotNull FilePointerPartNode[] outNode) {
+ checkConsistency();
+
+ int partStart;
+ if (parent == null) {
+ partStart = 0;
+ outNode[0] = this;
+ }
+ else {
+ VirtualFile gparent = parent.getParent();
+ partStart = position(gparent, gparent != null && !StringUtil.equals(gparent.getNameSequence(), "/"), parent.getNameSequence(), outNode);
+ if (partStart == -1) return -1;
+ }
+
+ boolean childSeparator = false;
+ if (separator) {
+ if (partStart == outNode[0].part.length()) {
+ childSeparator = true;
+ }
+ else {
+ int sepIndex = indexOfFirstDifferentChar("/", 0, outNode[0].part, partStart);
+ if (sepIndex != 1) return -1;
+ partStart++;
+ }
+ }
+ int index = indexOfFirstDifferentChar(childName, 0, outNode[0].part, partStart);
+
+ if (index == childName.length()) {
+ return partStart+index;
+ }
+
+ if (partStart + index == outNode[0].part.length()) {
+ // go to children
+ for (FilePointerPartNode child : outNode[0].children) {
+ int childPos = child.position(null, childSeparator, childName.subSequence(index, childName.length()), outNode);
+ if (childPos != -1) return childPos;
+ }
+ }
+ // else there is no match
+ return -1;
+ }
+
+ // appends to "out" all nodes under this node whose path (beginning from this node) starts in prefix.subSequence(start), then parent.getPath(), then childName
+ void getPointersUnder(@Nullable VirtualFile parent,
+ boolean separator,
+ @NotNull CharSequence childName,
+ @NotNull List<FilePointerPartNode> out) {
+ FilePointerPartNode[] outNode = new FilePointerPartNode[1];
+ int position = position(parent, separator, childName, outNode);
+ if (position != -1) {
+ FilePointerPartNode node = outNode[0];
+ addAllPointersUnder(node, out);
+ }
+ }
+
+ private static void addAllPointersUnder(@NotNull FilePointerPartNode node, @NotNull List<FilePointerPartNode> out) {
+ if (node.leaf != null) out.add(node);
+ for (FilePointerPartNode child : node.children) {
+ addAllPointersUnder(child, out);
+ }
+ }
+
boolean getPointersUnder(@NotNull String path, int start, @NotNull List<FilePointerPartNode> out) {
- checkStructure();
+ checkConsistency();
if (pointersUnder == 0) return false;
// invariant: upper nodes are matched
int index = indexOfFirstDifferentChar(path, start);
@@ -76,12 +138,18 @@ class FilePointerPartNode {
return false;
}
- void checkStructure() {
- if (!DEBUG) return;
+ private static final boolean UNIT_TEST = ApplicationManager.getApplication().isUnitTestMode();
+ void checkConsistency() {
+ if (UNIT_TEST && !ApplicationInfoImpl.isInPerformanceTest()) {
+ doCheckConsistency();
+ }
+ }
+
+ private void doCheckConsistency() {
int childSum = 0;
for (FilePointerPartNode child : children) {
childSum += child.pointersUnder;
- child.checkStructure();
+ child.doCheckConsistency();
assert child.parent == this;
}
if (leaf != null) childSum++;
@@ -157,56 +225,68 @@ class FilePointerPartNode {
return false;
}
- private int indexOfFirstDifferentChar(@NotNull String path, int start) {
- return indexOfFirstDifferentChar(path, start, part, 0, !SystemInfo.isFileSystemCaseSensitive);
+ private int indexOfFirstDifferentChar(@NotNull CharSequence path, int start) {
+ return indexOfFirstDifferentChar(path, start, part, 0);
}
@NotNull
// returns pair.second != null always
Pair<VirtualFile, String> update() {
- VirtualFileManager fileManager = VirtualFileManager.getInstance();
-
long lastUpdated = myLastUpdated;
Pair<VirtualFile, String> fileAndUrl = myFileAndUrl;
- long fsModCount = fileManager.getModificationCount();
+ long fsModCount = ourFileManager.getModificationCount();
if (lastUpdated == fsModCount) return fileAndUrl;
VirtualFile file = fileAndUrl.first;
String url = fileAndUrl.second;
+ boolean changed = false;
if (url == null) {
url = file.getUrl();
if (!file.isValid()) file = null;
+ changed = true;
}
boolean fileIsValid = file != null && file.isValid();
if (file != null && !fileIsValid) {
file = null;
+ changed = true;
}
if (file == null) {
- file = fileManager.findFileByUrl(url);
+ file = ourFileManager.findFileByUrl(url);
fileIsValid = file != null && file.isValid();
+ if (file != null) {
+ changed = true;
+ }
}
if (file != null) {
if (fileIsValid) {
url = file.getUrl(); // refresh url, it can differ
+ changed |= !url.equals(fileAndUrl.second);
}
else {
file = null; // can't find, try next time
+ changed = true;
}
}
- assert url != null;
- Pair<VirtualFile, String> result = Pair.create(file, url);
- myFileAndUrl = result;
+ Pair<VirtualFile, String> result;
+ if (changed) {
+ result = Pair.create(file, url);
+ myFileAndUrl = result;
+ }
+ else {
+ result = fileAndUrl;
+ }
myLastUpdated = fsModCount;
return result;
}
- private static int indexOfFirstDifferentChar(@NotNull String s1, int start1, @NotNull String s2, int start2, boolean ignoreCase) {
+ private static int indexOfFirstDifferentChar(@NotNull CharSequence s1, int start1, @NotNull String s2, int start2) {
+ boolean ignoreCase = !SystemInfo.isFileSystemCaseSensitive;
int len1 = s1.length();
int len2 = s2.length();
while (start1 < len1 && start2 < len2) {
char c1 = s1.charAt(start1);
char c2 = s2.charAt(start2);
- if (ignoreCase ? !StringUtil.charsEqualIgnoreCase(c1, c2) : c1 != c2) {
+ if (!StringUtil.charsEqual(c1, c2, ignoreCase)) {
return start1;
}
start1++;
@@ -231,16 +311,4 @@ class FilePointerPartNode {
int getPointersUnder() {
return pointersUnder;
}
-
- @TestOnly
- public static void pushDebug(boolean newDebug, @NotNull Disposable disposable) {
- final boolean oldDebug = DEBUG;
- DEBUG = newDebug;
- Disposer.register(disposable, new Disposable() {
- @Override
- public void dispose() {
- DEBUG = oldDebug;
- }
- });
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
index c5617e426b3c..8c36b3129fbb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,30 +30,34 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Function;
+import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.io.URLUtil;
import com.intellij.util.messages.MessageBus;
import gnu.trove.THashMap;
import gnu.trove.TObjectIntHashMap;
+import gnu.trove.TObjectIntProcedure;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
+import java.util.concurrent.ConcurrentMap;
public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements ApplicationComponent, ModificationTracker, BulkFileListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl");
private final TempFileSystem TEMP_FILE_SYSTEM;
private final LocalFileSystem LOCAL_FILE_SYSTEM;
private final JarFileSystem JAR_FILE_SYSTEM;
- private volatile long myVfsModificationCounter;
// guarded by this
private final Map<VirtualFilePointerListener, FilePointerPartNode> myPointers = new LinkedHashMap<VirtualFilePointerListener, FilePointerPartNode>();
// compare by identity because VirtualFilePointerContainer has too smart equals
// guarded by myContainers
- private final Set<VirtualFilePointerContainerImpl> myContainers = ContainerUtil.<VirtualFilePointerContainerImpl>newIdentityTroveSet();
+ private final Set<VirtualFilePointerContainerImpl> myContainers = ContainerUtil.newIdentityTroveSet();
@NotNull private final VirtualFileManager myVirtualFileManager;
@NotNull private final MessageBus myBus;
private static final Comparator<String> URL_COMPARATOR = SystemInfo.isFileSystemCaseSensitive ? new Comparator<String>() {
@@ -81,12 +85,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
JAR_FILE_SYSTEM = jarFileSystem;
}
-
- @Override
- public long getModificationCount() {
- return myVfsModificationCounter;
- }
-
@Override
public void initComponent() {
}
@@ -138,9 +136,12 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
return list.toArray(new VirtualFilePointer[list.size()]);
}
- private void addPointersUnder(@NotNull String path, @NotNull List<FilePointerPartNode> out) {
+ private void addPointersUnder(VirtualFile parent,
+ boolean separator,
+ @NotNull CharSequence childName,
+ @NotNull List<FilePointerPartNode> out) {
for (FilePointerPartNode root : myPointers.values()) {
- root.getPointersUnder(path, 0, out);
+ root.getPointersUnder(parent, separator, childName, out);
}
}
@@ -153,23 +154,34 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
@Override
@NotNull
public synchronized VirtualFilePointer create(@NotNull VirtualFile file, @NotNull Disposable parent, @Nullable VirtualFilePointerListener listener) {
- return create(file, file.getUrl(), parent, listener);
+ return create(file, null, parent, listener);
}
@NotNull
- private VirtualFilePointer create(@Nullable VirtualFile file,
- @NotNull String url,
+ private VirtualFilePointer create(@Nullable("null means the pointer will be created from the (not null) url") VirtualFile file,
+ @Nullable("null means url has to be computed from the (not-null) file path") String url,
@NotNull Disposable parentDisposable,
@Nullable VirtualFilePointerListener listener) {
- String protocol;
VirtualFileSystem fileSystem;
+ String protocol;
+ String path;
if (file == null) {
- protocol = VirtualFileManager.extractProtocol(url);
- fileSystem = protocol == null ? null : myVirtualFileManager.getFileSystem(protocol);
+ int protocolEnd = url.indexOf(URLUtil.SCHEME_SEPARATOR);
+ if (protocolEnd == -1) {
+ protocol = null;
+ fileSystem = null;
+ }
+ else {
+ protocol = url.substring(0, protocolEnd);
+ fileSystem = myVirtualFileManager.getFileSystem(protocol);
+ }
+ path = url.substring(protocolEnd + URLUtil.SCHEME_SEPARATOR.length());
}
else {
- protocol = null;
fileSystem = file.getFileSystem();
+ protocol = fileSystem.getProtocol();
+ path = file.getPath();
+ url = VirtualFileManager.constructUrl(protocol, path);
}
if (fileSystem == TEMP_FILE_SYSTEM) {
@@ -178,22 +190,24 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
return new IdentityVirtualFilePointer(found, url);
}
- if (fileSystem != LOCAL_FILE_SYSTEM && fileSystem != JAR_FILE_SYSTEM) {
+ boolean isJar = fileSystem == JAR_FILE_SYSTEM;
+ if (fileSystem != LOCAL_FILE_SYSTEM && !isJar) {
// we are unable to track alien file systems for now
VirtualFile found = fileSystem == null ? null : file != null ? file : VirtualFileManager.getInstance().findFileByUrl(url);
// if file is null, this pointer will never be alive
return getOrCreateIdentity(url, found);
}
- String path;
if (file == null) {
- path = VirtualFileManager.extractPath(url);
- path = cleanupPath(path, protocol);
- url = VirtualFileManager.constructUrl(protocol, path);
- }
- else {
- path = file.getPath(); // url has come from VirtualFile.getUrl() and is good enough
+ String cleanPath = cleanupPath(path, isJar);
+ // if newly created path is the same as substringed from url one then the url did not change, we can reuse it
+ //noinspection StringEquality
+ if (cleanPath != path) {
+ url = VirtualFileManager.constructUrl(protocol, cleanPath);
+ path = cleanPath;
+ }
}
+ // else url has come from VirtualFile.getPath() and is good enough
VirtualFilePointerImpl pointer = getOrCreate(parentDisposable, listener, path, Pair.create(file, url));
DelegatingDisposable.registerDisposable(parentDisposable, pointer);
@@ -211,9 +225,10 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
return pointer;
}
- private static String cleanupPath(@NotNull String path, @NotNull String protocol) {
+ @NotNull
+ private static String cleanupPath(@NotNull String path, boolean isJar) {
path = FileUtil.normalize(path);
- path = trimTrailingSeparators(path, protocol.equals(JarFileSystem.PROTOCOL));
+ path = trimTrailingSeparators(path, isJar);
return path;
}
@@ -250,7 +265,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
pointer.myNode.incrementUsageCount(1);
- root.checkStructure();
+ root.checkConsistency();
return pointer;
}
@@ -267,7 +282,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
for (Map.Entry<VirtualFilePointerListener, FilePointerPartNode> entry : myPointers.entrySet()) {
FilePointerPartNode root = entry.getValue();
ArrayList<FilePointerPartNode> left = new ArrayList<FilePointerPartNode>();
- root.getPointersUnder("", 0, left);
+ root.getPointersUnder(null, false, "", left);
if (!left.isEmpty()) {
VirtualFilePointerImpl p = left.get(0).leaf;
try {
@@ -314,10 +329,10 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
}
- private void addAllPointers(Collection<VirtualFilePointerImpl> pointers) {
+ private void addAllPointers(@NotNull Collection<VirtualFilePointerImpl> pointers) {
List<FilePointerPartNode> out = new ArrayList<FilePointerPartNode>();
for (FilePointerPartNode root : myPointers.values()) {
- root.getPointersUnder("", 0, out);
+ root.getPointersUnder(null, false, "", out);
}
for (FilePointerPartNode node : out) {
pointers.add(node.leaf);
@@ -328,10 +343,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
public void dispose() {
}
- private void incModificationCounter() {
- myVfsModificationCounter++;
- }
-
@Override
@NotNull
public VirtualFilePointerContainer createContainer(@NotNull Disposable parent) {
@@ -362,6 +373,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
}
+ @Override
@NonNls
@NotNull
public String toString() {
@@ -371,9 +383,9 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
return virtualFilePointerContainer;
}
- @Nullable private List<EventDescriptor> myEvents = Collections.emptyList();
- @Nullable private List<FilePointerPartNode> myPointersToUpdateUrl = Collections.emptyList();
- @Nullable private List<FilePointerPartNode> myPointersToFire = Collections.emptyList();
+ private List<EventDescriptor> myEvents = Collections.emptyList();
+ private List<FilePointerPartNode> myPointersToUpdateUrl = Collections.emptyList();
+ private List<FilePointerPartNode> myPointersToFire = Collections.emptyList();
@Override
public void before(@NotNull final List<? extends VFileEvent> events) {
@@ -382,30 +394,28 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
VirtualFilePointer[] toFirePointers;
synchronized (this) {
- incModificationCounter();
+ incModificationCount();
for (VFileEvent event : events) {
if (event instanceof VFileDeleteEvent) {
final VFileDeleteEvent deleteEvent = (VFileDeleteEvent)event;
- String path = deleteEvent.getFile().getPath();
- addPointersUnder(path, toFireEvents);
+ addPointersUnder(deleteEvent.getFile(), false, "", toFireEvents);
+
}
else if (event instanceof VFileCreateEvent) {
final VFileCreateEvent createEvent = (VFileCreateEvent)event;
- String url = createEvent.getPath();
- addPointersUnder(url, toFireEvents);
+ addPointersUnder(createEvent.getParent(), true, createEvent.getChildName(), toFireEvents);
}
else if (event instanceof VFileCopyEvent) {
final VFileCopyEvent copyEvent = (VFileCopyEvent)event;
- String url = copyEvent.getNewParent().getPath() + "/" + copyEvent.getFile().getName();
- addPointersUnder(url, toFireEvents);
+ addPointersUnder(copyEvent.getNewParent(), true, copyEvent.getFile().getName(), toFireEvents);
}
else if (event instanceof VFileMoveEvent) {
final VFileMoveEvent moveEvent = (VFileMoveEvent)event;
VirtualFile eventFile = moveEvent.getFile();
- addPointersUnder(moveEvent.getNewParent().getPath() + "/" + eventFile.getName(), toFireEvents);
+ addPointersUnder(moveEvent.getNewParent(), true, eventFile.getName(), toFireEvents);
List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>();
- addPointersUnder(eventFile.getPath(), nodes);
+ addPointersUnder(eventFile, false, "", nodes);
for (FilePointerPartNode pair : nodes) {
VirtualFile file = pair.leaf.getFile();
if (file != null) {
@@ -418,10 +428,10 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) {
VirtualFile eventFile = change.getFile();
VirtualFile parent = eventFile.getParent(); // e.g. for LightVirtualFiles
- addPointersUnder((parent == null ? "" : parent.getPath()) + "/" + change.getNewValue(), toFireEvents);
+ addPointersUnder(parent, true, change.getNewValue().toString(), toFireEvents);
List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>();
- addPointersUnder(eventFile.getPath(), nodes);
+ addPointersUnder(eventFile, false, "", nodes);
for (FilePointerPartNode pair : nodes) {
VirtualFile file = pair.leaf.getFile();
if (file != null) {
@@ -463,7 +473,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
@Override
public void after(@NotNull final List<? extends VFileEvent> events) {
- incModificationCounter();
+ incModificationCount();
for (FilePointerPartNode node : myPointersToUpdateUrl) {
synchronized (this) {
@@ -508,7 +518,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
myEvents = Collections.emptyList();
myPointersToFire = Collections.emptyList();
for (FilePointerPartNode root : myPointers.values()) {
- root.checkStructure();
+ root.checkConsistency();
}
}
@@ -518,43 +528,47 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
myPointers.remove(listener);
}
else {
- myPointers.get(listener).checkStructure();
+ myPointers.get(listener).checkConsistency();
}
}
private static class DelegatingDisposable implements Disposable {
- private static final Map<Disposable, DelegatingDisposable> ourInstances = new IdentityHashMap<Disposable, DelegatingDisposable>();
+ private static final ConcurrentMap<Disposable, DelegatingDisposable> ourInstances = new ConcurrentHashMap<Disposable, DelegatingDisposable>(ContainerUtil.<Disposable>identityStrategy());
private final TObjectIntHashMap<VirtualFilePointerImpl> myCounts = new TObjectIntHashMap<VirtualFilePointerImpl>();
private final Disposable myParent;
- private DelegatingDisposable(Disposable parent) {
+ private DelegatingDisposable(@NotNull Disposable parent) {
myParent = parent;
}
- static void registerDisposable(Disposable parentDisposable, VirtualFilePointerImpl pointer) {
- synchronized (ourInstances) {
- DelegatingDisposable result = ourInstances.get(parentDisposable);
- if (result == null) {
- ourInstances.put(parentDisposable, result = new DelegatingDisposable(parentDisposable));
+ static void registerDisposable(@NotNull Disposable parentDisposable, @NotNull VirtualFilePointerImpl pointer) {
+ DelegatingDisposable result = ourInstances.get(parentDisposable);
+ if (result == null) {
+ DelegatingDisposable newDisposable = new DelegatingDisposable(parentDisposable);
+ result = ConcurrencyUtil.cacheOrGet(ourInstances, parentDisposable, newDisposable);
+ if (result == newDisposable) {
Disposer.register(parentDisposable, result);
}
+ }
+ synchronized (result) {
result.myCounts.put(pointer, result.myCounts.get(pointer) + 1);
}
}
@Override
public void dispose() {
- synchronized (ourInstances) {
- ourInstances.remove(myParent);
-
- for (Object o : myCounts.keys()) {
- VirtualFilePointerImpl pointer = (VirtualFilePointerImpl)o;
- int disposeCount = myCounts.get(pointer);
- int after = pointer.myNode.incrementUsageCount(-disposeCount + 1);
- LOG.assertTrue(after > 0, after);
- pointer.dispose();
- }
+ ourInstances.remove(myParent);
+ synchronized (this) {
+ myCounts.forEachEntry(new TObjectIntProcedure<VirtualFilePointerImpl>() {
+ @Override
+ public boolean execute(VirtualFilePointerImpl pointer, int disposeCount) {
+ int after = pointer.myNode.incrementUsageCount(-disposeCount + 1);
+ LOG.assertTrue(after > 0, after);
+ pointer.dispose();
+ return true;
+ }
+ });
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java
index e2a43ce4a52f..6684090a218d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/DefaultRemoteContentProvider.java
@@ -30,6 +30,7 @@ import com.intellij.util.Url;
import com.intellij.util.io.UrlConnectionUtil;
import com.intellij.util.net.ssl.CertificateManager;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.io.Responses;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -69,6 +70,7 @@ public class DefaultRemoteContentProvider extends RemoteContentProvider {
String presentableUrl = StringUtil.trimMiddle(url.trimParameters().toDecodedForm(), 40);
callback.setProgressText(VfsBundle.message("download.progress.connecting", presentableUrl), true);
HttpURLConnection connection = (HttpURLConnection)new URL(url.toExternalForm()).openConnection();
+ connection.setRequestProperty("User-Agent", Responses.getServerHeaderValue());
connection.setConnectTimeout(CONNECT_TIMEOUT);
connection.setReadTimeout(READ_TIMEOUT);
if (connection instanceof HttpsURLConnection) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
index 822552576a62..f2c9bf472a6b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
@@ -141,4 +141,11 @@ public class RefreshQueueImpl extends RefreshQueue {
public void processSingleEvent(@NotNull VFileEvent event) {
new RefreshSessionImpl(Collections.singletonList(event)).launch();
}
+
+ public static boolean isRefreshInProgress() {
+ RefreshQueueImpl refreshQueue = (RefreshQueueImpl)RefreshQueue.getInstance();
+ synchronized (refreshQueue.mySessions) {
+ return !refreshQueue.mySessions.isEmpty();
+ }
+ }
} \ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java
index 99eca70ed7db..15f6b6475b77 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/FileNameCache.java
@@ -91,6 +91,7 @@ public class FileNameCache {
@NotNull
private static IntObjectLinkedMap.MapEntry<CharSequence> getEntry(int id) {
+ assert id > 0;
final int stripe = calcStripeIdFromNameId(id);
IntSLRUCache<IntObjectLinkedMap.MapEntry<CharSequence>> cache = ourNameCache[stripe];
//noinspection SynchronizationOnLocalVariableOrMethodParameter
@@ -109,10 +110,6 @@ public class FileNameCache {
return getEntry(nameId).value;
}
- static int compareNameTo(int nameId, @NotNull CharSequence name, boolean ignoreCase) {
- return VirtualFileSystemEntry.compareNames(getEntry(nameId).value, name, ignoreCase);
- }
-
@NotNull
static char[] appendPathOnFileSystem(int nameId, @Nullable VirtualFileSystemEntry parent, int accumulatedPathLength, @NotNull int[] positionRef) {
IntObjectLinkedMap.MapEntry<CharSequence> entry = getEntry(nameId);
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SubList.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SubList.java
deleted file mode 100644
index e84a2c2cfe1f..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SubList.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.vfs.newvfs.impl;
-
-import com.intellij.util.ArrayUtil;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.AbstractList;
-import java.util.Arrays;
-import java.util.RandomAccess;
-
-class SubList<E> extends AbstractList<E> implements RandomAccess {
- private final E[] a;
- private final int start;
- private final int end;
-
- SubList(@NotNull E[] array, int start, int end) {
- a = array;
- this.start = start;
- this.end = end;
- assert start <= a.length;
- assert end <= a.length;
- assert start <= end && start >= 0;
- }
-
- @Override
- public int size() {
- return end - start;
- }
-
- @NotNull
- @Override
- public Object[] toArray() {
- return Arrays.copyOfRange(a, start, end);
- }
-
- @NotNull
- @Override
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(@NotNull T[] a) {
- int size = size();
- if (a.length < size) {
- return Arrays.copyOfRange(this.a, start, end, (Class<? extends T[]>)a.getClass());
- }
- System.arraycopy(this.a, start, a, 0, size);
- if (a.length > size) {
- a[size] = null;
- }
- return a;
- }
-
- @Override
- public E get(int index) {
- return a[index+start];
- }
-
- @Override
- public int indexOf(Object o) {
- return ArrayUtil.indexOf(a, o, start, end);
- }
-
- @Override
- public boolean contains(Object o) {
- return indexOf(o) != -1;
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/UserDataInterner.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/UserDataInterner.java
new file mode 100644
index 000000000000..f8da08d33198
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/UserDataInterner.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vfs.newvfs.impl;
+
+import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.containers.ConcurrentWeakHashMap;
+import com.intellij.util.keyFMap.KeyFMap;
+import com.intellij.util.keyFMap.OneElementFMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.nio.charset.Charset;
+
+/**
+ * @author peter
+ */
+class UserDataInterner {
+ private static final ConcurrentWeakHashMap<OneElementFMap, OneElementFMap> ourCache = new ConcurrentWeakHashMap<OneElementFMap, OneElementFMap>();
+
+ static KeyFMap internUserData(@NotNull KeyFMap map) {
+ if (map instanceof OneElementFMap && shouldIntern((OneElementFMap)map)) {
+ return ConcurrencyUtil.cacheOrGet(ourCache, (OneElementFMap)map, (OneElementFMap)map);
+ }
+ return map;
+ }
+
+ private static boolean shouldIntern(OneElementFMap map) {
+ Object value = map.getValue();
+ return value instanceof Enum || value instanceof Boolean || value instanceof Charset;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java
new file mode 100644
index 000000000000..ceb3a779f596
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vfs.newvfs.impl;
+
+import com.intellij.openapi.application.ApplicationAdapter;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.vfs.InvalidVirtualFileAccessException;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.SmartFMap;
+import com.intellij.util.concurrency.AtomicFieldUpdater;
+import com.intellij.util.containers.ConcurrentBitSet;
+import com.intellij.util.containers.ConcurrentIntObjectMap;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
+import com.intellij.util.keyFMap.KeyFMap;
+import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
+import gnu.trove.THashSet;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+import static com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry.ALL_FLAGS_MASK;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+/**
+ * The place where all the data is stored for VFS parts loaded into a memory: name-ids, flags, user data, children.
+ *
+ * The purpose is to avoid holding this data in separate immortal file/directory objects because that involves space overhead, significant
+ * when there are hundreds of thousands of files.
+ *
+ * The data is stored per-id in blocks of {@link #SEGMENT_SIZE}. File ids in one project tend to cluster together,
+ * so the overhead for non-loaded id should not be large in most cases.
+ *
+ * File objects are still created if needed. There might be several objects for the same file, so equals() should be used instead of ==.
+ *
+ * The lifecycle of a file object is as follows:
+ *
+ * 1. The file has not been instantiated yet, so {@link #getFileById} returns null.
+ *
+ * 2. A file is explicitly requested by calling getChildren or findChild on its parent. The parent initializes all the necessary data (in a thread-safe context)
+ * and creates the file instance. See {@link #initFile}
+ *
+ * 3. After that the file is live, an object representing it can be retrieved any time from its parent. File system roots are
+ * kept on hard references in {@link com.intellij.openapi.vfs.newvfs.persistent.PersistentFS}
+ *
+ * 4. If a file is deleted (invalidated), then its data is not needed anymore, and should be removed. But this can only happen after
+ * all the listener have been notified about the file deletion and have had their chance to look at the data the last time. See {@link #killInvalidatedFiles()}
+ *
+ * 5. The file with removed data is marked as "dead" (see {@link #ourDeadMarker}, any access to it will throw {@link com.intellij.openapi.vfs.InvalidVirtualFileAccessException}
+ * Dead ids won't be reused in the same session of the IDE.
+ *
+ * @author peter
+ */
+public class VfsData {
+ private static final int SEGMENT_BITS = 9;
+ private static final int SEGMENT_SIZE = 1 << SEGMENT_BITS;
+ private static final int OFFSET_MASK = SEGMENT_SIZE - 1;
+ private static final Object ourDeadMarker = new String("dead file");
+
+ private static final ConcurrentIntObjectMap<Segment> ourSegments = new StripedLockIntObjectConcurrentHashMap<Segment>();
+ private static final ConcurrentBitSet ourInvalidatedIds = new ConcurrentBitSet();
+ private static TIntHashSet ourDyingIds = new TIntHashSet();
+ private static volatile SmartFMap<VirtualFileSystemEntry, VirtualDirectoryImpl> ourChangedParents = SmartFMap.emptyMap();
+
+ static {
+ ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() {
+ @Override
+ public void writeActionFinished(Object action) {
+ // after top-level write action is finished, all the deletion listeners should have processed the deleted files
+ // and their data is considered safe to remove. From this point on accessing a removed file will result in an exception.
+ if (!ApplicationManager.getApplication().isWriteAccessAllowed()) {
+ killInvalidatedFiles();
+ }
+ }
+ });
+ }
+
+ private static void killInvalidatedFiles() {
+ synchronized (ourDeadMarker) {
+ if (!ourDyingIds.isEmpty()) {
+ for (int id : ourDyingIds.toArray()) {
+ assertNotNull(getSegment(id, false)).myObjectArray.set(getOffset(id), ourDeadMarker);
+ ourChangedParents = ourChangedParents.minus(new VirtualFileImpl(id, null, null));
+ }
+ ourDyingIds = new TIntHashSet();
+ }
+ }
+ }
+
+ @Nullable
+ public static VirtualFileSystemEntry getFileById(int id, VirtualDirectoryImpl parent) {
+ Segment segment = getSegment(id, false);
+ if (segment == null) return null;
+
+ int offset = getOffset(id);
+ Object o = segment.myObjectArray.get(offset);
+ if (o == null) return null;
+
+ if (o == ourDeadMarker) {
+ throw reportDeadFileAccess(new VirtualFileImpl(id, segment, parent));
+ }
+ assert segment.getNameId(id) > 0;
+
+ return o instanceof DirectoryData ? new VirtualDirectoryImpl(id, segment, (DirectoryData)o, parent, parent.getFileSystem())
+ : new VirtualFileImpl(id, segment, parent);
+ }
+
+ private static InvalidVirtualFileAccessException reportDeadFileAccess(VirtualFileSystemEntry file) {
+ return new InvalidVirtualFileAccessException("Accessing dead virtual file: " + file.getUrl());
+ }
+
+ private static int getOffset(int id) {
+ return id & OFFSET_MASK;
+ }
+
+ @Nullable @Contract("_,true->!null")
+ public static Segment getSegment(int id, boolean create) {
+ int key = id >>> SEGMENT_BITS;
+ Segment segment = ourSegments.get(key);
+ if (segment != null || !create) return segment;
+ return ourSegments.cacheOrGet(key, new Segment());
+ }
+
+ public static void initFile(int id, Segment segment, int nameId, @NotNull Object data) {
+ assert id > 0;
+ int offset = getOffset(id);
+
+ segment.setNameId(id, nameId);
+
+ if (segment.myObjectArray.get(offset) != null) {
+ throw new AssertionError("File already created");
+ }
+ segment.myObjectArray.set(offset, data);
+ }
+
+ static CharSequence getNameByFileId(int id) {
+ return FileNameCache.getVFileName(assertNotNull(getSegment(id, false)).getNameId(id));
+ }
+
+ static boolean isFileValid(int id) {
+ return !ourInvalidatedIds.get(id);
+ }
+
+ @Nullable
+ static VirtualDirectoryImpl getChangedParent(VirtualFileSystemEntry child) {
+ SmartFMap<VirtualFileSystemEntry, VirtualDirectoryImpl> map = ourChangedParents;
+ return map == (SmartFMap)SmartFMap.emptyMap() ? null : map.get(child);
+ }
+
+ static void changeParent(VirtualFileSystemEntry child, VirtualDirectoryImpl parent) {
+ synchronized (ourDeadMarker) {
+ ourChangedParents = ourChangedParents.plus(child, parent);
+ }
+ }
+
+ static void invalidateFile(int id) {
+ ourInvalidatedIds.set(id);
+ synchronized (ourDeadMarker) {
+ ourDyingIds.add(id);
+ }
+ }
+
+ public static class Segment {
+ // user data for files, DirectoryData for folders
+ final AtomicReferenceArray<Object> myObjectArray = new AtomicReferenceArray<Object>(SEGMENT_SIZE);
+
+ // <nameId, flags> pairs, "flags" part containing flags per se and modification stamp
+ private final AtomicIntegerArray myIntArray = new AtomicIntegerArray(SEGMENT_SIZE * 2);
+
+ int getNameId(int fileId) {
+ return myIntArray.get(getOffset(fileId) * 2);
+ }
+
+ void setNameId(int fileId, int nameId) {
+ myIntArray.set(getOffset(fileId) * 2, nameId);
+ }
+
+ void setUserMap(int fileId, KeyFMap map) {
+ myObjectArray.set(getOffset(fileId), map);
+ }
+
+ KeyFMap getUserMap(VirtualFileSystemEntry file) {
+ Object o = myObjectArray.get(getOffset(Math.abs(file.getId())));
+ if (!(o instanceof KeyFMap)) {
+ throw reportDeadFileAccess(file);
+ }
+ return (KeyFMap)o;
+ }
+
+ boolean changeUserMap(int fileId, KeyFMap oldMap, KeyFMap newMap) {
+ return myObjectArray.compareAndSet(getOffset(fileId), oldMap, newMap);
+ }
+
+ boolean getFlag(int id, int mask) {
+ assert (mask & ~ALL_FLAGS_MASK) == 0 : "Unexpected flag";
+ return (myIntArray.get(getOffset(id) * 2 + 1) & mask) != 0;
+ }
+
+ void setFlag(int id, int mask, boolean value) {
+ assert (mask & ~ALL_FLAGS_MASK) == 0 : "Unexpected flag";
+ int offset = getOffset(id) * 2 + 1;
+ while (true) {
+ int oldInt = myIntArray.get(offset);
+ int updated = value ? (oldInt | mask) : (oldInt & ~mask);
+ if (myIntArray.compareAndSet(offset, oldInt, updated)) {
+ return;
+ }
+ }
+ }
+
+ long getModificationStamp(int id) {
+ return myIntArray.get(getOffset(id) * 2 + 1) & ~ALL_FLAGS_MASK;
+ }
+
+ void setModificationStamp(int id, long stamp) {
+ int offset = getOffset(id) * 2 + 1;
+ while (true) {
+ int oldInt = myIntArray.get(offset);
+ int updated = (oldInt & ALL_FLAGS_MASK) | ((int)stamp & ~ALL_FLAGS_MASK);
+ if (myIntArray.compareAndSet(offset, oldInt, updated)) {
+ return;
+ }
+ }
+ }
+
+ }
+
+ // non-final field accesses are synchronized on this instance, but this happens in VirtualDirectoryImpl
+ public static class DirectoryData {
+ private static final AtomicFieldUpdater<DirectoryData, KeyFMap> updater = AtomicFieldUpdater.forFieldOfType(DirectoryData.class, KeyFMap.class);
+ volatile KeyFMap myUserMap = KeyFMap.EMPTY_MAP;
+ int[] myChildrenIds = ArrayUtil.EMPTY_INT_ARRAY;
+ private THashSet<String> myAdoptedNames;
+
+ VirtualFileSystemEntry[] getFileChildren(int fileId, VirtualDirectoryImpl parent) {
+ assert fileId > 0;
+ VirtualFileSystemEntry[] children = new VirtualFileSystemEntry[myChildrenIds.length];
+ for (int i = 0; i < myChildrenIds.length; i++) {
+ children[i] = assertNotNull(getFileById(myChildrenIds[i], parent));
+ }
+ return children;
+ }
+
+ boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
+ return updater.compareAndSet(this, oldMap, newMap);
+ }
+
+ boolean isAdoptedName(String name) {
+ return myAdoptedNames != null && myAdoptedNames.contains(name);
+ }
+
+ void removeAdoptedName(String name) {
+ if (myAdoptedNames != null) {
+ myAdoptedNames.remove(name);
+ if (myAdoptedNames.isEmpty()) {
+ myAdoptedNames = null;
+ }
+ }
+ }
+ void addAdoptedName(String name, boolean caseSensitive) {
+ if (myAdoptedNames == null) {
+ //noinspection unchecked
+ myAdoptedNames = new THashSet<String>(0, caseSensitive ? TObjectHashingStrategy.CANONICAL : CaseInsensitiveStringHashingStrategy.INSTANCE);
+ }
+ myAdoptedNames.add(name);
+ }
+
+ List<String> getAdoptedNames() {
+ return myAdoptedNames == null ? Collections.<String>emptyList() : ContainerUtil.newArrayList(myAdoptedNames);
+ }
+ }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java
new file mode 100644
index 000000000000..b6fa97092059
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vfs.newvfs.impl;
+
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.impl.ApplicationImpl;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
+import com.intellij.util.PathUtil;
+import com.intellij.util.SystemProperties;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Set;
+
+public class VfsRootAccess {
+ private static final boolean SHOULD_PERFORM_ACCESS_CHECK = System.getenv("NO_FS_ROOTS_ACCESS_CHECK") == null;
+ // we don't want test subclasses to accidentally remove allowed files, added by base classes
+ private static final Set<String> ourAdditionalRoots = new THashSet<String>();
+ private static boolean insideGettingRoots;
+
+ @TestOnly
+ static void assertAccessInTests(@NotNull VirtualFileSystemEntry child, @NotNull NewVirtualFileSystem delegate) {
+ final Application application = ApplicationManager.getApplication();
+ if (SHOULD_PERFORM_ACCESS_CHECK &&
+ application.isUnitTestMode() &&
+ application instanceof ApplicationImpl &&
+ ((ApplicationImpl)application).isComponentsCreated()) {
+ if (delegate != LocalFileSystem.getInstance() && delegate != JarFileSystem.getInstance()) {
+ return;
+ }
+
+ // root' children are loaded always
+ if (child.getParent() == null || child.getParent().getParent() == null) {
+ return;
+ }
+
+ Set<String> allowed = ApplicationManager.getApplication().runReadAction(new Computable<Set<String>>() {
+ @Override
+ public Set<String> compute() {
+ return allowedRoots();
+ }
+ });
+ boolean isUnder = allowed == null || allowed.isEmpty();
+
+ if (!isUnder) {
+ String childPath = child.getPath();
+ if (delegate == JarFileSystem.getInstance()) {
+ VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(child);
+ assert local != null : child;
+ childPath = local.getPath();
+ }
+ for (String root : allowed) {
+ if (FileUtil.startsWith(childPath, root)) {
+ isUnder = true;
+ break;
+ }
+ if (root.startsWith(JarFileSystem.PROTOCOL_PREFIX)) {
+ String rootLocalPath = FileUtil.toSystemIndependentName(PathUtil.toPresentableUrl(root));
+ isUnder = FileUtil.startsWith(childPath, rootLocalPath);
+ if (isUnder) break;
+ }
+ }
+ }
+
+ assert isUnder : "File accessed outside allowed roots: " + child + ";\nAllowed roots: " + new ArrayList<String>(allowed);
+ }
+ }
+
+ // null means we were unable to get roots, so do not check access
+ @Nullable
+ @TestOnly
+ private static Set<String> allowedRoots() {
+ if (insideGettingRoots) return null;
+
+ Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
+ if (openProjects.length == 0) return null;
+
+ final Set<String> allowed = new THashSet<String>();
+ allowed.add(FileUtil.toSystemIndependentName(PathManager.getHomePath()));
+
+ try {
+ URL outUrl = Application.class.getResource("/");
+ String output = new File(outUrl.toURI()).getParentFile().getParentFile().getPath();
+ allowed.add(FileUtil.toSystemIndependentName(output));
+ }
+ catch (URISyntaxException ignored) { }
+
+ String javaHome = SystemProperties.getJavaHome();
+ allowed.add(FileUtil.toSystemIndependentName(javaHome));
+ if (SystemInfo.isMac && SystemInfo.isAppleJvm) {
+ // Apple SDK has jars in the folder _next_ to the java.home
+ allowed.add(FileUtil.toSystemIndependentName(new File(new File(javaHome).getParent(), "Classes").getPath()));
+ }
+ allowed.add(FileUtil.toSystemIndependentName(new File(FileUtil.getTempDirectory()).getParent()));
+ allowed.add(FileUtil.toSystemIndependentName(System.getProperty("java.io.tmpdir")));
+ allowed.add(FileUtil.toSystemIndependentName(SystemProperties.getUserHome()));
+
+ for (final Project project : openProjects) {
+ if (!project.isInitialized()) {
+ return null; // all is allowed
+ }
+ for (VirtualFile root : ProjectRootManager.getInstance(project).getContentRoots()) {
+ allowed.add(root.getPath());
+ }
+ for (VirtualFile root : getAllRoots(project)) {
+ allowed.add(StringUtil.trimEnd(root.getPath(), JarFileSystem.JAR_SEPARATOR));
+ }
+ String location = project.getBasePath();
+ assert location != null : project;
+ allowed.add(FileUtil.toSystemIndependentName(location));
+ }
+
+ allowed.addAll(ourAdditionalRoots);
+
+ return allowed;
+ }
+
+ @TestOnly
+ private static VirtualFile[] getAllRoots(@NotNull Project project) {
+ insideGettingRoots = true;
+ final Set<VirtualFile> roots = new THashSet<VirtualFile>();
+
+ final OrderEnumerator enumerator = ProjectRootManager.getInstance(project).orderEntries();
+ ContainerUtil.addAll(roots, enumerator.getClassesRoots());
+ ContainerUtil.addAll(roots, enumerator.getSourceRoots());
+
+ insideGettingRoots = false;
+ return VfsUtilCore.toVirtualFileArray(roots);
+ }
+
+ @TestOnly
+ public static void allowRootAccess(@NotNull String... roots) {
+ for (String root : roots) {
+ ourAdditionalRoots.add(FileUtil.toSystemIndependentName(root));
+ }
+ }
+
+ @TestOnly
+ public static void disallowRootAccess(@NotNull String... roots) {
+ for (String root : roots) {
+ ourAdditionalRoots.remove(FileUtil.toSystemIndependentName(root));
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java
index 4c6917ea6d1b..bc898a49987b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java
@@ -15,23 +15,14 @@
*/
package com.intellij.openapi.vfs.newvfs.impl;
-import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.application.impl.ApplicationImpl;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.roots.OrderEnumerator;
-import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileAttributes;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
@@ -40,21 +31,23 @@ import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
-import com.intellij.util.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.UriUtil;
import com.intellij.util.containers.ContainerUtil;
-import gnu.trove.THashSet;
+import com.intellij.util.keyFMap.KeyFMap;
+import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* @author max
@@ -65,41 +58,25 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
public static boolean CHECK = ApplicationManager.getApplication().isUnitTestMode();
static final VirtualDirectoryImpl NULL_VIRTUAL_FILE =
- new VirtualDirectoryImpl(FileNameCache.storeName("*?;%NULL"), null, LocalFileSystem.getInstance(), -42, 0) {
+ new VirtualDirectoryImpl(-42, null, null, null, LocalFileSystem.getInstance()) {
+ @Override
public String toString() {
return "NULL";
}
};
+ private final VfsData.DirectoryData myData;
+ private final NewVirtualFileSystem myFs;
- private final NewVirtualFileSystem myFS;
-
- /**
- * The array is logically divided into the two parts:
- * - left subarray for storing real child files
- * - right subarray for storing "adopted children" files.
- * "Adopted children" are fake files which are used for storing names which were accessed via findFileByName() or similar calls.
- * We have to store these unsuccessful find attempts to be able to correctly refresh in the future.
- * See usages of {@link #getSuspiciousNames()} in the {@link com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker}
- *
- * Guarded by this, files in each subarray are sorted according to the compareNameTo() comparator
- * TODO: revise the whole adopted scheme
- */
- private VirtualFileSystemEntry[] myChildren = EMPTY_ARRAY;
-
- public VirtualDirectoryImpl(@NonNls final int nameId,
- @Nullable final VirtualDirectoryImpl parent,
- @NotNull final NewVirtualFileSystem fs,
- final int id,
- @PersistentFS.Attributes final int attributes) {
- super(nameId, parent, id, attributes);
- myFS = fs;
- LOG.assertTrue(!(fs instanceof Win32LocalFileSystem));
+ public VirtualDirectoryImpl(int id, VfsData.Segment segment, VfsData.DirectoryData data, VirtualDirectoryImpl parent, NewVirtualFileSystem fs) {
+ super(id, segment, parent);
+ myData = data;
+ myFs = fs;
}
@Override
@NotNull
public NewVirtualFileSystem getFileSystem() {
- return myFS;
+ return myFs;
}
@Nullable
@@ -108,9 +85,9 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
boolean ensureCanonicalName,
@NotNull NewVirtualFileSystem delegate) {
boolean ignoreCase = !delegate.isCaseSensitive();
- Comparator comparator = getComparator(ignoreCase);
- VirtualFileSystemEntry result = doFindChild(name, ensureCanonicalName, delegate, comparator);
+ VirtualFileSystemEntry result = doFindChild(name, ensureCanonicalName, delegate, ignoreCase);
+ //noinspection UseVirtualFileEquals
if (result == NULL_VIRTUAL_FILE) {
result = doRefresh ? createAndFindChildWithEventFire(name, delegate) : null;
}
@@ -120,91 +97,53 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
if (result == null) {
- addToAdoptedChildren(!delegate.isCaseSensitive(), name, comparator);
+ synchronized (myData) {
+ addToAdoptedChildren(ignoreCase, name);
+ }
}
return result;
}
- private synchronized void addToAdoptedChildren(final boolean ignoreCase,
- @NotNull final String name,
- @NotNull Comparator comparator) {
- long r = findIndexInBoth(myChildren, name, comparator);
- int indexInReal = (int)(r >> 32);
- int indexInAdopted = (int)r;
- if (indexInAdopted >= 0) return; //already added
+ private void addToAdoptedChildren(final boolean ignoreCase, @NotNull final String name) {
+ if (myData.isAdoptedName(name)) return; //already added
if (!allChildrenLoaded()) {
- insertChildAt(new AdoptedChild(name), indexInAdopted);
+ myData.addAdoptedName(name, getFileSystem().isCaseSensitive());
}
+ int indexInReal = findIndex(myData.myChildrenIds, name, ignoreCase);
if (indexInReal >= 0) {
// there suddenly can be that we ask to add name to adopted whereas it already contains in the real part
// in this case we should remove it from there
removeFromArray(indexInReal);
}
- assertConsistency(myChildren, ignoreCase, name);
- }
-
- private static class AdoptedChild extends VirtualFileImpl {
- private final String myName;
-
- private AdoptedChild(String name) {
- super(-1, NULL_VIRTUAL_FILE, -42, -1);
- myName = name;
- }
-
- @NotNull
- @Override
- public CharSequence getNameSequence() {
- return myName;
- }
-
- @Override
- public void setNewName(@NotNull String newName) {
- throw new IncorrectOperationException();
- }
-
- @Override
- public int compareNameTo(@NotNull CharSequence name, boolean ignoreCase) {
- return compareNames(myName, name, ignoreCase);
- }
-
- @Override
- protected char[] appendPathOnFileSystem(int accumulatedPathLength, int[] positionRef) {
- char[] chars = getParent().appendPathOnFileSystem(accumulatedPathLength + 1 + myName.length(), positionRef);
- if (positionRef[0] > 0 && chars[positionRef[0] - 1] != '/') {
- chars[positionRef[0]++] = '/';
- }
- positionRef[0] = VirtualFileSystemEntry.copyString(chars, positionRef[0], myName);
- return chars;
-
- }
+ assertConsistency(ignoreCase, name);
}
@Nullable // null if there can't be a child with this name, NULL_VIRTUAL_FILE
- private synchronized VirtualFileSystemEntry doFindChildInArray(@NotNull String name, @NotNull Comparator comparator) {
- VirtualFileSystemEntry[] array = myChildren;
- long r = findIndexInBoth(array, name, comparator);
- int indexInReal = (int)(r >> 32);
- int indexInAdopted = (int)r;
- if (indexInAdopted >= 0) return NULL_VIRTUAL_FILE;
+ private VirtualFileSystemEntry doFindChildInArray(@NotNull String name, boolean ignoreCase) {
+ synchronized (myData) {
+ if (myData.isAdoptedName(name)) return NULL_VIRTUAL_FILE;
- if (indexInReal >= 0) {
- return array[indexInReal];
+ int[] array = myData.myChildrenIds;
+ int indexInReal = findIndex(array, name, ignoreCase);
+ if (indexInReal >= 0) {
+ return VfsData.getFileById(array[indexInReal], this);
+ }
+ return null;
}
- return null;
}
@Nullable // null if there can't be a child with this name, NULL_VIRTUAL_FILE if cached as absent, the file if found
private VirtualFileSystemEntry doFindChild(@NotNull String name,
boolean ensureCanonicalName,
@NotNull NewVirtualFileSystem delegate,
- @NotNull Comparator comparator) {
+ boolean ignoreCase) {
if (name.isEmpty()) {
return null;
}
- VirtualFileSystemEntry found = doFindChildInArray(name, comparator);
+ VirtualFileSystemEntry found = doFindChildInArray(name, ignoreCase);
if (found != null) return found;
if (allChildrenLoaded()) {
@@ -219,17 +158,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
if (name.isEmpty()) return null;
}
- //noinspection SynchronizeOnThis
- synchronized (this) {
+ VirtualFileSystemEntry child;
+ synchronized (myData) {
// maybe another doFindChild() sneaked in the middle
- VirtualFileSystemEntry[] array = myChildren;
- long r = findIndexInBoth(array, name, comparator);
- int indexInReal = (int)(r >> 32);
- int indexInAdopted = (int)r;
- if (indexInAdopted >= 0) return NULL_VIRTUAL_FILE;
+ if (myData.isAdoptedName(name)) return NULL_VIRTUAL_FILE;
+
+ int[] array = myData.myChildrenIds;
+ int indexInReal = findIndex(array, name, ignoreCase);
// double check
if (indexInReal >= 0) {
- return array[indexInReal];
+ return VfsData.getFileById(array[indexInReal], this);
}
// do not extract getId outside the synchronized block since it will cause a concurrency problem.
@@ -237,9 +175,9 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
if (id <= 0) {
return null;
}
- VirtualFileSystemEntry child = createChild(FileNameCache.storeName(name), id, delegate);
+ child = createChild(FileNameCache.storeName(name), id, delegate);
- VirtualFileSystemEntry[] after = myChildren;
+ int[] after = myData.myChildrenIds;
if (after != array) {
// in tests when we call assertAccessInTests it can load a huge number of files which lead to children modification
// so fall back to slow path
@@ -247,31 +185,23 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
else {
insertChildAt(child, indexInReal);
- assertConsistency(myChildren, !delegate.isCaseSensitive(), name);
+ assertConsistency(!delegate.isCaseSensitive(), name);
}
- return child;
}
- }
- private static final Comparator CASE_SENSITIVE = new Comparator() {
- @Override
- public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) {
- return -file.compareNameTo(myName, false);
- }
- };
- private static final Comparator CASE_INSENSITIVE = new Comparator() {
- @Override
- public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) {
- return -file.compareNameTo(myName, true);
+ if (!child.isDirectory()) {
+ // access check should only be called when child is actually added to the parent, otherwise it may break VirtualFilePointers validity
+ //noinspection TestOnlyProblems
+ VfsRootAccess.assertAccessInTests(child, getFileSystem());
}
- };
- @NotNull
- private static Comparator getComparator(final boolean ignoreCase) {
- return ignoreCase ? CASE_INSENSITIVE : CASE_SENSITIVE;
+
+ return child;
}
- private synchronized VirtualFileSystemEntry[] getArraySafely() {
- return myChildren;
+ private VirtualFileSystemEntry[] getArraySafely() {
+ synchronized (myData) {
+ return myData.getFileChildren(Math.abs(getId()), this);
+ }
}
@NotNull
@@ -281,15 +211,19 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
@NotNull
private VirtualFileSystemEntry createChild(int nameId, int id, @NotNull NewVirtualFileSystem delegate) {
- VirtualFileSystemEntry child;
-
final int attributes = ourPersistence.getFileAttributes(id);
- if (PersistentFS.isDirectory(attributes)) {
- child = new VirtualDirectoryImpl(nameId, this, getFileSystem(), id, attributes);
- }
- else {
- child = new VirtualFileImpl(nameId, this, id, attributes);
- }
+ VfsData.Segment segment = VfsData.getSegment(id, true);
+ VfsData.initFile(id, segment, nameId,
+ PersistentFS.isDirectory(attributes) ? new VfsData.DirectoryData() : KeyFMap.EMPTY_MAP);
+ LOG.assertTrue(!(getFileSystem() instanceof Win32LocalFileSystem));
+
+ VirtualFileSystemEntry child = VfsData.getFileById(id, this);
+ assert child != null;
+ segment.setFlag(id, IS_SYMLINK_FLAG, PersistentFS.isSymLink(attributes));
+ segment.setFlag(id, IS_SPECIAL_FLAG, PersistentFS.isSpecialFile(attributes));
+ segment.setFlag(id, IS_WRITABLE_FLAG, PersistentFS.isWritable(attributes));
+ segment.setFlag(id, IS_HIDDEN_FLAG, PersistentFS.isHidden(attributes));
+ child.updateLinkStatus();
if (delegate.markNewFilesAsDirty()) {
child.markDirty();
@@ -298,133 +232,6 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
return child;
}
-
- private static final boolean SHOULD_PERFORM_ACCESS_CHECK = System.getenv("NO_FS_ROOTS_ACCESS_CHECK") == null;
-
- // we don't want test subclasses to accidentally remove allowed files, added by base classes
- private static final List<String> ourAdditionalRoots = new ArrayList<String>();
-
- @TestOnly
- public static void allowRootAccess(@NotNull String... roots) {
- for (String root : roots) {
- ourAdditionalRoots.add(FileUtil.toSystemIndependentName(root));
- }
- }
-
- @TestOnly
- public static void disallowRootAccess(@NotNull String... roots) {
- for (String root : roots) {
- ourAdditionalRoots.remove(FileUtil.toSystemIndependentName(root));
- }
- }
-
- @TestOnly
- private static void assertAccessInTests(@NotNull VirtualFileSystemEntry child, @NotNull NewVirtualFileSystem delegate) {
- final Application application = ApplicationManager.getApplication();
- if (SHOULD_PERFORM_ACCESS_CHECK &&
- application.isUnitTestMode() &&
- application instanceof ApplicationImpl &&
- ((ApplicationImpl)application).isComponentsCreated()) {
- if (delegate != LocalFileSystem.getInstance() && delegate != JarFileSystem.getInstance()) {
- return;
- }
-
- // root' children are loaded always
- if (child.getParent() == null || child.getParent().getParent() == null) {
- return;
- }
-
- Set<String> allowed = allowedRoots();
- boolean isUnder = allowed == null || allowed.isEmpty();
-
- if (!isUnder) {
- String childPath = child.getPath();
- if (delegate == JarFileSystem.getInstance()) {
- VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(child);
- assert local != null : child;
- childPath = local.getPath();
- }
- for (String root : allowed) {
- if (FileUtil.startsWith(childPath, root)) {
- isUnder = true;
- break;
- }
- if (root.startsWith(JarFileSystem.PROTOCOL_PREFIX)) {
- String rootLocalPath = FileUtil.toSystemIndependentName(PathUtil.toPresentableUrl(root));
- isUnder = FileUtil.startsWith(childPath, rootLocalPath);
- if (isUnder) break;
- }
- }
- }
-
- assert isUnder : "File accessed outside allowed roots: " + child + ";\nAllowed roots: " + new ArrayList<String>(allowed);
- }
- }
-
- // null means we were unable to get roots, so do not check access
- @Nullable
- @TestOnly
- private static Set<String> allowedRoots() {
- if (insideGettingRoots) return null;
-
- Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
- if (openProjects.length == 0) return null;
-
- final Set<String> allowed = new THashSet<String>();
- allowed.add(FileUtil.toSystemIndependentName(PathManager.getHomePath()));
-
- try {
- URL outUrl = Application.class.getResource("/");
- String output = new File(outUrl.toURI()).getParentFile().getParentFile().getPath();
- allowed.add(FileUtil.toSystemIndependentName(output));
- }
- catch (URISyntaxException ignored) { }
-
- String javaHome = SystemProperties.getJavaHome();
- allowed.add(FileUtil.toSystemIndependentName(javaHome));
- if (SystemInfo.isMac && SystemInfo.isAppleJvm) {
- // Apple SDK has jars in the folder _next_ to the java.home
- allowed.add(FileUtil.toSystemIndependentName(new File(new File(javaHome).getParent(), "Classes").getPath()));
- }
- allowed.add(FileUtil.toSystemIndependentName(new File(FileUtil.getTempDirectory()).getParent()));
- allowed.add(FileUtil.toSystemIndependentName(System.getProperty("java.io.tmpdir")));
- allowed.add(FileUtil.toSystemIndependentName(SystemProperties.getUserHome()));
-
- for (Project project : openProjects) {
- if (!project.isInitialized()) {
- return null; // all is allowed
- }
- for (VirtualFile root : ProjectRootManager.getInstance(project).getContentRoots()) {
- allowed.add(root.getPath());
- }
- for (VirtualFile root : getAllRoots(project)) {
- allowed.add(StringUtil.trimEnd(root.getPath(), JarFileSystem.JAR_SEPARATOR));
- }
- String location = project.getBasePath();
- assert location != null : project;
- allowed.add(FileUtil.toSystemIndependentName(location));
- }
-
- allowed.addAll(ourAdditionalRoots);
-
- return allowed;
- }
-
- private static boolean insideGettingRoots;
-
- @TestOnly
- private static VirtualFile[] getAllRoots(@NotNull Project project) {
- insideGettingRoots = true;
- final Set<VirtualFile> roots = new THashSet<VirtualFile>();
-
- final OrderEnumerator enumerator = ProjectRootManager.getInstance(project).orderEntries();
- ContainerUtil.addAll(roots, enumerator.getClassesRoots());
- ContainerUtil.addAll(roots, enumerator.getSourceRoots());
-
- insideGettingRoots = false;
- return VfsUtilCore.toVirtualFileArray(roots);
- }
-
@Nullable
private VirtualFileSystemEntry createAndFindChildWithEventFire(@NotNull String name, @NotNull NewVirtualFileSystem delegate) {
final VirtualFile fake = new FakeVirtualFile(this, name);
@@ -442,82 +249,12 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
return findChild(name, true, true, getFileSystem());
}
- private static int findIndexInOneHalf(final VirtualFileSystemEntry[] array,
- int start,
- int end,
- final boolean isAdopted,
- @NotNull String name, @NotNull final Comparator comparator) {
- return binSearch(array, start, end, name, new Comparator() {
- @Override
- public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file) {
- if (isAdopted && !isAdoptedChild(file)) return 1;
- if (!isAdopted && isAdoptedChild(file)) return -1;
- return comparator.compareFileNameTo(myName, file);
- }
- });
- }
-
- // returns two int indices packed into one long. left index is for the real file array half, right is for the adopted children name array
- private static long findIndexInBoth(@NotNull VirtualFileSystemEntry[] array,
- @NotNull String name,
- @NotNull Comparator comparator) {
- int high = array.length - 1;
- if (high == -1) {
- return pack(-1, -1);
- }
- int low = 0;
- boolean startInAdopted = isAdoptedChild(array[low]);
- boolean endInAdopted = isAdoptedChild(array[high]);
- if (startInAdopted == endInAdopted) {
- int index = findIndexInOneHalf(array, low, high + 1, startInAdopted, name, comparator);
- int otherIndex = startInAdopted ? -1 : -array.length - 1;
- return startInAdopted ? pack(otherIndex, index) : pack(index, otherIndex);
- }
- boolean adopted = false;
- int cmp = -1;
- int mid = -1;
- int foundIndex = -1;
- while (low <= high) {
- mid = low + high >>> 1;
- VirtualFileSystemEntry file = array[mid];
- cmp = comparator.compareFileNameTo(name, file);
- adopted = isAdoptedChild(file);
- if (cmp == 0) {
- foundIndex = mid;
- break;
- }
- if ((adopted || cmp <= 0) && (!adopted || cmp >= 0)) {
- int indexInAdopted = findIndexInOneHalf(array, mid + 1, high + 1, true, name, comparator);
- int indexInReal = findIndexInOneHalf(array, low, mid, false, name, comparator);
- return pack(indexInReal, indexInAdopted);
- }
-
- if (cmp > 0) {
- low = mid + 1;
- }
- else {
- high = mid - 1;
- }
- }
-
- // key not found.
- if (cmp != 0) foundIndex = -low-1;
- int newStart = adopted ? low : mid + 1;
- int newEnd = adopted ? mid + 1 : high + 1;
- int theOtherHalfIndex = newStart < newEnd ? findIndexInOneHalf(array, newStart, newEnd, !adopted, name, comparator) : -newStart-1;
- return adopted ? pack(theOtherHalfIndex, foundIndex) : pack(foundIndex, theOtherHalfIndex);
- }
-
- private static long pack(int indexInReal, int indexInAdopted) {
- return (long)indexInReal << 32 | (indexInAdopted & 0xffffffffL);
- }
-
@Override
@Nullable
- public synchronized NewVirtualFile findChildIfCached(@NotNull String name) {
+ public NewVirtualFile findChildIfCached(@NotNull String name) {
final boolean ignoreCase = !getFileSystem().isCaseSensitive();
- Comparator comparator = getComparator(ignoreCase);
- VirtualFileSystemEntry found = doFindChildInArray(name, comparator);
+ VirtualFileSystemEntry found = doFindChildInArray(name, ignoreCase);
+ //noinspection UseVirtualFileEquals
return found == NULL_VIRTUAL_FILE ? null : found;
}
@@ -540,96 +277,78 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
@Override
@NotNull
- public synchronized VirtualFile[] getChildren() {
- VirtualFileSystemEntry[] children = myChildren;
+ public VirtualFile[] getChildren() {
NewVirtualFileSystem delegate = getFileSystem();
final boolean ignoreCase = !delegate.isCaseSensitive();
- if (allChildrenLoaded()) {
- assertConsistency(children, ignoreCase);
- return children;
- }
+ synchronized (myData) {
+ if (allChildrenLoaded()) {
+ assertConsistency(ignoreCase);
+ return getArraySafely();
+ }
- final boolean wasChildrenLoaded = ourPersistence.areChildrenLoaded(this);
- final FSRecords.NameId[] childrenIds = ourPersistence.listAll(this);
- VirtualFileSystemEntry[] result;
- if (childrenIds.length == 0) {
- result = EMPTY_ARRAY;
- }
- else {
- Arrays.sort(childrenIds, new java.util.Comparator<FSRecords.NameId>() {
- @Override
- public int compare(FSRecords.NameId o1, FSRecords.NameId o2) {
- CharSequence name1 = o1.name;
- CharSequence name2 = o2.name;
- int cmp = compareNames(name1, name2, ignoreCase);
- if (cmp == 0 && name1 != name2) {
- LOG.error(ourPersistence + " returned duplicate file names("+name1+","+name2+")" +
- " ignoreCase: "+ignoreCase+
- " SystemInfo.isFileSystemCaseSensitive: "+ SystemInfo.isFileSystemCaseSensitive+
- " SystemInfo.OS: "+ SystemInfo.OS_NAME+" "+SystemInfo.OS_VERSION+
- " wasChildrenLoaded: "+wasChildrenLoaded+
- " in the dir: "+VirtualDirectoryImpl.this+";" +
- " children: "+Arrays.toString(childrenIds));
+ final boolean wasChildrenLoaded = ourPersistence.areChildrenLoaded(this);
+ final FSRecords.NameId[] childrenIds = ourPersistence.listAll(this);
+ int[] result;
+ if (childrenIds.length == 0) {
+ result = ArrayUtil.EMPTY_INT_ARRAY;
+ }
+ else {
+ Arrays.sort(childrenIds, new Comparator<FSRecords.NameId>() {
+ @Override
+ public int compare(FSRecords.NameId o1, FSRecords.NameId o2) {
+ CharSequence name1 = o1.name;
+ CharSequence name2 = o2.name;
+ int cmp = compareNames(name1, name2, ignoreCase);
+ if (cmp == 0 && name1 != name2) {
+ LOG.error(ourPersistence + " returned duplicate file names("+name1+","+name2+")" +
+ " ignoreCase: "+ignoreCase+
+ " SystemInfo.isFileSystemCaseSensitive: "+ SystemInfo.isFileSystemCaseSensitive+
+ " SystemInfo.OS: "+ SystemInfo.OS_NAME+" "+SystemInfo.OS_VERSION+
+ " wasChildrenLoaded: "+wasChildrenLoaded+
+ " in the dir: "+VirtualDirectoryImpl.this+";" +
+ " children: "+Arrays.toString(childrenIds));
+ }
+ return cmp;
+ }
+ });
+ TIntHashSet prevChildren = new TIntHashSet(myData.myChildrenIds);
+ result = new int[childrenIds.length];
+ for (int i = 0; i < childrenIds.length; i++) {
+ FSRecords.NameId child = childrenIds[i];
+ result[i] = child.id;
+ prevChildren.remove(child.id);
+ if (VfsData.getFileById(child.id, this) == null) {
+ createChild(child.nameId, child.id, delegate);
}
- return cmp;
- }
- });
- result = new VirtualFileSystemEntry[childrenIds.length];
- int delegateI = 0;
- int i = 0;
-
- int cachedEnd = getAdoptedChildrenStart();
- // merge (sorted) children[0..cachedEnd) and childrenIds into the result array.
- // file that is already in children array must be copied into the result as is
- // for the file name that is new in childrenIds the file must be created and copied into result
- while (delegateI < childrenIds.length) {
- FSRecords.NameId nameId = childrenIds[delegateI];
- while (i < cachedEnd && children[i].compareNameTo(nameId.name, ignoreCase) < 0) i++; // skip files that are not in childrenIds
-
- VirtualFileSystemEntry resultFile;
- if (i < cachedEnd && children[i].compareNameTo(nameId.name, ignoreCase) == 0) {
- resultFile = children[i++];
}
- else {
- resultFile = createChild(nameId.nameId, nameId.id, delegate);
+ if (!prevChildren.isEmpty()) {
+ LOG.error("Loaded child disappeared: " +
+ "parent=" + verboseToString.fun(this) +
+ "; child=" + verboseToString.fun(VfsData.getFileById(prevChildren.toArray()[0], this)));
}
- result[delegateI++] = resultFile;
}
- assertConsistency(result, ignoreCase, children, cachedEnd, childrenIds);
- }
+ if (getId() > 0) {
+ myData.myChildrenIds = result;
+ assertConsistency(ignoreCase, childrenIds);
+ setChildrenLoaded();
+ }
- if (getId() > 0) {
- myChildren = result;
- setChildrenLoaded();
+ return getArraySafely();
}
-
- return result;
}
- private void assertConsistency(@NotNull VirtualFileSystemEntry[] array, boolean ignoreCase, @NotNull Object... details) {
- if (!CHECK) return;
- boolean allChildrenLoaded = allChildrenLoaded();
- for (int i = 0; i < array.length; i++) {
- VirtualFileSystemEntry file = array[i];
- boolean isAdopted = isAdoptedChild(file);
- assert !isAdopted || !allChildrenLoaded;
- if (isAdopted && i != array.length - 1) {
- assert isAdoptedChild(array[i + 1]);
- }
- if (i != 0) {
- VirtualFileSystemEntry prev = array[i - 1];
- CharSequence prevName = prev.getNameSequence();
- int cmp = file.compareNameTo(prevName, ignoreCase);
- if (cmp == 0) {
- error(verboseToString.fun(prev) + " equals to " + verboseToString.fun(file), array, details);
- }
-
- if (isAdopted == isAdoptedChild(prev)) {
- if (cmp <= 0) {
- error("Not sorted: "+verboseToString.fun(prev) + " is not less than " + verboseToString.fun(file), array, details);
- }
- }
+ private void assertConsistency(boolean ignoreCase, @NotNull Object... details) {
+ if (!CHECK || ApplicationInfoImpl.isInPerformanceTest()) return;
+ int[] childrenIds = myData.myChildrenIds;
+ for (int i = 1; i < childrenIds.length; i++) {
+ int id = childrenIds[i];
+ int prev = childrenIds[i - 1];
+ CharSequence name = VfsData.getNameByFileId(id);
+ CharSequence prevName = VfsData.getNameByFileId(prev);
+ int cmp = compareNames(name, prevName, ignoreCase);
+ if (cmp <= 0) {
+ error(verboseToString.fun(VfsData.getFileById(prev, this)) + " is wrongly placed before " + verboseToString.fun(VfsData.getFileById(id, this)), getArraySafely(), details);
}
}
}
@@ -637,6 +356,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static final Function<VirtualFileSystemEntry, String> verboseToString = new Function<VirtualFileSystemEntry, String>() {
@Override
public String fun(VirtualFileSystemEntry file) {
+ if (file == null) return "null";
//noinspection HardCodedStringLiteral
return file + " (name: '" + file.getName()
+ "', " + file.getClass()
@@ -668,16 +388,11 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
public VirtualFileSystemEntry findChildById(int id, boolean cachedOnly) {
- VirtualFile[] array = getArraySafely();
- VirtualFileSystemEntry result = null;
- for (VirtualFile file : array) {
- VirtualFileSystemEntry withId = (VirtualFileSystemEntry)file;
- if (withId.getId() == id) {
- result = withId;
- break;
+ synchronized (myData) {
+ if (ArrayUtil.indexOf(myData.myChildrenIds, id) >= 0) {
+ return VfsData.getFileById(id, this);
}
}
- if (result != null) return result;
if (cachedOnly) return null;
String name = ourPersistence.getName(id);
@@ -690,57 +405,42 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
throw new IOException("Cannot get content of directory: " + this);
}
- public synchronized void addChild(@NotNull VirtualFileSystemEntry child) {
- VirtualFileSystemEntry[] array = myChildren;
+ public void addChild(@NotNull VirtualFileSystemEntry child) {
final String childName = child.getName();
final boolean ignoreCase = !getFileSystem().isCaseSensitive();
- long r = findIndexInBoth(array, childName, getComparator(ignoreCase));
- int indexInReal = (int)(r >> 32);
- int indexInAdopted = (int)r;
+ synchronized (myData) {
+ int indexInReal = findIndex(myData.myChildrenIds, childName, ignoreCase);
- if (indexInAdopted >= 0) {
- // remove Adopted first
- removeFromArray(indexInAdopted);
- }
- if (indexInReal < 0) {
- insertChildAt(child, indexInReal);
+ myData.removeAdoptedName(childName);
+ if (indexInReal < 0) {
+ insertChildAt(child, indexInReal);
+ }
+ // else already stored
+ assertConsistency(ignoreCase, child);
}
- // else already stored
- assertConsistency(myChildren, ignoreCase, child);
}
private void insertChildAt(@NotNull VirtualFileSystemEntry file, int negativeIndex) {
- @NotNull VirtualFileSystemEntry[] array = myChildren;
- VirtualFileSystemEntry[] appended = new VirtualFileSystemEntry[array.length + 1];
+ @NotNull int[] array = myData.myChildrenIds;
+ int[] appended = new int[array.length + 1];
int i = -negativeIndex -1;
System.arraycopy(array, 0, appended, 0, i);
- appended[i] = file;
+ appended[i] = file.getId();
System.arraycopy(array, i, appended, i + 1, array.length - i);
- myChildren = appended;
-
- if (!file.isDirectory()) {
- // access check should only be called when child is actually added to the parent, otherwise it may break VirtualFilePointers validity
- //noinspection TestOnlyProblems
- assertAccessInTests(file, myFS);
- }
+ myData.myChildrenIds = appended;
}
- public synchronized void removeChild(@NotNull VirtualFile file) {
+ public void removeChild(@NotNull VirtualFile file) {
boolean ignoreCase = !getFileSystem().isCaseSensitive();
String name = file.getName();
-
- addToAdoptedChildren(ignoreCase, name, getComparator(ignoreCase));
- assertConsistency(myChildren, ignoreCase, file);
+ synchronized (myData) {
+ addToAdoptedChildren(ignoreCase, name);
+ assertConsistency(ignoreCase, file);
+ }
}
private void removeFromArray(int index) {
- myChildren = ArrayUtil.remove(myChildren, index, new ArrayFactory<VirtualFileSystemEntry>() {
- @NotNull
- @Override
- public VirtualFileSystemEntry[] create(int count) {
- return new VirtualFileSystemEntry[count];
- }
- });
+ myData.myChildrenIds = ArrayUtil.remove(myData.myChildrenIds, index);
}
public boolean allChildrenLoaded() {
@@ -751,46 +451,19 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
@NotNull
- public synchronized List<String> getSuspiciousNames() {
- List<VirtualFile> suspicious = new SubList<VirtualFile>(myChildren, getAdoptedChildrenStart(), myChildren.length);
- return ContainerUtil.map2List(suspicious, new Function<VirtualFile, String>() {
- @Override
- public String fun(VirtualFile file) {
- return file.getName();
- }
- });
- }
-
- private int getAdoptedChildrenStart() {
- int index = binSearch(myChildren, 0, myChildren.length, "", new Comparator() {
- @Override
- public int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry v) {
- return isAdoptedChild(v) ? -1 : 1;
- }
- });
- return -index - 1;
- }
-
- private static boolean isAdoptedChild(@NotNull VirtualFileSystemEntry v) {
- return v.getParent() == NULL_VIRTUAL_FILE;
- }
-
- private interface Comparator {
- int compareFileNameTo(@NotNull String myName, @NotNull VirtualFileSystemEntry file);
+ public List<String> getSuspiciousNames() {
+ synchronized (myData) {
+ return myData.getAdoptedNames();
+ }
}
- private static int binSearch(@NotNull VirtualFileSystemEntry[] array,
- int start,
- int end,
- @NotNull String name,
- @NotNull Comparator comparator) {
- int low = start;
- int high = end - 1;
- assert low >= 0 && low <= array.length;
+ private static int findIndex(final int[] array, @NotNull CharSequence name, boolean ignoreCase) {
+ int low = 0;
+ int high = array.length - 1;
while (low <= high) {
int mid = low + high >>> 1;
- int cmp = comparator.compareFileNameTo(name, array[mid]);
+ int cmp = -compareNames(VfsData.getNameByFileId(array[mid]), name, ignoreCase);
if (cmp > 0) {
low = mid + 1;
}
@@ -804,6 +477,17 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
return -(low + 1); // key not found.
}
+ private static int compareNames(@NotNull CharSequence name1, @NotNull CharSequence name2, boolean ignoreCase) {
+ int d = name1.length() - name2.length();
+ if (d != 0) return d;
+ for (int i = 0; i < name1.length(); i++) {
+ // com.intellij.openapi.util.text.StringUtil.compare(String,String,boolean) inconsistent
+ d = StringUtil.compare(name1.charAt(i), name2.charAt(i), ignoreCase);
+ if (d != 0) return d;
+ }
+ return 0;
+ }
+
@Override
public boolean isDirectory() {
return true;
@@ -811,8 +495,8 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
@Override
@NotNull
- public synchronized List<VirtualFile> getCachedChildren() {
- return new SubList<VirtualFile>(myChildren, 0, getAdoptedChildrenStart());
+ public List<VirtualFile> getCachedChildren() {
+ return Arrays.<VirtualFile>asList(getArraySafely());
}
@Override
@@ -835,11 +519,26 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
// optimisation: do not travel up unnecessary
private void markDirtyRecursivelyInternal() {
for (VirtualFileSystemEntry child : getArraySafely()) {
- if (isAdoptedChild(child)) break;
child.markDirtyInternal();
if (child instanceof VirtualDirectoryImpl) {
((VirtualDirectoryImpl)child).markDirtyRecursivelyInternal();
}
}
}
+
+ @Override
+ protected void setUserMap(KeyFMap map) {
+ myData.myUserMap = map;
+ }
+
+ @NotNull
+ @Override
+ protected KeyFMap getUserMap() {
+ return myData.myUserMap;
+ }
+
+ @Override
+ protected boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
+ return myData.changeUserMap(oldMap, UserDataInterner.internUserData(newMap));
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java
index 8a3c5e7404d4..5175a5875dbf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileImpl.java
@@ -23,9 +23,9 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
-import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.util.LineSeparator;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.keyFMap.KeyFMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,8 +38,8 @@ import java.util.Collections;
public class VirtualFileImpl extends VirtualFileSystemEntry {
- VirtualFileImpl(int nameId, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes final int attributes) {
- super(nameId, parent, id, attributes);
+ VirtualFileImpl(int id, VfsData.Segment segment, VirtualDirectoryImpl parent) {
+ super(id, segment, parent);
}
@Override
@@ -128,4 +128,21 @@ public class VirtualFileImpl extends VirtualFileSystemEntry {
setFlagInt(SYSTEM_LINE_SEPARATOR_DETECTED, hasSystemSeparator);
super.setDetectedLineSeparator(hasSystemSeparator ? null : separator);
}
+
+ @Override
+ protected void setUserMap(KeyFMap map) {
+ mySegment.setUserMap(Math.abs(getId()), map);
+ }
+
+ @NotNull
+ @Override
+ protected KeyFMap getUserMap() {
+ return mySegment.getUserMap(this);
+ }
+
+ @Override
+ protected boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
+ return mySegment.changeUserMap(Math.abs(getId()), oldMap, UserDataInterner.internUserData(newMap));
+ }
+
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java
index faf3819dfe69..00fbdc5dd724 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java
@@ -53,52 +53,41 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
private static final Key<String> SYMLINK_TARGET = Key.create("local.vfs.symlink.target");
- private static final int IS_WRITABLE_FLAG = 0x01000000;
- private static final int IS_HIDDEN_FLAG = 0x02000000;
+ static final int IS_WRITABLE_FLAG = 0x01000000;
+ static final int IS_HIDDEN_FLAG = 0x02000000;
private static final int INDEXED_FLAG = 0x04000000;
static final int CHILDREN_CACHED = 0x08000000; // makes sense for directory only
private static final int DIRTY_FLAG = 0x10000000;
- private static final int IS_SYMLINK_FLAG = 0x20000000;
+ static final int IS_SYMLINK_FLAG = 0x20000000;
private static final int HAS_SYMLINK_FLAG = 0x40000000;
- private static final int IS_SPECIAL_FLAG = 0x80000000;
+ static final int IS_SPECIAL_FLAG = 0x80000000;
static final int SYSTEM_LINE_SEPARATOR_DETECTED = CHILDREN_CACHED; // makes sense only for non-directory file
- private static final int ALL_FLAGS_MASK =
+ static final int ALL_FLAGS_MASK =
DIRTY_FLAG | IS_SYMLINK_FLAG | HAS_SYMLINK_FLAG | IS_SPECIAL_FLAG | IS_WRITABLE_FLAG | IS_HIDDEN_FLAG | INDEXED_FLAG | CHILDREN_CACHED;
- private volatile int myNameId;
- private volatile VirtualDirectoryImpl myParent;
- private volatile int myFlags;
- private volatile int myId;
-
+ protected final VfsData.Segment mySegment;
+ private final VirtualDirectoryImpl myParent;
+ private final int myId;
+
static {
+ //noinspection ConstantConditions
assert (~ALL_FLAGS_MASK) == LocalTimeCounter.TIME_MASK;
}
- public VirtualFileSystemEntry(int nameId, VirtualDirectoryImpl parent, int id, @PersistentFS.Attributes int attributes) {
- myParent = parent;
+ public VirtualFileSystemEntry(int id, VfsData.Segment segment, VirtualDirectoryImpl parent) {
+ mySegment = segment;
myId = id;
- myNameId = nameId;
-
- if (parent != null && parent != VirtualDirectoryImpl.NULL_VIRTUAL_FILE) {
- setFlagInt(IS_SYMLINK_FLAG, PersistentFS.isSymLink(attributes));
- setFlagInt(IS_SPECIAL_FLAG, PersistentFS.isSpecialFile(attributes));
- updateLinkStatus();
- }
-
- setFlagInt(IS_WRITABLE_FLAG, PersistentFS.isWritable(attributes));
- setFlagInt(IS_HIDDEN_FLAG, PersistentFS.isHidden(attributes));
-
- setModificationStamp(LocalTimeCounter.currentTime());
+ myParent = parent;
}
- private void updateLinkStatus() {
+ void updateLinkStatus() {
boolean isSymLink = is(VFileProperty.SYMLINK);
if (isSymLink) {
- String target = myParent.getFileSystem().resolveSymLink(this);
+ String target = getParent().getFileSystem().resolveSymLink(this);
setLinkTarget(target != null ? FileUtil.toSystemIndependentName(target) : null);
}
- setFlagInt(HAS_SYMLINK_FLAG, isSymLink || myParent.getFlagInt(HAS_SYMLINK_FLAG));
+ setFlagInt(HAS_SYMLINK_FLAG, isSymLink || getParent().getFlagInt(HAS_SYMLINK_FLAG));
}
@Override
@@ -110,60 +99,35 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
@NotNull
@Override
public CharSequence getNameSequence() {
- return FileNameCache.getVFileName(myNameId);
- }
-
- public int compareNameTo(@NotNull CharSequence name, boolean ignoreCase) {
- return FileNameCache.compareNameTo(myNameId, name, ignoreCase);
- }
-
- protected static int compareNames(@NotNull CharSequence name1, @NotNull CharSequence name2, boolean ignoreCase) {
- return compareNames(name1, name2, ignoreCase, 0);
- }
-
- static int compareNames(@NotNull CharSequence name1, @NotNull CharSequence name2, boolean ignoreCase, int offset2) {
- int d = name1.length() - name2.length() + offset2;
- if (d != 0) return d;
- for (int i=0; i<name1.length(); i++) {
- // com.intellij.openapi.util.text.StringUtil.compare(String,String,boolean) inconsistent
- d = StringUtil.compare(name1.charAt(i), name2.charAt(i + offset2), ignoreCase);
- if (d != 0) return d;
- }
- return 0;
+ return FileNameCache.getVFileName(mySegment.getNameId(myId));
}
@Override
- public VirtualFileSystemEntry getParent() {
- return myParent;
+ public VirtualDirectoryImpl getParent() {
+ VirtualDirectoryImpl changedParent = VfsData.getChangedParent(this);
+ return changedParent != null ? changedParent : myParent;
}
@Override
public boolean isDirty() {
- return (myFlags & DIRTY_FLAG) != 0;
+ return getFlagInt(DIRTY_FLAG);
}
@Override
public long getModificationStamp() {
- return myFlags & ~ALL_FLAGS_MASK;
+ return mySegment.getModificationStamp(myId);
}
- public synchronized void setModificationStamp(long modificationStamp) {
- myFlags = (myFlags & ALL_FLAGS_MASK) | ((int)modificationStamp & ~ALL_FLAGS_MASK);
+ public void setModificationStamp(long modificationStamp) {
+ mySegment.setModificationStamp(myId, modificationStamp);
}
boolean getFlagInt(int mask) {
- assert (mask & ~ALL_FLAGS_MASK) == 0 : "Unexpected flag";
- return (myFlags & mask) != 0;
+ return mySegment.getFlag(myId, mask);
}
- synchronized void setFlagInt(int mask, boolean value) {
- assert (mask & ~ALL_FLAGS_MASK) == 0 : "Unexpected flag";
- if (value) {
- myFlags |= mask;
- }
- else {
- myFlags &= ~mask;
- }
+ void setFlagInt(int mask, boolean value) {
+ mySegment.setFlag(myId, mask, value);
}
public boolean isFileIndexed() {
@@ -183,7 +147,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
public void markDirty() {
if (!isDirty()) {
markDirtyInternal();
- VirtualDirectoryImpl parent = myParent;
+ VirtualFileSystemEntry parent = getParent();
if (parent != null) parent.markDirty();
}
}
@@ -201,7 +165,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
}
protected char[] appendPathOnFileSystem(int accumulatedPathLength, int[] positionRef) {
- return FileNameCache.appendPathOnFileSystem(myNameId, myParent, accumulatedPathLength, positionRef);
+ return FileNameCache.appendPathOnFileSystem(mySegment.getNameId(myId), getParent(), accumulatedPathLength, positionRef);
}
protected static int copyString(@NotNull char[] chars, int pos, @NotNull CharSequence s) {
@@ -311,13 +275,17 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
@Override
public int getId() {
- return myId;
+ return VfsData.isFileValid(myId) ? myId : -myId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this == o || o instanceof VirtualFileSystemEntry && myId == ((VirtualFileSystemEntry)o).myId;
}
@Override
public int hashCode() {
- int id = myId;
- return id >= 0 ? id : -id;
+ return myId;
}
@Override
@@ -353,15 +321,19 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
throw new IllegalArgumentException("Name of the virtual file cannot be set to empty string");
}
- myParent.removeChild(this);
- myNameId = FileNameCache.storeName(newName);
- myParent.addChild(this);
+ VirtualDirectoryImpl parent = (VirtualDirectoryImpl)getParent();
+ parent.removeChild(this);
+ mySegment.setNameId(myId, FileNameCache.storeName(newName));
+ parent.addChild(this);
}
public void setParent(@NotNull final VirtualFile newParent) {
- myParent.removeChild(this);
- myParent = (VirtualDirectoryImpl)newParent;
- myParent.addChild(this);
+ VirtualDirectoryImpl parent = (VirtualDirectoryImpl)getParent();
+ parent.removeChild(this);
+
+ VirtualDirectoryImpl directory = (VirtualDirectoryImpl)newParent;
+ VfsData.changeParent(this, directory);
+ directory.addChild(this);
updateLinkStatus();
}
@@ -371,7 +343,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
}
public void invalidate() {
- myId = -Math.abs(myId);
+ VfsData.invalidateFile(myId);
}
@Override
@@ -443,7 +415,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
if (is(VFileProperty.SYMLINK)) {
return getUserData(SYMLINK_TARGET);
}
- VirtualDirectoryImpl parent = myParent;
+ VirtualFileSystemEntry parent = getParent();
if (parent != null) {
return parent.getCanonicalPath() + "/" + getName();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
index 6cff8a6892fe..d7b90178e7e8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
@@ -30,10 +30,7 @@ import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.openapi.vfs.newvfs.*;
import com.intellij.openapi.vfs.newvfs.events.*;
-import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile;
-import com.intellij.openapi.vfs.newvfs.impl.FileNameCache;
-import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
-import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
+import com.intellij.openapi.vfs.newvfs.impl.*;
import com.intellij.util.*;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.ContainerUtil;
@@ -873,22 +870,36 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
myRootsLock.readLock().unlock();
}
- VirtualFileSystemEntry newRoot;
+ final VirtualFileSystemEntry newRoot;
int rootId = FSRecords.findRootRecord(rootUrl);
+ VfsData.Segment segment = VfsData.getSegment(rootId, true);
+ VfsData.DirectoryData directoryData = new VfsData.DirectoryData();
if (fs instanceof JarFileSystem) {
String parentPath = basePath.substring(0, basePath.indexOf(JarFileSystem.JAR_SEPARATOR));
VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(parentPath);
if (parentFile == null) return null;
FileType type = FileTypeRegistry.getInstance().getFileTypeByFileName(parentFile.getName());
if (type != FileTypes.ARCHIVE) return null;
- newRoot = new JarRoot(fs, rootId, parentFile);
+ newRoot = new JarRoot(fs, rootId, segment, directoryData, parentFile);
}
else {
- newRoot = new FsRoot(fs, rootId, basePath);
+ newRoot = new FsRoot(fs, rootId, segment, directoryData, basePath);
}
- FileAttributes attributes = fs.getAttributes(newRoot);
+ FileAttributes attributes = fs.getAttributes(new StubVirtualFile() {
+ @NotNull
+ @Override
+ public String getPath() {
+ return newRoot.getPath();
+ }
+
+ @Nullable
+ @Override
+ public VirtualFile getParent() {
+ return null;
+ }
+ });
if (attributes == null || !attributes.isDirectory()) {
return null;
}
@@ -900,6 +911,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
VirtualFileSystemEntry root = myRoots.get(rootUrl);
if (root != null) return root;
+ VfsData.initFile(rootId, segment, -1, directoryData);
mark = writeAttributesToRecord(rootId, 0, newRoot, fs, attributes);
myRoots.put(rootUrl, newRoot);
@@ -1276,8 +1288,8 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private abstract static class AbstractRoot extends VirtualDirectoryImpl {
- protected AbstractRoot(@NotNull NewVirtualFileSystem fs, int id) {
- super(-1, null, fs, id, 0);
+ public AbstractRoot(int id, VfsData.Segment segment, VfsData.DirectoryData data, NewVirtualFileSystem fs) {
+ super(id, segment, data, null, fs);
}
@NotNull
@@ -1285,11 +1297,6 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
public abstract CharSequence getNameSequence();
@Override
- public int compareNameTo(@NotNull CharSequence name, boolean ignoreCase) {
- return VirtualFileSystemEntry.compareNames(getName(), name, ignoreCase);
- }
-
- @Override
protected abstract char[] appendPathOnFileSystem(int accumulatedPathLength, int[] positionRef);
@Override
@@ -1307,8 +1314,8 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private final VirtualFile myParentLocalFile;
private final String myParentPath;
- private JarRoot(@NotNull NewVirtualFileSystem fs, int rootId, @NotNull VirtualFile parentLocalFile) {
- super(fs, rootId);
+ private JarRoot(@NotNull NewVirtualFileSystem fs, int id, VfsData.Segment segment, VfsData.DirectoryData data, VirtualFile parentLocalFile) {
+ super(id, segment, data, fs);
myParentLocalFile = parentLocalFile;
myParentPath = myParentLocalFile.getPath();
}
@@ -1331,8 +1338,8 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private static class FsRoot extends AbstractRoot {
private final String myName;
- private FsRoot(@NotNull NewVirtualFileSystem fs, int rootId, @NotNull String basePath) {
- super(fs, rootId);
+ private FsRoot(@NotNull NewVirtualFileSystem fs, int id, VfsData.Segment segment, VfsData.DirectoryData data, @NotNull String basePath) {
+ super(id, segment, data, fs);
myName = FileUtil.toSystemIndependentName(basePath);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java
index 58f315f0246c..36a79f23cf89 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -203,6 +203,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
public ActionCallback requestFocus(@NotNull final FocusCommand command, final boolean forced) {
assertDispatchThread();
+ if (!forced && !command.canFocusChangeFrom(getFocusOwner())) {
+ return ActionCallback.REJECTED;
+ }
if (isInternalMode) {
recordCommand(command, new Throwable(), forced);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
index 06b00ea0e933..6c6bcd137949 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
@@ -248,27 +248,13 @@ public class X11UiUtil {
try {
if (wmName.startsWith("Mutter") || "Muffin".equals(wmName) || "GNOME Shell".equals(wmName)) {
- try {
- setWM("MUTTER_WM");
- }
- catch (NoSuchFieldException e) {
- setWM("METACITY_WM");
- }
+ setWM("MUTTER_WM", "METACITY_WM");
}
else if ("Marco".equals(wmName)) {
- setWM("METACITY_WM");
+ setWM("MARCO_WM", "METACITY_WM");
}
else if ("awesome".equals(wmName)) {
- try {
- Class<?> xwmClass = Class.forName("sun.awt.X11.XWM");
- xwmClass.getDeclaredField("OTHER_NONREPARENTING_WM");
- if (System.getenv("_JAVA_AWT_WM_NONREPARENTING") == null) {
- setWM("OTHER_NONREPARENTING_WM"); // patch present but not activated
- }
- }
- catch (NoSuchFieldException e) {
- setWM("LG3D_WM"); // patch absent - mimic LG3D
- }
+ setWM("SAWFISH_WM");
}
}
catch (Throwable e) {
@@ -276,15 +262,21 @@ public class X11UiUtil {
}
}
- private static void setWM(String wmConstant) throws Exception {
+ private static void setWM(String... wmConstants) throws Exception {
Class<?> xwmClass = Class.forName("sun.awt.X11.XWM");
Object xwm = method(xwmClass, "getWM").invoke(null);
if (xwm != null) {
- Field wm = field(xwmClass, wmConstant);
- Object id = wm.get(null);
- if (id != null) {
- field(xwmClass, "awt_wmgr").set(null, id);
- field(xwmClass, "WMID").set(xwm, id);
+ for (String wmConstant : wmConstants) {
+ try {
+ Field wm = field(xwmClass, wmConstant);
+ Object id = wm.get(null);
+ if (id != null) {
+ field(xwmClass, "awt_wmgr").set(null, id);
+ field(xwmClass, "WMID").set(xwm, id);
+ break;
+ }
+ }
+ catch (NoSuchFieldException ignore) { }
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java
index ea846bfe5b8f..362d136413e5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java
@@ -45,7 +45,7 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
private final TextPanel myText = new TextPanel();
private final TextPanel myText2 = new TextPanel();
- private MyProgressBar myProgress;
+ private JProgressBar myProgress;
private JPanel myComponent;
@@ -78,7 +78,8 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
myCancelButton.setToolTipText(processInfo.getCancelTooltipText());
myCancelButton.setFillBg(false);
- myProgress = new MyProgressBar(JProgressBar.HORIZONTAL, compact);
+ myProgress = new JProgressBar(SwingConstants.HORIZONTAL);
+ myProgress.putClientProperty("JComponent.sizeVariant", "mini");
myComponent = new MyComponent(compact, myProcessName);
if (myCompact) {
@@ -101,7 +102,6 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
myComponent.add(textAndProgress, BorderLayout.CENTER);
myComponent.add(myCancelButton, BorderLayout.EAST);
myComponent.setToolTipText(processInfo.getTitle() + ". " + IdeBundle.message("progress.text.clickToViewProgressWindow"));
- myProgress.setActive(false);
} else {
myComponent.setLayout(new BorderLayout());
myProcessName.setText(processInfo.getTitle());
@@ -127,7 +127,6 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
myText2.setDecorate(false);
myComponent.setBorder(new EmptyBorder(2, 2, 2, 2));
- myProgress.setActive(false);
}
if (!myCompact) {
@@ -164,21 +163,9 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
}
final long delta = System.currentTimeMillis() - myLastTimeProgressWasAtZero;
- boolean forcedIndeterminite = false;
-
- boolean indeterminate = isIndeterminate();
- if (!indeterminate && getFraction() == 0) {
- if (delta > 2000 && !myCompact) {
- indeterminate = true;
- forcedIndeterminite = true;
- } else {
- forcedIndeterminite = false;
- }
- }
- final boolean visible = getFraction() > 0 || (indeterminate || forcedIndeterminite);
- updateVisibility(myProgress, visible);
- if (indeterminate || forcedIndeterminite) {
+ boolean indeterminate = isIndeterminate() || getFraction() == 0 && delta > 2000 && !myCompact;
+ if (indeterminate) {
myProgress.setIndeterminate(true);
}
else {
@@ -240,24 +227,6 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
update.run();
}
-
- private void updateVisibility(MyProgressBar bar, boolean holdsValue) {
- if (holdsValue && !bar.isActive()) {
- bar.setActive(true);
- bar.revalidate();
- bar.repaint();
- myComponent.revalidate();
- myComponent.repaint();
- }
- else if (!holdsValue && bar.isActive()) {
- bar.setActive(false);
- bar.revalidate();
- bar.repaint();
- myComponent.revalidate();
- myComponent.repaint();
- }
- }
-
protected void onProgressChange() {
updateProgress();
}
@@ -278,45 +247,6 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di
return myInfo;
}
- private static class MyProgressBar extends JProgressBar {
- private boolean myActive = true;
- private final boolean myCompact;
-
- public MyProgressBar(final int orient, boolean compact) {
- super(orient);
- myCompact = compact;
- putClientProperty("JComponent.sizeVariant", "mini");
- }
-
-
- public void paint(final Graphics g) {
- if (!myActive) return;
- super.paint(g);
- }
-
- @Override
- public void setIndeterminate(boolean newValue) {
- super.setIndeterminate(newValue);
- if (myCompact) {
- setVisible(!newValue);
- }
- }
-
- public boolean isActive() {
- return myActive;
- }
-
-
- public Dimension getPreferredSize() {
- if (!myActive && myCompact) return new Dimension(0, 0);
- return super.getPreferredSize();
- }
-
- public void setActive(final boolean active) {
- myActive = active;
- }
- }
-
private class MyComponent extends JPanel {
private final boolean myCompact;
private final JComponent myProcessName;
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/AbstractActionWithPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/AbstractActionWithPanel.java
new file mode 100644
index 000000000000..cc9564d9e800
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/AbstractActionWithPanel.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.wm.impl.welcomeScreen;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.project.DumbAware;
+
+import javax.swing.*;
+
+public abstract class AbstractActionWithPanel extends AnAction implements DumbAware {
+
+ public abstract JPanel createPanel();
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/CardActionsPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/CardActionsPanel.java
index 08ce9caa0db5..598d0f46ac74 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/CardActionsPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/CardActionsPanel.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.actionSystem.impl.PresentationFactory;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.JBCardLayout;
+import com.intellij.ui.JBColor;
import com.intellij.ui.LightColors;
import com.intellij.util.ui.CenteredIcon;
import com.intellij.util.ui.GraphicsUtil;
@@ -63,31 +64,26 @@ public class CardActionsPanel extends JPanel {
withBottomFiller.add(card, BorderLayout.NORTH);
myContent.add(withBottomFiller, cardId);
- List<Button> buttons = buildButtons(group, cardId);
+ List<JComponent> components = buildComponents(group, cardId);
- JPanel buttonsPanel = new JPanel(new GridLayout(buttons.size(), 1, 5, 5));
+ JPanel componentsPanel = new JPanel(new GridLayout(components.size(), 1, 5, 5));
if (!USE_ICONS) {
- buttonsPanel.setOpaque(false);
+ componentsPanel.setOpaque(false);
}
- buttonsPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
- for (Button button : buttons) {
- buttonsPanel.add(button);
+ componentsPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
+ for (JComponent component : components) {
+ componentsPanel.add(component);
}
- card.add(buttonsPanel, BorderLayout.CENTER);
+ card.add(componentsPanel, BorderLayout.CENTER);
String title;
- if (parentId != null) {
- title = group.getTemplatePresentation().getText();
- }
- else {
- title = "Quick Start";
- }
+ title = group.getTemplatePresentation().getText();
card.add(new HeaderPanel(title, parentId), BorderLayout.NORTH);
}
- private List<Button> buildButtons(ActionGroup group, String parentId) {
+ private List<JComponent> buildComponents(ActionGroup group, String parentId) {
AnAction[] actions = group.getChildren(null);
- List<Button> buttons = new ArrayList<Button>();
+ List<JComponent> components = new ArrayList<JComponent>();
PresentationFactory factory = new PresentationFactory();
for (AnAction action : actions) {
@@ -101,21 +97,25 @@ public class CardActionsPanel extends JPanel {
final String id = String.valueOf(++nCards);
createCardForGroup(childGroup, id, parentId);
- buttons.add(new Button(new ActivateCard(id), presentation));
+ components.add(new Button(new ActivateCard(id), presentation));
}
else {
- buttons.addAll(buildButtons(childGroup, parentId));
+ components.addAll(buildComponents(childGroup, parentId));
}
}
+ else if (action instanceof AbstractActionWithPanel){
+ final JPanel panel = ((AbstractActionWithPanel)action).createPanel();
+ components.add(panel);
+ }
else {
action.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(this),
ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0));
if (presentation.isVisible()) {
- buttons.add(new Button(action, presentation));
+ components.add(new Button(action, presentation));
}
}
}
- return buttons;
+ return components;
}
private class HeaderPanel extends JPanel {
@@ -159,7 +159,7 @@ public class CardActionsPanel extends JPanel {
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(LightColors.SLIGHTLY_GREEN);
g.fillRoundRect(x + 4, y + 4, 32 - 8, 32 - 8, 8, 8);
- g.setColor(Color.GRAY);
+ g.setColor(JBColor.GRAY);
g.drawRoundRect(x + 4, y + 4, 32 - 8, 32 - 8, 8, 8);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java
index b9bd86db0d15..a899f8bb681c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java
@@ -47,7 +47,7 @@ public class NewWelcomeScreen extends JPanel implements WelcomeScreen {
}
private static WelcomePane createInnerPanel(WelcomeScreen screen) {
- WelcomeScreenGroup root = new WelcomeScreenGroup(null, "Root");
+ WelcomeScreenGroup root = new WelcomeScreenGroup(null, "Quick Start");
ActionManager actionManager = ActionManager.getInstance();
ActionGroup quickStart = (ActionGroup)actionManager.getAction(IdeActions.GROUP_WELCOME_SCREEN_QUICKSTART);
@@ -98,7 +98,7 @@ public class NewWelcomeScreen extends JPanel implements WelcomeScreen {
footerPanel.add(makeSmallFont(new LinkLabel("Check", null, new LinkListener() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
- UpdateChecker.updateAndShowResult(null, false, null, UpdateSettings.getInstance());
+ UpdateChecker.updateAndShowResult(null, false, UpdateSettings.getInstance());
}
})));
footerPanel.add(makeSmallFont(new JLabel(" for updates now.")));
diff --git a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java
index c99bf6afe372..d123f9e94b53 100644
--- a/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java
+++ b/platform/platform-impl/src/com/intellij/platform/DirectoryProjectGenerator.java
@@ -25,6 +25,8 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+
/**
* @author yole
*/
@@ -38,6 +40,9 @@ public interface DirectoryProjectGenerator<T> {
@Nullable
T showGenerationSettings(final VirtualFile baseDir) throws ProcessCanceledException;
+ @Nullable
+ Icon getLogo();
+
void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
@Nullable final T settings, @NotNull final Module module);
diff --git a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java b/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java
deleted file mode 100644
index ce707e3ba2bb..000000000000
--- a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindow.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @author max
- */
-package com.intellij.platform;
-
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataProvider;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileSystemTree;
-import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl;
-import com.intellij.openapi.fileEditor.OpenFileDescriptor;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowAnchor;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.ui.ScrollPaneFactory;
-import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentFactory;
-import com.intellij.ui.content.ContentFactoryImpl;
-import com.intellij.util.EditSourceOnDoubleClickHandler;
-import com.intellij.util.EditSourceOnEnterKeyHandler;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-
-public class FilesystemToolwindow {
- private final VirtualFile myRoot;
- private final Project myProject;
- private final ToolWindow myToolWindow;
- private final JPanel myContent;
- private final FileSystemTree myFsTree;
-
- public FilesystemToolwindow(final VirtualFile root, Project project) {
- myRoot = root;
- myProject = project;
-
- myToolWindow = ToolWindowManager.getInstance(project).registerToolWindow("File System", false, ToolWindowAnchor.LEFT);
- myContent = new MyContent();
-
- final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, false, true, true);
- descriptor.setRoots(myRoot);
-
- myFsTree = new FileSystemTreeImpl(project, descriptor);
- myContent.add(ScrollPaneFactory.createScrollPane(myFsTree.getTree()), BorderLayout.CENTER);
- EditSourceOnDoubleClickHandler.install(myFsTree.getTree());
- EditSourceOnEnterKeyHandler.install(myFsTree.getTree());
-
- final ContentFactory contentFactory = new ContentFactoryImpl();
- final Content content = contentFactory.createContent(myContent, null, false);
- myToolWindow.getContentManager().addContent(content);
- }
-
-
- private class MyContent extends JPanel implements DataProvider {
- public MyContent() {
- super(new BorderLayout());
- }
-
- @Nullable
- public Object getData(@NonNls final String dataId) {
- if (CommonDataKeys.NAVIGATABLE.is(dataId)) {
- final VirtualFile file = myFsTree.getSelectedFile();
- if (file != null) {
- return new OpenFileDescriptor(myProject, file);
- }
- }
- else if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) {
- return myFsTree.getSelectedFile();
- }
- return null;
- }
- }
-
-}
diff --git a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindowOpener.java b/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindowOpener.java
deleted file mode 100644
index c1f1717c49d6..000000000000
--- a/platform/platform-impl/src/com/intellij/platform/FilesystemToolwindowOpener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.platform;
-
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.startup.StartupActivity;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.wm.ToolWindowManager;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author yole
- */
-public class FilesystemToolwindowOpener implements StartupActivity, DumbAware {
-
- @Override
- public void runActivity(@NotNull final Project project) {
- final VirtualFile baseDir = ProjectBaseDirectory.getInstance(project).getBaseDir();
- if (baseDir == null || !baseDir.isDirectory()) return;
- ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
- public void run() {
- ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
- public void run() {
- new FilesystemToolwindow(baseDir, project);
- }
- });
- }
- });
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
index f711f4e51e21..e31b067e5d79 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
@@ -27,14 +27,17 @@ public class RemoteConnectionCredentialsWrapper {
public static final String VAGRANT_PREFIX = "vagrant://";
public static final String SFTP_DEPLOYMENT_PREFIX = "sftp://";
+ /**
+ * Connection types
+ */
public final Key<VagrantBasedCredentialsHolder> VAGRANT_BASED_CREDENTIALS = Key.create("VAGRANT_BASED_CREDENTIALS");
public final Key<WebDeploymentCredentialsHolder> WEB_DEPLOYMENT_BASED_CREDENTIALS = Key.create("WEB_DEPLOYMENT_BASED_CREDENTIALS");
-
public final Key<RemoteCredentialsHolder> PLAIN_SSH_CREDENTIALS = Key.create("PLAIN_SSH_CREDENTIALS");
private UserDataHolderBase myCredentialsTypeHolder = new UserDataHolderBase();
public void setVagrantConnectionType(VagrantBasedCredentialsHolder vagrantBasedCredentials) {
+ myCredentialsTypeHolder = new UserDataHolderBase();
myCredentialsTypeHolder.putUserData(VAGRANT_BASED_CREDENTIALS, vagrantBasedCredentials);
}
@@ -44,6 +47,7 @@ public class RemoteConnectionCredentialsWrapper {
}
public void setPlainSshCredentials(RemoteCredentialsHolder credentials) {
+ myCredentialsTypeHolder = new UserDataHolderBase();
myCredentialsTypeHolder.putUserData(PLAIN_SSH_CREDENTIALS, credentials);
}
@@ -53,6 +57,7 @@ public class RemoteConnectionCredentialsWrapper {
public void setWebDeploymentCredentials(WebDeploymentCredentialsHolder webDeploymentCredentials) {
+ myCredentialsTypeHolder = new UserDataHolderBase();
myCredentialsTypeHolder.putUserData(WEB_DEPLOYMENT_BASED_CREDENTIALS, webDeploymentCredentials);
}
@@ -91,17 +96,17 @@ public class RemoteConnectionCredentialsWrapper {
public void save(final Element rootElement) {
switchType(new RemoteSdkConnectionAcceptor() {
@Override
- public void ssh(RemoteCredentialsHolder cred) {
+ public void ssh(@NotNull RemoteCredentialsHolder cred) {
cred.save(rootElement);
}
@Override
- public void vagrant(VagrantBasedCredentialsHolder cred) {
+ public void vagrant(@NotNull VagrantBasedCredentialsHolder cred) {
cred.save(rootElement);
}
@Override
- public void deployment(WebDeploymentCredentialsHolder cred) {
+ public void deployment(@NotNull WebDeploymentCredentialsHolder cred) {
cred.save(rootElement);
}
});
@@ -147,7 +152,7 @@ public class RemoteConnectionCredentialsWrapper {
return RemoteCredentialsHolder.SSH_PREFIX + cred.getUserName() + "@" + cred.getHost() + ":" + cred.getPort();
}
- public void switchType(RemoteSdkConnectionAcceptor acceptor) {
+ public void switchType(@NotNull final RemoteSdkConnectionAcceptor acceptor) {
if (isVagrantConnection()) {
acceptor.vagrant(getVagrantCredentials());
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteCredentialException.java b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialException.java
new file mode 100644
index 000000000000..ba2da269c921
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteCredentialException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remote;
+
+/**
+ * @author traff
+ */
+public class RemoteCredentialException extends RuntimeException {
+ public RemoteCredentialException(String message) {
+ super(message);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java
index 1da39343b4c0..b51c85bc2c18 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkAdditionalData.java
@@ -22,15 +22,13 @@ import org.jetbrains.annotations.NotNull;
* @author traff
*/
public interface RemoteSdkAdditionalData<T extends RemoteSdkCredentials>
- extends SdkAdditionalData, RemoteSdkProducer<T>, RemoteSdkProperties {
+ extends SdkAdditionalData, RemoteSdkCredentialsProducer<T>, RemoteSdkProperties {
void completeInitialization();
boolean isInitialized();
void setInitialized(boolean initialized);
- String getFullInterpreterPath();
-
void setVagrantConnectionType(@NotNull VagrantBasedCredentialsHolder vagrantBasedCredentials);
/**
@@ -43,5 +41,5 @@ public interface RemoteSdkAdditionalData<T extends RemoteSdkCredentials>
CredentialsType getRemoteConnectionType();
- void switchOnConnectionType(RemoteSdkConnectionAcceptor acceptor);
+ void switchOnConnectionType(@NotNull RemoteSdkConnectionAcceptor acceptor);
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkConnectionAcceptor.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkConnectionAcceptor.java
index 12e42526a5f7..d0d0b7a64253 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkConnectionAcceptor.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkConnectionAcceptor.java
@@ -15,11 +15,13 @@
*/
package com.intellij.remote;
+import org.jetbrains.annotations.NotNull;
+
/**
* @author traff
*/
public interface RemoteSdkConnectionAcceptor {
- void ssh(RemoteCredentialsHolder cred);
- void vagrant(VagrantBasedCredentialsHolder cred);
- void deployment(WebDeploymentCredentialsHolder cred);
+ void ssh(@NotNull RemoteCredentialsHolder cred);
+ void vagrant(@NotNull VagrantBasedCredentialsHolder cred);
+ void deployment(@NotNull WebDeploymentCredentialsHolder cred);
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java
index 876f82771025..aeca525bd347 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentials.java
@@ -1,8 +1,5 @@
package com.intellij.remote;
-import com.intellij.remote.MutableRemoteCredentials;
-import com.intellij.remote.RemoteSdkProperties;
-
/**
* @author traff
*/
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java
index 59e9cf02d7ba..e848c3d9c32c 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsBuilder.java
@@ -57,7 +57,7 @@ public class RemoteSdkCredentialsBuilder {
copyTo.setRemoteRoots(data.getRemoteRoots());
}
- public static void copyCredentials(RemoteCredentials data, MutableRemoteCredentials copyTo) {
+ public static void copyCredentials(@NotNull RemoteCredentials data, @NotNull MutableRemoteCredentials copyTo) {
copyTo.setHost(data.getHost());
copyTo.setPort(data.getPort());
copyTo.setAnonymous(data.isAnonymous());
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java
index 8069f8c0336a..d92839e212b8 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java
@@ -1,5 +1,6 @@
package com.intellij.remote;
+import com.intellij.util.PathMappingSettings;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -97,6 +98,17 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
myRemoteSdkProperties.setRemoteRoots(remoteRoots);
}
+ @NotNull
+ @Override
+ public PathMappingSettings getPathMappings() {
+ return myRemoteSdkProperties.getPathMappings();
+ }
+
+ @Override
+ public void setPathMappings(@Nullable PathMappingSettings pathMappings) {
+ myRemoteSdkProperties.setPathMappings(pathMappings);
+ }
+
@Override
public boolean isHelpersVersionChecked() {
return myRemoteSdkProperties.isHelpersVersionChecked();
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsProducer.java
index b3461bf08210..0dfa214c9971 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProducer.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsProducer.java
@@ -21,13 +21,14 @@ import com.intellij.util.Consumer;
/**
* @author traff
*/
-public interface RemoteSdkProducer<T extends RemoteSdkCredentials> {
+public interface RemoteSdkCredentialsProducer<T extends RemoteSdkCredentials> {
/**
* Synchronously returns remote sdk credentials
* @return
* @throws InterruptedException
* @deprecated
*/
+ @Deprecated
T getRemoteSdkCredentials() throws InterruptedException;
T getRemoteSdkCredentials(boolean allowSynchronousInteraction) throws InterruptedException, ExecutionException;
@@ -38,6 +39,7 @@ public interface RemoteSdkProducer<T extends RemoteSdkCredentials> {
* @param remoteSdkCredentialsConsumer
* @deprecated
*/
+ @Deprecated
void produceRemoteSdkCredentials(Consumer<T> remoteSdkCredentialsConsumer);
Object getRemoteSdkDataKey();
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java
index 7d132578a6d4..a690afd96afc 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java
@@ -15,6 +15,10 @@
*/
package com.intellij.remote;
+import com.intellij.util.PathMappingSettings;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
import java.util.List;
/**
@@ -31,14 +35,47 @@ public interface RemoteSdkProperties {
String getDefaultHelpersName();
+ /**
+ * Use getPathMappings() instead
+ * To be removed in IDEA 15
+ *
+ * @deprecated
+ */
+ @Deprecated
void addRemoteRoot(String remoteRoot);
+ /**
+ * Use getPathMappings() instead
+ * To be removed in IDEA 15
+ *
+ * @deprecated
+ */
+ @Deprecated
void clearRemoteRoots();
+ /**
+ * Use getPathMappings() instead
+ * To be removed in IDEA 15
+ *
+ * @deprecated
+ */
+ @Deprecated
List<String> getRemoteRoots();
+ /**
+ * Use setPathMappings() instead
+ * To be removed in IDEA 15
+ *
+ * @deprecated
+ */
+ @Deprecated
void setRemoteRoots(List<String> remoteRoots);
+ @NotNull
+ PathMappingSettings getPathMappings();
+
+ void setPathMappings(@Nullable PathMappingSettings pathMappings);
+
boolean isHelpersVersionChecked();
void setHelpersVersionChecked(boolean helpersVersionChecked);
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java
index 71bf44ba3cb7..a0407d27f7e9 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java
@@ -19,12 +19,13 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.JDOMExternalizer;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PathMappingSettings;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import java.util.TreeSet;
/**
* @author traff
@@ -35,6 +36,7 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
private static final String REMOTE_ROOTS = "REMOTE_ROOTS";
private static final String REMOTE_PATH = "REMOTE_PATH";
private static final String INITIALIZED = "INITIALIZED";
+ private static final String PATH_MAPPINGS = "PATH_MAPPINGS";
private String mySdkId;
@@ -49,6 +51,9 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
private boolean myInitialized = false;
+ @NotNull
+ private PathMappingSettings myPathMappings = new PathMappingSettings();
+
public RemoteSdkPropertiesHolder(String name) {
myHelpersDefaultDirName = name;
}
@@ -97,6 +102,20 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
myRemoteRoots = Sets.newTreeSet(remoteRoots);
}
+ @NotNull
+ @Override
+ public PathMappingSettings getPathMappings() {
+ return myPathMappings;
+ }
+
+ @Override
+ public void setPathMappings(@Nullable PathMappingSettings pathMappings) {
+ myPathMappings = new PathMappingSettings();
+ if (pathMappings != null) {
+ myPathMappings.addAll(pathMappings);
+ }
+ }
+
@Override
public boolean isHelpersVersionChecked() {
return myHelpersVersionChecked;
@@ -123,7 +142,6 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
@Override
public void setInitialized(boolean initialized) {
myInitialized = initialized;
-
}
public void copyTo(RemoteSdkProperties copy) {
@@ -142,6 +160,8 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
rootElement.setAttribute(INITIALIZED, Boolean.toString(isInitialized()));
+ PathMappingSettings.writeExternal(rootElement, myPathMappings);
+
for (String remoteRoot : getRemoteRoots()) {
final Element child = new Element(REMOTE_ROOTS);
child.setAttribute(REMOTE_PATH, remoteRoot);
@@ -156,5 +176,7 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
setRemoteRoots(JDOMExternalizer.loadStringsList(element, REMOTE_ROOTS, REMOTE_PATH));
setInitialized(StringUtil.parseBoolean(element.getAttributeValue(INITIALIZED), true));
+
+ setPathMappings(PathMappingSettings.readExternal(element));
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index 060bfb2a597a..50a7ebbca92b 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -125,7 +125,7 @@ public class AppUIUtil {
if ("true".equals(System.getProperty("idea.debug.mode"))) {
wmClass += "-debug";
}
- return PlatformUtils.isIdeaCommunity() ? wmClass + "-ce" : wmClass;
+ return PlatformUtils.isCommunityEdition() ? wmClass + "-ce" : wmClass;
}
public static void registerBundledFonts() {
diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java
index f3158c203cd8..d78e68137df1 100644
--- a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java
+++ b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java
@@ -1128,7 +1128,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen
myPickerFrame.setSize(SIZE - 4, SIZE - 4);
myPickerFrame.setUndecorated(true);
- myPickerFrame.setAlwaysOnTop(true);
+ myPickerFrame.setAlwaysOnTop(!SystemInfo.isJavaVersionAtLeast("1.8.0"));
JRootPane rootPane = ((JDialog)myPickerFrame).getRootPane();
rootPane.putClientProperty("Window.shadow", Boolean.FALSE);
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
index 24660c6674ab..5721f4af4821 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
@@ -30,8 +30,8 @@ import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.reference.SoftReference;
import com.intellij.util.ConcurrencyUtil;
-import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
@@ -41,8 +41,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.lang.ref.WeakReference;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
/**
@@ -50,7 +50,7 @@ import java.util.concurrent.ThreadPoolExecutor;
*/
public class EditorNotificationsImpl extends EditorNotifications {
private static final ExtensionPointName<Provider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.editorNotificationProvider");
- private final Map<VirtualFile, ProgressIndicator> myCurrentUpdates = new ConcurrentWeakHashMap<VirtualFile, ProgressIndicator>();
+ private static final Key<WeakReference<ProgressIndicator>> CURRENT_UPDATES = Key.create("CURRENT_UPDATES");
private final ThreadPoolExecutor myExecutor = ConcurrencyUtil.newSingleThreadExecutor("EditorNotifications executor");
private final MergingUpdateQueue myUpdateMerger;
@@ -78,18 +78,26 @@ public class EditorNotificationsImpl extends EditorNotifications {
}
- public void updateNotifications(final VirtualFile file) {
+ @Override
+ public void updateNotifications(@NotNull final VirtualFile file) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
- ProgressIndicator indicator = myCurrentUpdates.remove(file);
+ ProgressIndicator indicator = getCurrentProgress(file);
if (indicator != null) {
indicator.cancel();
}
+ file.putUserData(CURRENT_UPDATES, null);
- indicator = new ProgressIndicatorBase();
- myCurrentUpdates.put(file, indicator);
+ if (myProject.isDisposed() || !file.isValid()) {
+ return;
+ }
+ indicator = new ProgressIndicatorBase();
final ReadTask task = createTask(indicator, file);
+ if (task == null) return;
+
+ file.putUserData(CURRENT_UPDATES, new WeakReference<ProgressIndicator>(indicator));
if (ApplicationManager.getApplication().isUnitTestMode()) {
task.computeInReadAction(indicator);
}
@@ -106,11 +114,24 @@ public class EditorNotificationsImpl extends EditorNotifications {
});
}
- private ReadTask createTask(final ProgressIndicator indicator, final VirtualFile file) {
- return new ReadTask() {
+ @Nullable
+ private ReadTask createTask(final ProgressIndicator indicator, @NotNull final VirtualFile file) {
+ final FileEditor[] editors = FileEditorManager.getInstance(myProject).getAllEditors(file);
+ if (editors.length == 0) return null;
+ return new ReadTask() {
private boolean isOutdated() {
- return myProject.isDisposed() || !file.isValid() || indicator != myCurrentUpdates.get(file);
+ if (myProject.isDisposed() || !file.isValid() || indicator != getCurrentProgress(file)) {
+ return true;
+ }
+
+ for (FileEditor editor : editors) {
+ if (!editor.isValid()) {
+ return true;
+ }
+ }
+
+ return false;
}
@Override
@@ -118,7 +139,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
if (isOutdated()) return;
final List<Runnable> updates = ContainerUtil.newArrayList();
- for (final FileEditor editor : FileEditorManager.getInstance(myProject).getAllEditors(file)) {
+ for (final FileEditor editor : editors) {
for (final Provider<?> provider : Extensions.getExtensions(EXTENSION_POINT_NAME, myProject)) {
final JComponent component = provider.createNotificationPanel(file, editor);
updates.add(new Runnable() {
@@ -134,7 +155,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
@Override
public void run() {
if (!isOutdated()) {
- myCurrentUpdates.remove(file);
+ file.putUserData(CURRENT_UPDATES, null);
for (Runnable update : updates) {
update.run();
}
@@ -144,14 +165,25 @@ public class EditorNotificationsImpl extends EditorNotifications {
}
@Override
- public void onCanceled(@NotNull ProgressIndicator indicator) {
- updateNotifications(file);
+ public void onCanceled(@NotNull ProgressIndicator _) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (getCurrentProgress(file) == indicator) {
+ updateNotifications(file);
+ }
+ }
+ });
}
};
}
+ private static ProgressIndicator getCurrentProgress(VirtualFile file) {
+ return SoftReference.dereference(file.getUserData(CURRENT_UPDATES));
+ }
+
- private void updateNotification(FileEditor editor, Key<? extends JComponent> key, @Nullable JComponent component) {
+ private void updateNotification(@NotNull FileEditor editor, @NotNull Key<? extends JComponent> key, @Nullable JComponent component) {
JComponent old = editor.getUserData(key);
if (old != null) {
FileEditorManager.getInstance(myProject).removeTopComponent(editor, old);
@@ -166,6 +198,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
}
}
+ @Override
public void updateAllNotifications() {
myUpdateMerger.queue(new Update("update") {
@Override
diff --git a/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java b/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java
index e34f03ce6d93..b19d02ff67c2 100644
--- a/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java
+++ b/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java
@@ -53,6 +53,7 @@ public class HideableDecorator {
};
myPanel.add(myTitledSeparator, BorderLayout.NORTH);
myTitledSeparator.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ updateIcon();
myTitledSeparator.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
@@ -66,6 +67,12 @@ public class HideableDecorator {
});
}
+ private void updateIcon() {
+ final Icon icon = myOn ? AllIcons.General.SplitDown : AllIcons.General.SplitRight;
+ myTitledSeparator.getLabel().setIcon(icon);
+ myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(icon, 0.5f));
+ }
+
public void setContentComponent(@Nullable JComponent content) {
if (content == null && myContent != null) {
myPanel.remove(myContent);
@@ -101,8 +108,7 @@ public class HideableDecorator {
protected void on() {
myOn = true;
- myTitledSeparator.getLabel().setIcon(AllIcons.General.SplitDown);
- myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.SplitDown, 0.5f));
+ updateIcon();
myTitledSeparator.getLabel().setIconTextGap(5);
if (myContent != null) {
myContent.setVisible(true);
@@ -114,8 +120,7 @@ public class HideableDecorator {
protected void off() {
myOn = false;
- myTitledSeparator.getLabel().setIcon(AllIcons.General.SplitRight);
- myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.SplitRight, 0.5f));
+ updateIcon();
if (myContent != null) {
myContent.setVisible(false);
myPreviousContentSize = myContent.getSize();
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
index 98e8ce7213a2..2d76d6391ee8 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
@@ -16,7 +16,9 @@
package com.intellij.ui.messages;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
@@ -34,7 +36,6 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URISyntaxException;
-import com.intellij.openapi.diagnostic.Logger;
/**
* Created by Denis Fokin
@@ -120,9 +121,6 @@ public class SheetController {
if (buttonTitle.equals(focusedButton)) {
myFocusedButton = buttons[i];
}
- if (buttonTitle.equals("Cancel")) {
- myResult = "Cancel";
- }
}
if (myFocusedButton == null) {
@@ -130,7 +128,7 @@ public class SheetController {
}
if (myResult == null) {
- myResult = buttonTitles[0];
+ myResult = Messages.CANCEL_BUTTON;
}
mySheetPanel = createSheetPanel(title, message, buttons);
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
index 1b3f8f2a50ad..446722c081e4 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
@@ -66,9 +66,9 @@ public class SheetMessage {
final String defaultButton,
final String focusedButton)
{
- beforeShowFocusOwner = new WeakReference<Component>(
- KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow().getMostRecentFocusOwner()
- );
+ final Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ final Component recentFocusOwner = activeWindow == null ? null : activeWindow.getMostRecentFocusOwner();
+ beforeShowFocusOwner = new WeakReference<Component>(recentFocusOwner);
myWindow = new JDialog(owner, "This should not be shown", Dialog.ModalityType.APPLICATION_MODAL);
myWindow.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", Boolean.FALSE);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index 686e4328ead0..e1c326d33cd8 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -800,7 +800,7 @@ public class AbstractPopup implements JBPopup {
}
// can be improved by moving in myPopup code
- myPopup.getWindow().setSize(myComponent.getSize());
+ myPopup.getWindow().setSize(myContent.getSize());
myPopup.setRequestFocus(myRequestFocus);
myPopup.show();
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
index 30c609029630..72f2e1dc3b37 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,8 +16,11 @@
package com.intellij.ui.popup.list;
import com.intellij.openapi.ui.popup.ListItemDescriptor;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.EngravedLabel;
import com.intellij.ui.ErrorLabel;
+import com.intellij.ui.Gray;
import com.intellij.ui.GroupedElementsRenderer;
import com.intellij.ui.components.panels.OpaquePanel;
@@ -55,15 +58,21 @@ public class GroupedItemsListRenderer extends GroupedElementsRenderer.List imple
@Override
protected JComponent createItemComponent() {
- myTextLabel = new ErrorLabel();
- myTextLabel.setOpaque(true);
- myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ if (Registry.is("ide.new.project.settings")) {
+ myTextLabel = new EngravedLabel();
+ myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD));
+ myTextLabel.setForeground(Gray._240);
+ } else {
+ myTextLabel = new ErrorLabel();
+ myTextLabel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
+ }
+ myTextLabel.setOpaque(true);
return layoutComponent(myTextLabel);
}
protected final JComponent layoutComponent(JComponent middleItemComponent) {
- JPanel result = new OpaquePanel(new BorderLayout(4, 4), Color.white);
+ JPanel result = new OpaquePanel(Registry.is("ide.new.project.settings") ? new BorderLayout(0, 0) : new BorderLayout(4, 4), Color.white);
myNextStepLabel = new JLabel();
myNextStepLabel.setOpaque(true);
diff --git a/platform/platform-impl/src/com/intellij/util/SingleAlarm.java b/platform/platform-impl/src/com/intellij/util/SingleAlarm.java
index 09bda6ad557a..ca7a37d1900b 100644
--- a/platform/platform-impl/src/com/intellij/util/SingleAlarm.java
+++ b/platform/platform-impl/src/com/intellij/util/SingleAlarm.java
@@ -18,6 +18,7 @@ package com.intellij.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ModalityState;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class SingleAlarm extends Alarm {
private final Runnable task;
@@ -32,7 +33,7 @@ public class SingleAlarm extends Alarm {
this(task, delay, Alarm.ThreadToUse.SWING_THREAD, parentDisposable);
}
- public SingleAlarm(@NotNull Runnable task, int delay, @NotNull ThreadToUse threadToUse, @NotNull Disposable parentDisposable) {
+ public SingleAlarm(@NotNull Runnable task, int delay, @NotNull ThreadToUse threadToUse, @Nullable Disposable parentDisposable) {
super(threadToUse, parentDisposable);
this.task = task;
diff --git a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
index f13ca6628845..5b22e706508a 100644
--- a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
+++ b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
@@ -91,7 +91,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
private static final Type CALLBACK =
TypeUtils.parseType("net.sf.cglib.proxy.Callback");
private static final Type CALLBACK_ARRAY =
- Type.getType("[Lnet/sf/cglib/proxy/Callback;");
+ Type.getType(Callback[].class);
private static final Signature CSTRUCT_NULL =
TypeUtils.parseConstructor("");
private static final Signature SET_THREAD_CALLBACKS =
diff --git a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
index ed279b4bbd37..692baaf1d4e4 100644
--- a/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
+++ b/platform/platform-impl/src/org/jetbrains/io/DelegatingHttpRequestHandlerBase.java
@@ -25,10 +25,10 @@ abstract class DelegatingHttpRequestHandlerBase extends SimpleChannelInboundHand
protected void messageReceived(ChannelHandlerContext context, FullHttpRequest message) throws Exception {
if (BuiltInServer.LOG.isDebugEnabled()) {
// BuiltInServer.LOG.debug("IN HTTP:\n" + message);
- BuiltInServer.LOG.debug("IN HTTP: " + message.getUri());
+ BuiltInServer.LOG.debug("IN HTTP: " + message.uri());
}
- if (!process(context, message, new QueryStringDecoder(message.getUri()))) {
+ if (!process(context, message, new QueryStringDecoder(message.uri()))) {
Responses.sendStatus(HttpResponseStatus.NOT_FOUND, context.channel(), message);
}
}
diff --git a/platform/platform-impl/src/org/jetbrains/io/FileResponses.java b/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
index 14897fd0177c..0f187659e28c 100644
--- a/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
+++ b/platform/platform-impl/src/org/jetbrains/io/FileResponses.java
@@ -23,6 +23,7 @@ import io.netty.channel.DefaultFileRegion;
import io.netty.handler.codec.http.*;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedFile;
+import org.jetbrains.annotations.NotNull;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
@@ -46,7 +47,7 @@ public class FileResponses {
String ifModifiedSince = request.headers().get(HttpHeaders.Names.IF_MODIFIED_SINCE);
if (!StringUtil.isEmpty(ifModifiedSince)) {
try {
- if (Responses.DATE_FORMAT.get().parse(ifModifiedSince).getTime() >= lastModified) {
+ if (DATE_FORMAT.get().parse(ifModifiedSince).getTime() >= lastModified) {
send(response(HttpResponseStatus.NOT_MODIFIED), channel, request);
return true;
}
@@ -59,7 +60,7 @@ public class FileResponses {
return false;
}
- public static void sendFile(HttpRequest request, Channel channel, File file) throws IOException {
+ public static void sendFile(@NotNull HttpRequest request, @NotNull Channel channel, @NotNull File file) throws IOException {
if (checkCache(request, channel, file.lastModified())) {
return;
}
@@ -68,7 +69,7 @@ public class FileResponses {
response.headers().add(CONTENT_TYPE, getContentType(file.getPath()));
addCommonHeaders(response);
response.headers().set(HttpHeaders.Names.CACHE_CONTROL, "private, must-revalidate");
- response.headers().set(HttpHeaders.Names.LAST_MODIFIED, Responses.DATE_FORMAT.get().format(new Date(file.lastModified())));
+ response.headers().set(HttpHeaders.Names.LAST_MODIFIED, DATE_FORMAT.get().format(new Date(file.lastModified())));
boolean keepAlive = addKeepAliveIfNeed(response, request);
@@ -84,12 +85,12 @@ public class FileResponses {
try {
long fileLength = raf.length();
- if (request.getMethod() != HttpMethod.HEAD) {
+ if (request.method() != HttpMethod.HEAD) {
HttpHeaders.setContentLength(response, fileLength);
}
channel.write(response);
- if (request.getMethod() != HttpMethod.HEAD) {
+ if (request.method() != HttpMethod.HEAD) {
if (channel.pipeline().get(SslHandler.class) == null) {
// no encryption - use zero-copy
channel.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength));
diff --git a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
index 466c996b4c19..3f88327d3d28 100644
--- a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
@@ -34,6 +34,8 @@ import java.security.KeyStore;
import java.security.Security;
import java.util.UUID;
+import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
+
@ChannelHandler.Sharable
class PortUnificationServerHandler extends Decoder {
private static final AtomicNotNullLazyValue<SSLContext> SSL_SERVER_CONTEXT = new AtomicNotNullLazyValue<SSLContext>() {
@@ -113,7 +115,7 @@ class PortUnificationServerHandler extends Decoder {
if (message instanceof HttpResponse) {
// BuiltInServer.LOG.debug("OUT HTTP:\n" + message);
HttpResponse response = (HttpResponse)message;
- BuiltInServer.LOG.debug("OUT HTTP: " + response.getStatus().code() + " " + response.headers().get("Content-type"));
+ BuiltInServer.LOG.debug("OUT HTTP: " + response.status().code() + " " + response.headers().get(CONTENT_TYPE));
}
super.write(context, message, promise);
}
diff --git a/platform/platform-impl/src/org/jetbrains/io/Responses.java b/platform/platform-impl/src/org/jetbrains/io/Responses.java
index fdb2a03c5b0c..02d1d76ca1ad 100644
--- a/platform/platform-impl/src/org/jetbrains/io/Responses.java
+++ b/platform/platform-impl/src/org/jetbrains/io/Responses.java
@@ -100,7 +100,7 @@ public final class Responses {
}
public static void send(HttpResponse response, Channel channel, @Nullable HttpRequest request) {
- if (response.getStatus() != HttpResponseStatus.NOT_MODIFIED && !HttpHeaders.isContentLengthSet(response)) {
+ if (response.status() != HttpResponseStatus.NOT_MODIFIED && !HttpHeaders.isContentLengthSet(response)) {
HttpHeaders.setContentLength(response,
response instanceof FullHttpResponse ? ((FullHttpResponse)response).content().readableBytes() : 0);
}
@@ -159,7 +159,7 @@ public final class Responses {
}
private static HttpResponse createStatusResponse(HttpResponseStatus responseStatus, @Nullable HttpRequest request, @Nullable String description) {
- if (request != null && request.getMethod() == HttpMethod.HEAD) {
+ if (request != null && request.method() == HttpMethod.HEAD) {
return response(responseStatus);
}
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 59e89750f30b..cf3ca0152b2d 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -90,7 +90,7 @@ action.EditorDownWithSelection.text=Down with Selection
action.EditorLeftWithSelection.text=Left with Selection
action.EditorRightWithSelection.text=Right with Selection
action.EditorIndentSelection.text=Indent Selection
-action.EditorUnindentSelection.text=Unindent Selection
+action.EditorUnindentSelection.text=Unindent Line or Selection
action.EditorIndentLineOrSelection.text=Indent Line or Selection
action.EditorTab.text=Tab
action.EditorResetFontSize.text=Reset Font Size
@@ -454,8 +454,8 @@ action.GotoNextError.text=_Next Highlighted Error
action.GotoNextError.description=Navigate to the next highlighted error in the active editor
action.GotoPreviousError.text=_Previous Highlighted Error
action.GotoPreviousError.description=Navigate to the previous highlighted error in the active editor
-action.GotoRelated.text=_Related File...
-action.GotoRelated.description=Navigate to one of the related or linked files
+action.GotoRelated.text=_Related Symbol...
+action.GotoRelated.description=Navigate to one of the related or linked symbols
action.MethodDown.text=N_ext Method
action.MethodDown.description=Navigate to the next method in the active editor
action.MethodUp.text=Prev_ious Method
@@ -559,8 +559,6 @@ action.Move.text=_Move...
action.Move.description=Move the selected class, method, package or static member to another package or class and correct all references
action.CopyElement.text=C_opy...
action.CopyElement.description=Create a copy of the selected class, file(s) or directory(es)
-action.CloneElement.text=Clo_ne...
-action.CloneElement.description=Create a copy of the selected class, file or directory in the same package/directory
action.SafeDelete.text=Safe _Delete...
action.SafeDelete.description=Delete the selected class, method or field, checking for usages
action.ExtractMethod.text=_Method...
@@ -1176,6 +1174,8 @@ action.FileChooser.NewFile.text=New File...
action.FileChooser.NewFile.description=Create new file
action.FileChooser.GotoHome.text=Home Directory
action.FileChooser.GotoHome.description=Go to home directory
+action.FileChooser.GotoDesktop.text=Desktop Directory
+action.FileChooser.GotoDesktop.description=Go to Desktop directory directory
action.FileChooser.GotoProject.text=Project Directory
action.FileChooser.GotoProject.description=Go to project directory
action.FileChooser.GotoModule.text=Module Directory
diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
index aa1877f3eebc..fb3d47133256 100644
--- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties
+++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
@@ -350,6 +350,7 @@ checkbox.collapse.annotations=<html>Annotations</html>
checkbox.collapse.inner.classes=Inner classes
checkbox.collapse.simple.property.accessors=<html>Simple property accessors<html>
checkbox.collapse.one.line.methods=<html>One-line methods<html>
+checkbox.collapse.boolean.parameters=<html>Inline parameter names for literal call arguments</html>
checkbox.collapse.method.bodies=Method bodies
checkbox.collapse.javadoc.comments=Documentation comments
checkbox.collapse.title.imports=Imports
@@ -407,6 +408,7 @@ checkbox.smart.indent=Smart indent
label.smart.enter=Smart Enter:
checkbox.smart.end.on.blank.line=End (on blank line)
checkbox.smart.home=Home
+checkbox.indenting.backspace=Backspace smart indent
group.error.highlighting=Error highlighting
editbox.autoreparse.delay.ms=Autoreparse delay (ms):
editbox.error.stripe.mark.min.height.pixels=Error stripe mark min height (pixels):
@@ -508,7 +510,6 @@ title.file.status=File Status
title.scope.based=Scope Based
title.colors.and.fonts=Colors \\& Fonts
progress.analysing.font=Analysing font: {0}
-button.edit.scopes=Edit Scopes...
group.editor.font=Editor Font
label.fallback.fonts.list.description=If primary font fails, IDE tries to use the secondary one
quickdoc.tooltip.font.size.by.wheel=Slider or Ctrl+Wheel change font size
diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties
index e5d15e334da7..155e2b6c6d74 100644
--- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties
+++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties
@@ -16,7 +16,7 @@ home.directory.not.specified.for.jdk.error.message=Home directory is not specifi
run.configuration.pause.output.action.name=Pause Output
main.class.is.not.specified.error.message=Main class is not specified
close.tab.action.name=Close
-run.configuration.show.command.line.action.name=Show Python Prompt
+run.configuration.show.command.line.action.name=Show Console Prompt
#---
create.run.configuration.action.name=Create Run Configuration
diff --git a/platform/platform-resources-en/src/messages/FindBundle.properties b/platform/platform-resources-en/src/messages/FindBundle.properties
index 2c17b13d459d..293d013fe8d6 100644
--- a/platform/platform-resources-en/src/messages/FindBundle.properties
+++ b/platform/platform-resources-en/src/messages/FindBundle.properties
@@ -44,7 +44,6 @@ find.field.accessors.title=Search Accessors
find.pointcut.applications.not.found.title=Information
find.usages.of.element.in.scope.panel.title={0} of {1} in {2}
find.usages.of.element.tab.name={0} of {1}
-find.usages.of.element.panel.title={0} of {1}
recent.find.usages.action.description=<html><body>{0} ''<b>{1}</b>'' in {2}</body></html>
recent.find.usages.action.popup={0} ''{1}'' in {2}
recent.find.usages.action.title=Recent Find Usages
diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties
index 5ca152bc0ab0..b6180094abd1 100644
--- a/platform/platform-resources-en/src/messages/IdeBundle.properties
+++ b/platform/platform-resources-en/src/messages/IdeBundle.properties
@@ -40,6 +40,8 @@ checkbox.synchronize.files.on.frame.activation=Synchronize files on frame activa
checkbox.reopen.last.project.on.startup=Reopen last project on startup
treenode.loading= loading...
action.clear.list=_Clear List
+action.clear.list.message=Would you like to clear the list of recent projects?
+action.clear.list.title=Clear Recent Projects List
action.descriptor.action=Action: {0}
action.descriptor.typing=Typing: "{0}"
action.descriptor.keystroke=Keystroke: "{0}"
@@ -704,7 +706,7 @@ label.please.enter.project.name=Please enter a name to create a new {0} {1}.
prompt.please.select.project.jdk=Please select project SDK.\nThis SDK will be used by default by all project modules.
label.project.jdk=Project SDK:
button.configure=&Configure...
-prompt.confirm.project.no.jdk=Do you want to create a project with no SDK assigned?\nSDK is required for compiling, debugging and running applications\nas well as for standard SDK classes resolution.
+prompt.confirm.project.no.jdk=Do you want to create a project with no SDK assigned?\nAn SDK is required for compiling, debugging and running applications\n, as well as for the standard SDK classes resolution.
title.no.jdk.specified=No SDK Specified
prompt.please.specify.module.name=Please specify module name
prompt.please.specify.module.name.and.content.root=Please specify module name and module content root.\nA module content root is a directory where the files that belong to the module are stored.
@@ -969,7 +971,7 @@ add.scope.name.label=Name
add.scope.dialog.title=Add New Scope
scope.banner.text=Scope ''{0}''
prompt.please.select.module.jdk=Please select the {0} to be set for this module
-scopes.save.dialog.title.shared=Save as shared scope
+scopes.save.dialog.title.shared=Save as Shared Scope
scopes.save.dialog.title.local=Save as local scope
plugin.version.label=Version
plugin.size.label=Size:
@@ -977,7 +979,7 @@ plugin.status.available=Available
detach.library.from.module=Detach library ''{0}'' from module ''{1}''?\nNo file on disk will be hurt.
detach.library=Detach Library
scope.unable.to.save.scope.message=Do you want to save scope as shared?
-scope.unable.to.save.scope.title=Unable to use local scope
+scope.unable.to.save.scope.title=Unable to Use Local Scope
predefined.scope.production.name=Production
plugin.manager.dependencies.detected.title=Plugin Dependencies Detected
plugin.manager.dependencies.detected.message=The plugin you want to install requires other plugin{0, choice, 1#|2#s} ({1}) which have to be installed as well. Proceed?
diff --git a/platform/platform-resources-en/src/messages/UsageView.properties b/platform/platform-resources-en/src/messages/UsageView.properties
index 1e33db40cad1..a65327e0a255 100644
--- a/platform/platform-resources-en/src/messages/UsageView.properties
+++ b/platform/platform-resources-en/src/messages/UsageView.properties
@@ -20,7 +20,6 @@ action.description.rerun=Rerun search
dialog.rerun.search=Would you like to rerun the search now?
action.next.occurrence=Next Occurrence
action.previous.occurrence=Previous Occurrence
-progress.searching.for=Searching for {0}...
progress.searching.for.in=Searching for {0} in {1}...
dialog.no.usages.found.in=No {0} found in {1}
dialog.title.information=Information
diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties
index 594db771aa60..3d34252c9c7a 100644
--- a/platform/platform-resources-en/src/messages/VcsBundle.properties
+++ b/platform/platform-resources-en/src/messages/VcsBundle.properties
@@ -82,8 +82,8 @@ message.text.could.not.load.virtual.file.content=Could not load content for file
message.title.could.not.load.content=Could Not Load Content
message.text.commit.failed.with.errors.and.warnings=Commit failed with errors and warnings
message.title.commit=Commit
-message.text.commit.failed.with.errors=Commit failed with errors
-message.text.commit.finished.with.warnings=Commit finished with warnings
+message.text.commit.failed.with.error=Commit failed with error
+message.text.commit.finished.with.warning=Commit finished with warning
message.text.binary.versions.are.identical=Binary versions are identical
message.title.diff=Diff
message.text.binary.versions.are.different=Binary versions are different
@@ -138,6 +138,8 @@ button.configure=&Configure VCS...
action.name.rollback=Rollback
command.name.rollback.change=Rollback Change
action.name.show.difference=Show Difference
+tooltip.text.line.before.deleted=Line before {0} deleted
+tooltip.text.lines.before.deleted={1} lines before {0} deleted
tooltip.text.line.changed=Line {0} changed
tooltip.text.lines.changed=Lines {0}-{1} changed
dialog.title.diff.for.range=Diff for Range
diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties
index 1ef6ef385adb..70e26de6ffeb 100644
--- a/platform/platform-resources-en/src/messages/XmlBundle.properties
+++ b/platform/platform-resources-en/src/messages/XmlBundle.properties
@@ -217,7 +217,7 @@ select.xsd.schema.dialog.title=Select XSD Schema
emmet.title=Emmet
emmet.configuration.title=Emmet
emmet.enable.label=&Enable XML Emmet
-emmet.enable.bem.filter=Enable &BEM filter by default
+emmet.filters.enabled.by.default=Filters enabled by default
emmet.enable.preview=Enable &abbreviation preview
emmet.expand.abbreviation.with=Expand &abbreviation with
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties
index 028ac70c1c73..8febeb004c43 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/platform-resources-en/src/misc/registry.properties
@@ -140,7 +140,7 @@ ide.mac.inplaceDialogMnemonicsFix=false
ide.mac.fix.dialog.showing=false
ide.mac.hide.cursor.when.typing=true
ide.mac.show.native.help=true
-ide.mac.useNativeClipboard=true
+ide.mac.useNativeClipboard=false
ide.mac.boldEditorTabs=false
ide.mac.disableMacScrollbars=false
ide.mac.disableMacScrollbars.description=Disables OS X overlay scrollbars (effective on restart)
@@ -198,6 +198,9 @@ compiler.automake.trigger.delay=300
# suppress inspection "UnusedProperty"
compiler.automake.trigger.delay.description=Delay in milliseconds before triggering auto-make in response to file system events
+compiler.automake.force.fs.rescan=false
+compiler.automake.force.fs.rescan.description=When enabled, for all automatically started builds (automake) collected VFS changes will be ignored and modified files will be determined with FS rescan will be forces
+
compiler.document.save.trigger.delay=1500
# suppress inspection "UnusedProperty"
compiler.document.save.trigger.delay.description=Delay in milliseconds before triggering save in response to document changes
@@ -205,6 +208,7 @@ compiler.document.save.trigger.delay.description=Delay in milliseconds before tr
vcs.show.colored.annotations=true
vcs.showConsole=true
vcs.log.bek.sort=false
+vcs.log.bek.sort.disabled=false
psi.incremental.reparse.depth.limit=1000
psi.deferIconLoading=true
@@ -401,3 +405,8 @@ console.too.much.text.buffer.ratio=10
console.too.much.text.buffer.ratio.description=Used for disabling of console processing(console filters for highlights, foldings...),\n\
when there is too much of text to process.\n\
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
+ide.new.project.settings=false
+ide.new.project.settings.description=Temporary key for new project settings dialog UI
+
+commonjs.complete.required.filename.with.extension=false
+commonjs.complete.required.filename.with.extension.description=If checked, required filenames are completed with extension
diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
index f25ff6b67232..dcdc0e2d983c 100644
--- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
@@ -147,6 +147,11 @@
<with attribute="implementationClass" implements="com.intellij.lang.Commenter"/>
</extensionPoint>
+ <extensionPoint name="lang.inspectionSuppressor"
+ beanClass="com.intellij.lang.LanguageExtensionPoint">
+ <with attribute="implementationClass" implements="com.intellij.codeInspection.InspectionSuppressor"/>
+ </extensionPoint>
+
<extensionPoint name="lang.braceMatcher"
beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.PairedBraceMatcher"/>
@@ -804,6 +809,7 @@
<extensionPoint name="sdkResolveScopeProvider" interface="com.intellij.psi.SdkResolveScopeProvider"/>
<extensionPoint name="goto.nonProjectScopeDisabler" beanClass="com.intellij.ide.actions.NonProjectScopeDisablerEP"/>
+ <extensionPoint qualifiedName="com.intellij.equivalenceDescriptorProvider" interface="com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider"/>
</extensionPoints>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index aba480580eae..0e6680392f94 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -594,6 +594,8 @@
id="EnterBetweenBracesHandler"/>
<enterHandlerDelegate implementation="com.intellij.codeInsight.editorActions.enter.EnterAfterJavadocTagHandler"/>
+ <backspaceHandlerDelegate implementation="com.intellij.codeInsight.editorActions.IndentingBackspaceHandler" />
+
<codeInsight.linkHandler prefix="#inspection/" handlerClass="com.intellij.codeInsight.hint.InspectionDescriptionLinkHandler"/>
<codeInsight.linkHandler prefix="#navigation/" handlerClass="com.intellij.codeInsight.hint.NavigationLinkHandler"/>
@@ -656,7 +658,7 @@
<editorActionHandler action="EditorBackSpace" implementationClass="com.intellij.codeInsight.editorActions.BackspaceHandler"/>
<editorActionHandler action="EditorDeleteToWordStart"
implementationClass="com.intellij.codeInsight.editorActions.BackspaceToWordStartHandler"/>
- <editorTypedHandler implementationClass="com.intellij.codeInsight.editorActions.TypedHandler"/>
+ <editorTypedHandler implementationClass="com.intellij.codeInsight.editorActions.TypedHandler" order="first"/>
<editorActionHandler action="EditorDuplicate" implementationClass="com.intellij.openapi.editor.actions.NamedElementDuplicateHandler"/>
@@ -680,7 +682,7 @@
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.refactoring.rename.inplace.EscapeHandler"
order="before hide-hints"/>
- <typedHandler implementation="com.intellij.codeInsight.lookup.impl.LookupTypedHandler" id="lookup" order="first"/>
+ <editorTypedHandler implementationClass="com.intellij.codeInsight.lookup.impl.LookupTypedHandler" id="lookup"/>
<typedHandler implementation="com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler" id="completionAutoPopup"
order="first"/>
<typedHandler implementation="com.intellij.codeInsight.editorActions.SelectionQuotingTypedHandler" id="selectionQuoting"/>
@@ -871,6 +873,7 @@
<lang.foldingBuilder language="TEXT" implementationClass="com.intellij.ide.highlighter.custom.impl.CustomFileTypeFoldingBuilder"/>
<virtualFileSystem key="scratchpad" implementationClass="com.intellij.ide.scratch.ScratchpadFileSystem"/>
+ <fileIconProvider implementation="com.intellij.ide.scratch.ScratchpadIconProvider"/>
<applicationService serviceImplementation="com.intellij.openapi.editor.richcopy.settings.RichCopySettings"/>
<copyPastePostProcessor implementation="com.intellij.openapi.editor.richcopy.TextWithMarkupProcessor"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 8b17da2d6dd5..851a91d314ab 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -283,6 +283,7 @@
serviceImplementation="com.intellij.ide.TypePresentationServiceImpl"/>
<postStartupActivity implementation="com.intellij.ide.TipOfTheDayManager"/>
+ <postStartupActivity implementation="com.intellij.ide.actions.PowerSaveModeNotifier"/>
<postStartupActivity implementation="com.intellij.openapi.actionSystem.impl.ActionPreloader"/>
<postStartupActivity id="OpenFilesActivity" implementation="com.intellij.openapi.fileEditor.impl.OpenFilesActivity"/>
@@ -302,6 +303,7 @@
<applicationService serviceInterface="org.jetbrains.ide.BuiltInServerManager" serviceImplementation="org.jetbrains.ide.BuiltInServerManagerImpl"/>
<applicationService serviceInterface="com.intellij.ide.XmlRpcServer" serviceImplementation="com.intellij.ide.XmlRpcServerImpl"/>
+ <applicationService serviceImplementation="com.intellij.util.net.ssl.CertificateManager"/>
<httpRequestHandler implementation="com.intellij.ide.XmlRpcServerImpl$XmlRpcRequestHandler"/>
<postStartupActivity implementation="org.jetbrains.ide.BuiltInServerManagerImpl$MyPostStartupActivity"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformPlugin.xml b/platform/platform-resources/src/META-INF/PlatformPlugin.xml
index 3ad57625810c..db1cae3e76aa 100644
--- a/platform/platform-resources/src/META-INF/PlatformPlugin.xml
+++ b/platform/platform-resources/src/META-INF/PlatformPlugin.xml
@@ -48,8 +48,7 @@
serviceImplementation="com.intellij.openapi.wm.impl.PlatformFrameTitleBuilder"/>
<projectService serviceInterface="com.intellij.platform.ProjectBaseDirectory"
serviceImplementation="com.intellij.platform.ProjectBaseDirectory"/>
- <postStartupActivity implementation="com.intellij.platform.FilesystemToolwindowOpener"/>
-
+
<projectOpenProcessor implementation="com.intellij.platform.PlatformProjectOpenProcessor"/>
</extensions>
diff --git a/platform/platform-resources/src/META-INF/XmlActions.xml b/platform/platform-resources/src/META-INF/XmlActions.xml
index a6f36bedcd4f..af40211eedde 100644
--- a/platform/platform-resources/src/META-INF/XmlActions.xml
+++ b/platform/platform-resources/src/META-INF/XmlActions.xml
@@ -78,9 +78,7 @@
icon="AllIcons.Nodes.PpWeb">
</action>
- <group id="OpenInBrowserGroup"
- class="com.intellij.ide.browsers.actions.OpenInBrowserBaseGroupAction$OpenInBrowserGroupAction"
- text="Open in _Browser" description="Open selected file in browser" icon="AllIcons.Nodes.PpWeb">
+ <group id="OpenInBrowserGroup" class="com.intellij.ide.browsers.actions.OpenInBrowserBaseGroupAction$OpenInBrowserGroupAction">
<add-to-group group-id="ViewMenu" anchor="after" relative-to-action="ViewSource"/>
<add-to-group group-id="RunContextPopupGroup" anchor="last"/>
</group>
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index d79152d8c54e..9da1e3317e13 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -529,6 +529,7 @@
<applicationConfigurable instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
key="browsers.settings" bundle="messages.IdeBundle"/>
+ <lang.inspectionSuppressor language="XML" implementationClass="com.intellij.codeInspection.XmlInspectionSuppressor"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains">
<urlOpener implementation="com.intellij.ide.browsers.impl.DefaultUrlOpener" order="last"/>
diff --git a/platform/platform-resources/src/META-INF/mime.types b/platform/platform-resources/src/META-INF/mime.types
index f8e1cde3315d..699aa1b3058b 100644
--- a/platform/platform-resources/src/META-INF/mime.types
+++ b/platform/platform-resources/src/META-INF/mime.types
@@ -1,1353 +1,89 @@
-# This file maps Internet media types to unique file extension(s).
-# Although created for httpd, this file is used by many software systems
-# and has been placed in the public domain for unlimited redisribution.
-#
-# The table below contains both registered and (common) unregistered types.
-# A type that has no unique extension can be ignored -- they are listed
-# here to guide configurations toward known types and to make it easier to
-# identify "new" types. File extensions are also commonly used to indicate
-# content languages and encodings, so choose them carefully.
-#
-# Internet media types should be registered as described in RFC 4288.
-# The registry is at <http://www.iana.org/assignments/media-types/>.
-#
-# MIME type Extensions
-# application/3gpp-ims+xml
-# application/activemessage
-application/andrew-inset ez
-# application/applefile
-application/applixware aw
-application/atom+xml atom
-application/atomcat+xml atomcat
-# application/atomicmail
-application/atomsvc+xml atomsvc
-# application/auth-policy+xml
-# application/batch-smtp
-# application/beep+xml
-# application/cals-1840
-application/ccxml+xml ccxml
-# application/cea-2018+xml
-# application/cellml+xml
-# application/cnrp+xml
-# application/commonground
-# application/conference-info+xml
-# application/cpl+xml
-# application/csta+xml
-# application/cstadata+xml
-application/cu-seeme cu
-# application/cybercash
-application/davmount+xml davmount
-# application/dca-rft
-# application/dec-dx
-# application/dialog-info+xml
-# application/dicom
-# application/dns
-application/dssc+der dssc
-application/dssc+xml xdssc
-# application/dvcs
-application/ecmascript ecma
-# application/edi-consent
-# application/edi-x12
-# application/edifact
-application/emma+xml emma
-# application/epp+xml
-application/epub+zip epub
-# application/eshop
-# application/example
-# application/fastinfoset
-# application/fastsoap
-# application/fits
-application/font-tdpfr pfr
-# application/h224
-# application/held+xml
-# application/http
-application/hyperstudio stk
-# application/ibe-key-request+xml
-# application/ibe-pkg-reply+xml
-# application/ibe-pp-data
-# application/iges
-# application/im-iscomposing+xml
-# application/index
-# application/index.cmd
-# application/index.obj
-# application/index.response
-# application/index.vnd
-# application/iotp
-application/ipfix ipfix
-# application/ipp
-# application/isup
-application/java-archive jar
-application/java-serialized-object ser
-application/java-vm class
-application/javascript js
-application/json json
-# application/kpml-request+xml
-# application/kpml-response+xml
-application/lost+xml lostxml
-application/mac-binhex40 hqx
-application/mac-compactpro cpt
-# application/macwriteii
-application/marc mrc
-application/mathematica ma nb mb
-application/mathml+xml mathml
-# application/mbms-associated-procedure-description+xml
-# application/mbms-deregister+xml
-# application/mbms-envelope+xml
-# application/mbms-msk+xml
-# application/mbms-msk-response+xml
-# application/mbms-protection-description+xml
-# application/mbms-reception-report+xml
-# application/mbms-register+xml
-# application/mbms-register-response+xml
-# application/mbms-user-service-description+xml
-application/mbox mbox
-# application/media_control+xml
-application/mediaservercontrol+xml mscml
-# application/mikey
-# application/moss-keys
-# application/moss-signature
-# application/mosskey-data
-# application/mosskey-request
-application/mp4 mp4s
-# application/mpeg4-generic
-# application/mpeg4-iod
-# application/mpeg4-iod-xmt
-application/msword doc dot
-application/mxf mxf
-# application/nasdata
-# application/news-checkgroups
-# application/news-groupinfo
-# application/news-transmission
-# application/nss
-# application/ocsp-request
-# application/ocsp-response
-application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy
-application/oda oda
-application/oebps-package+xml opf
-application/ogg ogx
-application/onenote onetoc onetoc2 onetmp onepkg
-# application/parityfec
-application/patch-ops-error+xml xer
-application/pdf pdf
-application/pgp-encrypted pgp
-# application/pgp-keys
-application/pgp-signature asc sig
-application/pics-rules prf
-# application/pidf+xml
-# application/pidf-diff+xml
-application/pkcs10 p10
-application/pkcs7-mime p7m p7c
-application/pkcs7-signature p7s
-application/pkix-cert cer
-application/pkix-crl crl
-application/pkix-pkipath pkipath
-application/pkixcmp pki
-application/pls+xml pls
-# application/poc-settings+xml
-application/postscript ai eps ps
-# application/prs.alvestrand.titrax-sheet
-application/prs.cww cww
-# application/prs.nprend
-# application/prs.plucker
-# application/qsig
-application/rdf+xml rdf
-application/reginfo+xml rif
-application/relax-ng-compact-syntax rnc
-# application/remote-printing
-application/resource-lists+xml rl
-application/resource-lists-diff+xml rld
-# application/riscos
-# application/rlmi+xml
-application/rls-services+xml rs
-application/rsd+xml rsd
-application/rss+xml rss
-application/rtf rtf
-# application/rtx
-# application/samlassertion+xml
-# application/samlmetadata+xml
-application/sbml+xml sbml
-application/scvp-cv-request scq
-application/scvp-cv-response scs
-application/scvp-vp-request spq
-application/scvp-vp-response spp
-application/sdp sdp
-# application/set-payment
-application/set-payment-initiation setpay
-# application/set-registration
-application/set-registration-initiation setreg
-# application/sgml
-# application/sgml-open-catalog
-application/shf+xml shf
-# application/sieve
-# application/simple-filter+xml
-# application/simple-message-summary
-# application/simplesymbolcontainer
-# application/slate
-# application/smil
-application/smil+xml smi smil
-# application/soap+fastinfoset
-# application/soap+xml
-application/sparql-query rq
-application/sparql-results+xml srx
-# application/spirits-event+xml
-application/srgs gram
-application/srgs+xml grxml
-application/ssml+xml ssml
-# application/timestamp-query
-# application/timestamp-reply
-# application/tve-trigger
-# application/ulpfec
-# application/vemmi
-# application/vividence.scriptfile
-# application/vnd.3gpp.bsf+xml
-application/vnd.3gpp.pic-bw-large plb
-application/vnd.3gpp.pic-bw-small psb
-application/vnd.3gpp.pic-bw-var pvb
-# application/vnd.3gpp.sms
-# application/vnd.3gpp2.bcmcsinfo+xml
-# application/vnd.3gpp2.sms
-application/vnd.3gpp2.tcap tcap
-application/vnd.3m.post-it-notes pwn
-application/vnd.accpac.simply.aso aso
-application/vnd.accpac.simply.imp imp
-application/vnd.acucobol acu
-application/vnd.acucorp atc acutc
-application/vnd.adobe.air-application-installer-package+zip air
-# application/vnd.adobe.partial-upload
-application/vnd.adobe.xdp+xml xdp
-application/vnd.adobe.xfdf xfdf
-# application/vnd.aether.imp
-application/vnd.airzip.filesecure.azf azf
-application/vnd.airzip.filesecure.azs azs
-application/vnd.amazon.ebook azw
-application/vnd.americandynamics.acc acc
-application/vnd.amiga.ami ami
-application/vnd.android.package-archive apk
-application/vnd.anser-web-certificate-issue-initiation cii
-application/vnd.anser-web-funds-transfer-initiation fti
-application/vnd.antix.game-component atx
-application/vnd.apple.installer+xml mpkg
-application/vnd.apple.mpegurl m3u8
-# application/vnd.arastra.swi
-application/vnd.aristanetworks.swi swi
-application/vnd.audiograph aep
-# application/vnd.autopackage
-# application/vnd.avistar+xml
-application/vnd.blueice.multipass mpm
-# application/vnd.bluetooth.ep.oob
-application/vnd.bmi bmi
-application/vnd.businessobjects rep
-# application/vnd.cab-jscript
-# application/vnd.canon-cpdl
-# application/vnd.canon-lips
-# application/vnd.cendio.thinlinc.clientconf
-application/vnd.chemdraw+xml cdxml
-application/vnd.chipnuts.karaoke-mmd mmd
-application/vnd.cinderella cdy
-# application/vnd.cirpack.isdn-ext
-application/vnd.claymore cla
-application/vnd.cloanto.rp9 rp9
-application/vnd.clonk.c4group c4g c4d c4f c4p c4u
-# application/vnd.commerce-battelle
-application/vnd.commonspace csp
-application/vnd.contact.cmsg cdbcmsg
-application/vnd.cosmocaller cmc
-application/vnd.crick.clicker clkx
-application/vnd.crick.clicker.keyboard clkk
-application/vnd.crick.clicker.palette clkp
-application/vnd.crick.clicker.template clkt
-application/vnd.crick.clicker.wordbank clkw
-application/vnd.criticaltools.wbs+xml wbs
-application/vnd.ctc-posml pml
-# application/vnd.ctct.ws+xml
-# application/vnd.cups-pdf
-# application/vnd.cups-postscript
-application/vnd.cups-ppd ppd
-# application/vnd.cups-raster
-# application/vnd.cups-raw
-application/vnd.curl.car car
-application/vnd.curl.pcurl pcurl
-# application/vnd.cybank
-application/vnd.data-vision.rdz rdz
-application/vnd.denovo.fcselayout-link fe_launch
-# application/vnd.dir-bi.plate-dl-nosuffix
-application/vnd.dna dna
-application/vnd.dolby.mlp mlp
-# application/vnd.dolby.mobile.1
-# application/vnd.dolby.mobile.2
-application/vnd.dpgraph dpg
-application/vnd.dreamfactory dfac
-# application/vnd.dvb.esgcontainer
-# application/vnd.dvb.ipdcdftnotifaccess
-# application/vnd.dvb.ipdcesgaccess
-# application/vnd.dvb.ipdcroaming
-# application/vnd.dvb.iptv.alfec-base
-# application/vnd.dvb.iptv.alfec-enhancement
-# application/vnd.dvb.notif-aggregate-root+xml
-# application/vnd.dvb.notif-container+xml
-# application/vnd.dvb.notif-generic+xml
-# application/vnd.dvb.notif-ia-msglist+xml
-# application/vnd.dvb.notif-ia-registration-request+xml
-# application/vnd.dvb.notif-ia-registration-response+xml
-# application/vnd.dvb.notif-init+xml
-# application/vnd.dxr
-application/vnd.dynageo geo
-# application/vnd.ecdis-update
-application/vnd.ecowin.chart mag
-# application/vnd.ecowin.filerequest
-# application/vnd.ecowin.fileupdate
-# application/vnd.ecowin.series
-# application/vnd.ecowin.seriesrequest
-# application/vnd.ecowin.seriesupdate
-# application/vnd.emclient.accessrequest+xml
-application/vnd.enliven nml
-application/vnd.epson.esf esf
-application/vnd.epson.msf msf
-application/vnd.epson.quickanime qam
-application/vnd.epson.salt slt
-application/vnd.epson.ssf ssf
-# application/vnd.ericsson.quickcall
-application/vnd.eszigno3+xml es3 et3
-# application/vnd.etsi.aoc+xml
-# application/vnd.etsi.cug+xml
-# application/vnd.etsi.iptvcommand+xml
-# application/vnd.etsi.iptvdiscovery+xml
-# application/vnd.etsi.iptvprofile+xml
-# application/vnd.etsi.iptvsad-bc+xml
-# application/vnd.etsi.iptvsad-cod+xml
-# application/vnd.etsi.iptvsad-npvr+xml
-# application/vnd.etsi.iptvueprofile+xml
-# application/vnd.etsi.mcid+xml
-# application/vnd.etsi.sci+xml
-# application/vnd.etsi.simservs+xml
-# application/vnd.etsi.tsl+xml
-# application/vnd.etsi.tsl.der
-# application/vnd.eudora.data
-application/vnd.ezpix-album ez2
-application/vnd.ezpix-package ez3
-# application/vnd.f-secure.mobile
-application/vnd.fdf fdf
-application/vnd.fdsn.mseed mseed
-application/vnd.fdsn.seed seed dataless
-# application/vnd.ffsns
-# application/vnd.fints
-application/vnd.flographit gph
-application/vnd.fluxtime.clip ftc
-# application/vnd.font-fontforge-sfd
-application/vnd.framemaker fm frame maker book
-application/vnd.frogans.fnc fnc
-application/vnd.frogans.ltf ltf
-application/vnd.fsc.weblaunch fsc
-application/vnd.fujitsu.oasys oas
-application/vnd.fujitsu.oasys2 oa2
-application/vnd.fujitsu.oasys3 oa3
-application/vnd.fujitsu.oasysgp fg5
-application/vnd.fujitsu.oasysprs bh2
-# application/vnd.fujixerox.art-ex
-# application/vnd.fujixerox.art4
-# application/vnd.fujixerox.hbpl
-application/vnd.fujixerox.ddd ddd
-application/vnd.fujixerox.docuworks xdw
-application/vnd.fujixerox.docuworks.binder xbd
-# application/vnd.fut-misnet
-application/vnd.fuzzysheet fzs
-application/vnd.genomatix.tuxedo txd
-# application/vnd.geocube+xml
-application/vnd.geogebra.file ggb
-application/vnd.geogebra.tool ggt
-application/vnd.geometry-explorer gex gre
-application/vnd.geonext gxt
-application/vnd.geoplan g2w
-application/vnd.geospace g3w
-# application/vnd.globalplatform.card-content-mgt
-# application/vnd.globalplatform.card-content-mgt-response
-application/vnd.gmx gmx
-application/vnd.google-earth.kml+xml kml
-application/vnd.google-earth.kmz kmz
-application/vnd.grafeq gqf gqs
-# application/vnd.gridmp
-application/vnd.groove-account gac
-application/vnd.groove-help ghf
-application/vnd.groove-identity-message gim
-application/vnd.groove-injector grv
-application/vnd.groove-tool-message gtm
-application/vnd.groove-tool-template tpl
-application/vnd.groove-vcard vcg
-application/vnd.handheld-entertainment+xml zmm
-application/vnd.hbci hbci
-# application/vnd.hcl-bireports
-application/vnd.hhe.lesson-player les
-application/vnd.hp-hpgl hpgl
-application/vnd.hp-hpid hpid
-application/vnd.hp-hps hps
-application/vnd.hp-jlyt jlt
-application/vnd.hp-pcl pcl
-application/vnd.hp-pclxl pclxl
-# application/vnd.httphone
-application/vnd.hydrostatix.sof-data sfd-hdstx
-application/vnd.hzn-3d-crossword x3d
-# application/vnd.ibm.afplinedata
-# application/vnd.ibm.electronic-media
-application/vnd.ibm.minipay mpy
-application/vnd.ibm.modcap afp listafp list3820
-application/vnd.ibm.rights-management irm
-application/vnd.ibm.secure-container sc
-application/vnd.iccprofile icc icm
-application/vnd.igloader igl
-application/vnd.immervision-ivp ivp
-application/vnd.immervision-ivu ivu
-# application/vnd.informedcontrol.rms+xml
-# application/vnd.informix-visionary
-application/vnd.intercon.formnet xpw xpx
-# application/vnd.intertrust.digibox
-# application/vnd.intertrust.nncp
-application/vnd.intu.qbo qbo
-application/vnd.intu.qfx qfx
-# application/vnd.iptc.g2.conceptitem+xml
-# application/vnd.iptc.g2.knowledgeitem+xml
-# application/vnd.iptc.g2.newsitem+xml
-# application/vnd.iptc.g2.packageitem+xml
-application/vnd.ipunplugged.rcprofile rcprofile
-application/vnd.irepository.package+xml irp
-application/vnd.is-xpr xpr
-application/vnd.jam jam
-# application/vnd.japannet-directory-service
-# application/vnd.japannet-jpnstore-wakeup
-# application/vnd.japannet-payment-wakeup
-# application/vnd.japannet-registration
-# application/vnd.japannet-registration-wakeup
-# application/vnd.japannet-setstore-wakeup
-# application/vnd.japannet-verification
-# application/vnd.japannet-verification-wakeup
-application/vnd.jcp.javame.midlet-rms rms
-application/vnd.jisp jisp
-application/vnd.joost.joda-archive joda
-application/vnd.kahootz ktz ktr
-application/vnd.kde.karbon karbon
-application/vnd.kde.kchart chrt
-application/vnd.kde.kformula kfo
-application/vnd.kde.kivio flw
-application/vnd.kde.kontour kon
-application/vnd.kde.kpresenter kpr kpt
-application/vnd.kde.kspread ksp
-application/vnd.kde.kword kwd kwt
-application/vnd.kenameaapp htke
-application/vnd.kidspiration kia
-application/vnd.kinar kne knp
-application/vnd.koan skp skd skt skm
-application/vnd.kodak-descriptor sse
-# application/vnd.liberty-request+xml
-application/vnd.llamagraphics.life-balance.desktop lbd
-application/vnd.llamagraphics.life-balance.exchange+xml lbe
-application/vnd.lotus-1-2-3 123
-application/vnd.lotus-approach apr
-application/vnd.lotus-freelance pre
-application/vnd.lotus-notes nsf
-application/vnd.lotus-organizer org
-application/vnd.lotus-screencam scm
-application/vnd.lotus-wordpro lwp
-application/vnd.macports.portpkg portpkg
-# application/vnd.marlin.drm.actiontoken+xml
-# application/vnd.marlin.drm.conftoken+xml
-# application/vnd.marlin.drm.license+xml
-# application/vnd.marlin.drm.mdcf
-application/vnd.mcd mcd
-application/vnd.medcalcdata mc1
-application/vnd.mediastation.cdkey cdkey
-# application/vnd.meridian-slingshot
-application/vnd.mfer mwf
-application/vnd.mfmp mfm
-application/vnd.micrografx.flo flo
-application/vnd.micrografx.igx igx
-application/vnd.mif mif
-# application/vnd.minisoft-hp3000-save
-# application/vnd.mitsubishi.misty-guard.trustweb
-application/vnd.mobius.daf daf
-application/vnd.mobius.dis dis
-application/vnd.mobius.mbk mbk
-application/vnd.mobius.mqy mqy
-application/vnd.mobius.msl msl
-application/vnd.mobius.plc plc
-application/vnd.mobius.txf txf
-application/vnd.mophun.application mpn
-application/vnd.mophun.certificate mpc
-# application/vnd.motorola.flexsuite
-# application/vnd.motorola.flexsuite.adsi
-# application/vnd.motorola.flexsuite.fis
-# application/vnd.motorola.flexsuite.gotap
-# application/vnd.motorola.flexsuite.kmr
-# application/vnd.motorola.flexsuite.ttc
-# application/vnd.motorola.flexsuite.wem
-# application/vnd.motorola.iprm
-application/vnd.mozilla.xul+xml xul
-application/vnd.ms-artgalry cil
-# application/vnd.ms-asf
-application/vnd.ms-cab-compressed cab
-application/vnd.ms-excel xls xlm xla xlc xlt xlw
-application/vnd.ms-excel.addin.macroenabled.12 xlam
-application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
-application/vnd.ms-excel.sheet.macroenabled.12 xlsm
-application/vnd.ms-excel.template.macroenabled.12 xltm
-application/vnd.ms-fontobject eot
-application/vnd.ms-htmlhelp chm
-application/vnd.ms-ims ims
-application/vnd.ms-lrm lrm
-application/vnd.ms-pki.seccat cat
-application/vnd.ms-pki.stl stl
-# application/vnd.ms-playready.initiator+xml
-application/vnd.ms-powerpoint ppt pps pot
-application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
-application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
-application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
-application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
-application/vnd.ms-powerpoint.template.macroenabled.12 potm
-application/vnd.ms-project mpp mpt
-# application/vnd.ms-tnef
-# application/vnd.ms-wmdrm.lic-chlg-req
-# application/vnd.ms-wmdrm.lic-resp
-# application/vnd.ms-wmdrm.meter-chlg-req
-# application/vnd.ms-wmdrm.meter-resp
-application/vnd.ms-word.document.macroenabled.12 docm
-application/vnd.ms-word.template.macroenabled.12 dotm
-application/vnd.ms-works wps wks wcm wdb
-application/vnd.ms-wpl wpl
-application/vnd.ms-xpsdocument xps
-application/vnd.mseq mseq
-# application/vnd.msign
-# application/vnd.multiad.creator
-# application/vnd.multiad.creator.cif
-# application/vnd.music-niff
-application/vnd.musician mus
-application/vnd.muvee.style msty
-# application/vnd.ncd.control
-# application/vnd.ncd.reference
-# application/vnd.nervana
-# application/vnd.netfpx
-application/vnd.neurolanguage.nlu nlu
-application/vnd.noblenet-directory nnd
-application/vnd.noblenet-sealer nns
-application/vnd.noblenet-web nnw
-# application/vnd.nokia.catalogs
-# application/vnd.nokia.conml+wbxml
-# application/vnd.nokia.conml+xml
-# application/vnd.nokia.isds-radio-presets
-# application/vnd.nokia.iptv.config+xml
-# application/vnd.nokia.landmark+wbxml
-# application/vnd.nokia.landmark+xml
-# application/vnd.nokia.landmarkcollection+xml
-# application/vnd.nokia.n-gage.ac+xml
-application/vnd.nokia.n-gage.data ngdat
-application/vnd.nokia.n-gage.symbian.install n-gage
-# application/vnd.nokia.ncd
-# application/vnd.nokia.pcd+wbxml
-# application/vnd.nokia.pcd+xml
-application/vnd.nokia.radio-preset rpst
-application/vnd.nokia.radio-presets rpss
-application/vnd.novadigm.edm edm
-application/vnd.novadigm.edx edx
-application/vnd.novadigm.ext ext
-# application/vnd.ntt-local.file-transfer
-application/vnd.oasis.opendocument.chart odc
-application/vnd.oasis.opendocument.chart-template otc
-application/vnd.oasis.opendocument.database odb
-application/vnd.oasis.opendocument.formula odf
-application/vnd.oasis.opendocument.formula-template odft
-application/vnd.oasis.opendocument.graphics odg
-application/vnd.oasis.opendocument.graphics-template otg
-application/vnd.oasis.opendocument.image odi
-application/vnd.oasis.opendocument.image-template oti
-application/vnd.oasis.opendocument.presentation odp
-application/vnd.oasis.opendocument.presentation-template otp
-application/vnd.oasis.opendocument.spreadsheet ods
-application/vnd.oasis.opendocument.spreadsheet-template ots
-application/vnd.oasis.opendocument.text odt
-application/vnd.oasis.opendocument.text-master otm
-application/vnd.oasis.opendocument.text-template ott
-application/vnd.oasis.opendocument.text-web oth
-# application/vnd.obn
-application/vnd.olpc-sugar xo
-# application/vnd.oma-scws-config
-# application/vnd.oma-scws-http-request
-# application/vnd.oma-scws-http-response
-# application/vnd.oma.bcast.associated-procedure-parameter+xml
-# application/vnd.oma.bcast.drm-trigger+xml
-# application/vnd.oma.bcast.imd+xml
-# application/vnd.oma.bcast.ltkm
-# application/vnd.oma.bcast.notification+xml
-# application/vnd.oma.bcast.provisioningtrigger
-# application/vnd.oma.bcast.sgboot
-# application/vnd.oma.bcast.sgdd+xml
-# application/vnd.oma.bcast.sgdu
-# application/vnd.oma.bcast.simple-symbol-container
-# application/vnd.oma.bcast.smartcard-trigger+xml
-# application/vnd.oma.bcast.sprov+xml
-# application/vnd.oma.bcast.stkm
-# application/vnd.oma.dcd
-# application/vnd.oma.dcdc
-application/vnd.oma.dd2+xml dd2
-# application/vnd.oma.drm.risd+xml
-# application/vnd.oma.group-usage-list+xml
-# application/vnd.oma.poc.detailed-progress-report+xml
-# application/vnd.oma.poc.final-report+xml
-# application/vnd.oma.poc.groups+xml
-# application/vnd.oma.poc.invocation-descriptor+xml
-# application/vnd.oma.poc.optimized-progress-report+xml
-# application/vnd.oma.push
-# application/vnd.oma.scidm.messages+xml
-# application/vnd.oma.xcap-directory+xml
-# application/vnd.omads-email+xml
-# application/vnd.omads-file+xml
-# application/vnd.omads-folder+xml
-# application/vnd.omaloc-supl-init
-application/vnd.openofficeorg.extension oxt
-# application/vnd.openxmlformats-officedocument.custom-properties+xml
-# application/vnd.openxmlformats-officedocument.customxmlproperties+xml
-# application/vnd.openxmlformats-officedocument.drawing+xml
-# application/vnd.openxmlformats-officedocument.drawingml.chart+xml
-# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml
-# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml
-# application/vnd.openxmlformats-officedocument.extended-properties+xml
-# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml
-# application/vnd.openxmlformats-officedocument.presentationml.comments+xml
-# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml
-# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml
-# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml
-application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
-# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml
-application/vnd.openxmlformats-officedocument.presentationml.slide sldx
-# application/vnd.openxmlformats-officedocument.presentationml.slide+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml
-application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
-# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml
-# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml
-# application/vnd.openxmlformats-officedocument.presentationml.tags+xml
-application/vnd.openxmlformats-officedocument.presentationml.template potx
-# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
-# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml
-application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml
-application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
-# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml
-# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
-# application/vnd.openxmlformats-officedocument.theme+xml
-# application/vnd.openxmlformats-officedocument.themeoverride+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
-application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
-# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
-application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
-# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
-# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml
-# application/vnd.openxmlformats-package.core-properties+xml
-# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
-# application/vnd.osa.netdeploy
-# application/vnd.osgi.bundle
-application/vnd.osgi.dp dp
-# application/vnd.otps.ct-kip+xml
-application/vnd.palm pdb pqa oprc
-# application/vnd.paos.xml
-application/vnd.pawaafile paw
-application/vnd.pg.format str
-application/vnd.pg.osasli ei6
-# application/vnd.piaccess.application-licence
-application/vnd.picsel efif
-application/vnd.pmi.widget wg
-# application/vnd.poc.group-advertisement+xml
-application/vnd.pocketlearn plf
-application/vnd.powerbuilder6 pbd
-# application/vnd.powerbuilder6-s
-# application/vnd.powerbuilder7
-# application/vnd.powerbuilder7-s
-# application/vnd.powerbuilder75
-# application/vnd.powerbuilder75-s
-# application/vnd.preminet
-application/vnd.previewsystems.box box
-application/vnd.proteus.magazine mgz
-application/vnd.publishare-delta-tree qps
-application/vnd.pvi.ptid1 ptid
-# application/vnd.pwg-multiplexed
-# application/vnd.pwg-xhtml-print+xml
-# application/vnd.qualcomm.brew-app-res
-application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
-# application/vnd.radisys.moml+xml
-# application/vnd.radisys.msml+xml
-# application/vnd.radisys.msml-audit+xml
-# application/vnd.radisys.msml-audit-conf+xml
-# application/vnd.radisys.msml-audit-conn+xml
-# application/vnd.radisys.msml-audit-dialog+xml
-# application/vnd.radisys.msml-audit-stream+xml
-# application/vnd.radisys.msml-conf+xml
-# application/vnd.radisys.msml-dialog+xml
-# application/vnd.radisys.msml-dialog-base+xml
-# application/vnd.radisys.msml-dialog-fax-detect+xml
-# application/vnd.radisys.msml-dialog-fax-sendrecv+xml
-# application/vnd.radisys.msml-dialog-group+xml
-# application/vnd.radisys.msml-dialog-speech+xml
-# application/vnd.radisys.msml-dialog-transform+xml
-# application/vnd.rapid
-application/vnd.realvnc.bed bed
-application/vnd.recordare.musicxml mxl
-application/vnd.recordare.musicxml+xml musicxml
-# application/vnd.renlearn.rlprint
-application/vnd.rim.cod cod
-application/vnd.rn-realmedia rm
-application/vnd.route66.link66+xml link66
-# application/vnd.ruckus.download
-# application/vnd.s3sms
-application/vnd.sailingtracker.track st
-# application/vnd.sbm.cid
-# application/vnd.sbm.mid2
-# application/vnd.scribus
-# application/vnd.sealed.3df
-# application/vnd.sealed.csf
-# application/vnd.sealed.doc
-# application/vnd.sealed.eml
-# application/vnd.sealed.mht
-# application/vnd.sealed.net
-# application/vnd.sealed.ppt
-# application/vnd.sealed.tiff
-# application/vnd.sealed.xls
-# application/vnd.sealedmedia.softseal.html
-# application/vnd.sealedmedia.softseal.pdf
-application/vnd.seemail see
-application/vnd.sema sema
-application/vnd.semd semd
-application/vnd.semf semf
-application/vnd.shana.informed.formdata ifm
-application/vnd.shana.informed.formtemplate itp
-application/vnd.shana.informed.interchange iif
-application/vnd.shana.informed.package ipk
-application/vnd.simtech-mindmapper twd twds
-application/vnd.smaf mmf
-# application/vnd.smart.notebook
-application/vnd.smart.teacher teacher
-# application/vnd.software602.filler.form+xml
-# application/vnd.software602.filler.form-xml-zip
-application/vnd.solent.sdkm+xml sdkm sdkd
-application/vnd.spotfire.dxp dxp
-application/vnd.spotfire.sfs sfs
-# application/vnd.sss-cod
-# application/vnd.sss-dtf
-# application/vnd.sss-ntf
-application/vnd.stardivision.calc sdc
-application/vnd.stardivision.draw sda
-application/vnd.stardivision.impress sdd
-application/vnd.stardivision.math smf
-application/vnd.stardivision.writer sdw
-application/vnd.stardivision.writer vor
-application/vnd.stardivision.writer-global sgl
-# application/vnd.street-stream
-application/vnd.sun.xml.calc sxc
-application/vnd.sun.xml.calc.template stc
-application/vnd.sun.xml.draw sxd
-application/vnd.sun.xml.draw.template std
-application/vnd.sun.xml.impress sxi
-application/vnd.sun.xml.impress.template sti
-application/vnd.sun.xml.math sxm
-application/vnd.sun.xml.writer sxw
-application/vnd.sun.xml.writer.global sxg
-application/vnd.sun.xml.writer.template stw
-# application/vnd.sun.wadl+xml
-application/vnd.sus-calendar sus susp
-application/vnd.svd svd
-# application/vnd.swiftview-ics
-application/vnd.symbian.install sis sisx
-application/vnd.syncml+xml xsm
-application/vnd.syncml.dm+wbxml bdm
-application/vnd.syncml.dm+xml xdm
-# application/vnd.syncml.dm.notification
-# application/vnd.syncml.ds.notification
-application/vnd.tao.intent-module-archive tao
-application/vnd.tmobile-livetv tmo
-application/vnd.trid.tpt tpt
-application/vnd.triscape.mxs mxs
-application/vnd.trueapp tra
-# application/vnd.truedoc
-application/vnd.ufdl ufd ufdl
-application/vnd.uiq.theme utz
-application/vnd.umajin umj
-application/vnd.unity unityweb
-application/vnd.uoml+xml uoml
-# application/vnd.uplanet.alert
-# application/vnd.uplanet.alert-wbxml
-# application/vnd.uplanet.bearer-choice
-# application/vnd.uplanet.bearer-choice-wbxml
-# application/vnd.uplanet.cacheop
-# application/vnd.uplanet.cacheop-wbxml
-# application/vnd.uplanet.channel
-# application/vnd.uplanet.channel-wbxml
-# application/vnd.uplanet.list
-# application/vnd.uplanet.list-wbxml
-# application/vnd.uplanet.listcmd
-# application/vnd.uplanet.listcmd-wbxml
-# application/vnd.uplanet.signal
-application/vnd.vcx vcx
-# application/vnd.vd-study
-# application/vnd.vectorworks
-# application/vnd.vidsoft.vidconference
-application/vnd.visio vsd vst vss vsw
-application/vnd.visionary vis
-# application/vnd.vividence.scriptfile
-application/vnd.vsf vsf
-# application/vnd.wap.sic
-# application/vnd.wap.slc
-application/vnd.wap.wbxml wbxml
-application/vnd.wap.wmlc wmlc
-application/vnd.wap.wmlscriptc wmlsc
-application/vnd.webturbo wtb
-# application/vnd.wfa.wsc
-# application/vnd.wmc
-# application/vnd.wmf.bootstrap
-# application/vnd.wolfram.mathematica
-# application/vnd.wolfram.mathematica.package
-application/vnd.wolfram.player nbp
-application/vnd.wordperfect wpd
-application/vnd.wqd wqd
-# application/vnd.wrq-hp3000-labelled
-application/vnd.wt.stf stf
-# application/vnd.wv.csp+wbxml
-# application/vnd.wv.csp+xml
-# application/vnd.wv.ssp+xml
-application/vnd.xara xar
-application/vnd.xfdl xfdl
-# application/vnd.xfdl.webform
-# application/vnd.xmi+xml
-# application/vnd.xmpie.cpkg
-# application/vnd.xmpie.dpkg
-# application/vnd.xmpie.plan
-# application/vnd.xmpie.ppkg
-# application/vnd.xmpie.xlim
-application/vnd.yamaha.hv-dic hvd
-application/vnd.yamaha.hv-script hvs
-application/vnd.yamaha.hv-voice hvp
-application/vnd.yamaha.openscoreformat osf
-application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
-application/vnd.yamaha.smaf-audio saf
-application/vnd.yamaha.smaf-phrase spf
-application/vnd.yellowriver-custom-menu cmp
-application/vnd.zul zir zirz
-application/vnd.zzazz.deck+xml zaz
-application/voicexml+xml vxml
-# application/watcherinfo+xml
-# application/whoispp-query
-# application/whoispp-response
-application/winhlp hlp
-# application/wita
-# application/wordperfect5.1
-application/wsdl+xml wsdl
-application/wspolicy+xml wspolicy
-application/x-abiword abw
-application/x-ace-compressed ace
-application/x-authorware-bin aab x32 u32 vox
-application/x-authorware-map aam
-application/x-authorware-seg aas
-application/x-bcpio bcpio
-application/x-bittorrent torrent
-application/x-bzip bz
-application/x-bzip2 bz2 boz
-application/x-cdlink vcd
-application/x-chat chat
-application/x-chess-pgn pgn
-# application/x-compress
-application/x-cpio cpio
-application/x-csh csh
-application/x-debian-package deb udeb
-application/x-director dir dcr dxr cst cct cxt w3d fgd swa
-application/x-doom wad
-application/x-dtbncx+xml ncx
-application/x-dtbook+xml dtb
-application/x-dtbresource+xml res
-application/x-dvi dvi
-application/x-font-bdf bdf
-# application/x-font-dos
-# application/x-font-framemaker
-application/x-font-ghostscript gsf
-# application/x-font-libgrx
-application/x-font-linux-psf psf
-application/x-font-otf otf
-application/x-font-pcf pcf
-application/x-font-snf snf
-# application/x-font-speedo
-# application/x-font-sunos-news
-application/x-font-ttf ttf ttc
-application/x-font-type1 pfa pfb pfm afm
-# application/x-font-vfont
-application/x-futuresplash spl
-application/x-gnumeric gnumeric
-application/x-gtar gtar
-# application/x-gzip
-application/x-hdf hdf
-application/x-java-jnlp-file jnlp
-application/x-latex latex
-application/x-mobipocket-ebook prc mobi
-application/x-ms-application application
-application/x-ms-wmd wmd
-application/x-ms-wmz wmz
-application/x-ms-xbap xbap
-application/x-msaccess mdb
-application/x-msbinder obd
-application/x-mscardfile crd
-application/x-msclip clp
-application/x-msdownload exe dll com bat msi
-application/x-msmediaview mvb m13 m14
-application/x-msmetafile wmf
-application/x-msmoney mny
-application/x-mspublisher pub
-application/x-msschedule scd
-application/x-msterminal trm
-application/x-mswrite wri
-application/x-netcdf nc cdf
-application/x-pkcs12 p12 pfx
-application/x-pkcs7-certificates p7b spc
-application/x-pkcs7-certreqresp p7r
-application/x-rar-compressed rar
-application/x-sh sh
-application/x-shar shar
-application/x-shockwave-flash swf
-application/x-silverlight-app xap
-application/x-stuffit sit
-application/x-stuffitx sitx
-application/x-sv4cpio sv4cpio
-application/x-sv4crc sv4crc
-application/x-tar tar
-application/x-tcl tcl
-application/x-tex tex
-application/x-tex-tfm tfm
-application/x-texinfo texinfo texi
-application/x-ustar ustar
-application/x-wais-source src
-application/x-x509-ca-cert der crt
-application/x-xfig fig
-application/x-xpinstall xpi
-# application/x400-bp
-# application/xcap-att+xml
-# application/xcap-caps+xml
-# application/xcap-el+xml
-# application/xcap-error+xml
-# application/xcap-ns+xml
-# application/xcon-conference-info-diff+xml
-# application/xcon-conference-info+xml
-application/xenc+xml xenc
-application/xhtml+xml xhtml xht
-# application/xhtml-voice+xml
-application/xml xml xsl
-application/xml-dtd dtd
-# application/xml-external-parsed-entity
-# application/xmpp+xml
-application/xop+xml xop
-application/xslt+xml xslt
-application/xspf+xml xspf
-application/xv+xml mxml xhvml xvml xvm
-application/zip zip
-# audio/32kadpcm
-# audio/3gpp
-# audio/3gpp2
-# audio/ac3
-audio/adpcm adp
-# audio/amr
-# audio/amr-wb
-# audio/amr-wb+
-# audio/asc
-# audio/atrac-advanced-lossless
-# audio/atrac-x
-# audio/atrac3
-audio/basic au snd
-# audio/bv16
-# audio/bv32
-# audio/clearmode
-# audio/cn
-# audio/dat12
-# audio/dls
-# audio/dsr-es201108
-# audio/dsr-es202050
-# audio/dsr-es202211
-# audio/dsr-es202212
-# audio/dvi4
-# audio/eac3
-# audio/evrc
-# audio/evrc-qcp
-# audio/evrc0
-# audio/evrc1
-# audio/evrcb
-# audio/evrcb0
-# audio/evrcb1
-# audio/evrcwb
-# audio/evrcwb0
-# audio/evrcwb1
-# audio/example
-# audio/g719
-# audio/g722
-# audio/g7221
-# audio/g723
-# audio/g726-16
-# audio/g726-24
-# audio/g726-32
-# audio/g726-40
-# audio/g728
-# audio/g729
-# audio/g7291
-# audio/g729d
-# audio/g729e
-# audio/gsm
-# audio/gsm-efr
-# audio/ilbc
-# audio/l16
-# audio/l20
-# audio/l24
-# audio/l8
-# audio/lpc
-audio/midi mid midi kar rmi
-# audio/mobile-xmf
-audio/mp4 mp4a
-# audio/mp4a-latm
-# audio/mpa
-# audio/mpa-robust
-audio/mpeg mpga mp2 mp2a mp3 m2a m3a
-# audio/mpeg4-generic
-audio/ogg oga ogg spx
-# audio/parityfec
-# audio/pcma
-# audio/pcma-wb
-# audio/pcmu-wb
-# audio/pcmu
-# audio/prs.sid
-# audio/qcelp
-# audio/red
-# audio/rtp-enc-aescm128
-# audio/rtp-midi
-# audio/rtx
-# audio/smv
-# audio/smv0
-# audio/smv-qcp
-# audio/sp-midi
-# audio/speex
-# audio/t140c
-# audio/t38
-# audio/telephone-event
-# audio/tone
-# audio/uemclip
-# audio/ulpfec
-# audio/vdvi
-# audio/vmr-wb
-# audio/vnd.3gpp.iufp
-# audio/vnd.4sb
-# audio/vnd.audiokoz
-# audio/vnd.celp
-# audio/vnd.cisco.nse
-# audio/vnd.cmles.radio-events
-# audio/vnd.cns.anp1
-# audio/vnd.cns.inf1
-audio/vnd.digital-winds eol
-# audio/vnd.dlna.adts
-# audio/vnd.dolby.heaac.1
-# audio/vnd.dolby.heaac.2
-# audio/vnd.dolby.mlp
-# audio/vnd.dolby.mps
-# audio/vnd.dolby.pl2
-# audio/vnd.dolby.pl2x
-# audio/vnd.dolby.pl2z
-# audio/vnd.dolby.pulse.1
-audio/vnd.dra dra
-audio/vnd.dts dts
-audio/vnd.dts.hd dtshd
-# audio/vnd.everad.plj
-# audio/vnd.hns.audio
-audio/vnd.lucent.voice lvp
-audio/vnd.ms-playready.media.pya pya
-# audio/vnd.nokia.mobile-xmf
-# audio/vnd.nortel.vbk
-audio/vnd.nuera.ecelp4800 ecelp4800
-audio/vnd.nuera.ecelp7470 ecelp7470
-audio/vnd.nuera.ecelp9600 ecelp9600
-# audio/vnd.octel.sbc
-# audio/vnd.qcelp
-# audio/vnd.rhetorex.32kadpcm
-# audio/vnd.sealedmedia.softseal.mpeg
-# audio/vnd.vmx.cvsd
-# audio/vorbis
-# audio/vorbis-config
-audio/x-aac aac
-audio/x-aiff aif aiff aifc
-audio/x-mpegurl m3u
-audio/x-ms-wax wax
-audio/x-ms-wma wma
-audio/x-pn-realaudio ram ra
-audio/x-pn-realaudio-plugin rmp
-audio/x-wav wav
-chemical/x-cdx cdx
-chemical/x-cif cif
-chemical/x-cmdf cmdf
-chemical/x-cml cml
-chemical/x-csml csml
-# chemical/x-pdb
-chemical/x-xyz xyz
-image/bmp bmp
-image/cgm cgm
-# image/example
-# image/fits
-image/g3fax g3
-image/gif gif
-image/ief ief
-# image/jp2
-image/jpeg jpeg jpg jpe
-# image/jpm
-# image/jpx
-# image/naplps
-image/png png
-image/prs.btif btif
-# image/prs.pti
-image/svg+xml svg svgz
-# image/t38
-image/tiff tiff tif
-# image/tiff-fx
-image/vnd.adobe.photoshop psd
-# image/vnd.cns.inf2
-image/vnd.djvu djvu djv
-image/vnd.dwg dwg
-image/vnd.dxf dxf
-image/vnd.fastbidsheet fbs
-image/vnd.fpx fpx
-image/vnd.fst fst
-image/vnd.fujixerox.edmics-mmr mmr
-image/vnd.fujixerox.edmics-rlc rlc
-# image/vnd.globalgraphics.pgb
-# image/vnd.microsoft.icon
-# image/vnd.mix
-image/vnd.ms-modi mdi
-image/vnd.net-fpx npx
-# image/vnd.radiance
-# image/vnd.sealed.png
-# image/vnd.sealedmedia.softseal.gif
-# image/vnd.sealedmedia.softseal.jpg
-# image/vnd.svf
-image/vnd.wap.wbmp wbmp
-image/vnd.xiff xif
-image/x-cmu-raster ras
-image/x-cmx cmx
-image/x-freehand fh fhc fh4 fh5 fh7
-image/x-icon ico
-image/x-pcx pcx
-image/x-pict pic pct
-image/x-portable-anymap pnm
-image/x-portable-bitmap pbm
-image/x-portable-graymap pgm
-image/x-portable-pixmap ppm
-image/x-rgb rgb
-image/x-xbitmap xbm
-image/x-xpixmap xpm
-image/x-xwindowdump xwd
-# message/cpim
-# message/delivery-status
-# message/disposition-notification
-# message/example
-# message/external-body
-# message/global
-# message/global-delivery-status
-# message/global-disposition-notification
-# message/global-headers
-# message/http
-# message/imdn+xml
-# message/news
-# message/partial
-message/rfc822 eml mime
-# message/s-http
-# message/sip
-# message/sipfrag
-# message/tracking-status
-# message/vnd.si.simp
-# model/example
-model/iges igs iges
-model/mesh msh mesh silo
-model/vnd.dwf dwf
-# model/vnd.flatland.3dml
-model/vnd.gdl gdl
-# model/vnd.gs-gdl
-# model/vnd.gs.gdl
-model/vnd.gtw gtw
-# model/vnd.moml+xml
-model/vnd.mts mts
-# model/vnd.parasolid.transmit.binary
-# model/vnd.parasolid.transmit.text
-model/vnd.vtu vtu
-model/vrml wrl vrml
-# multipart/alternative
-# multipart/appledouble
-# multipart/byteranges
-# multipart/digest
-# multipart/encrypted
-# multipart/example
-# multipart/form-data
-# multipart/header-set
-# multipart/mixed
-# multipart/parallel
-# multipart/related
-# multipart/report
-# multipart/signed
-# multipart/voice-message
-text/calendar ics ifb
-text/css css
-text/csv csv
-# text/directory
-# text/dns
-# text/ecmascript
-# text/enriched
-# text/example
-text/html html htm
-# text/javascript
-# text/parityfec
-text/plain txt text conf def list log in
-# text/prs.fallenstein.rst
-text/prs.lines.tag dsc
-# text/vnd.radisys.msml-basic-layout
-# text/red
-# text/rfc822-headers
-text/richtext rtx
-# text/rtf
-# text/rtp-enc-aescm128
-# text/rtx
-text/sgml sgml sgm
-# text/t140
-text/tab-separated-values tsv
-text/troff t tr roff man me ms
-# text/ulpfec
-text/uri-list uri uris urls
-# text/vnd.abc
-text/vnd.curl curl
-text/vnd.curl.dcurl dcurl
-text/vnd.curl.scurl scurl
-text/vnd.curl.mcurl mcurl
-# text/vnd.dmclientscript
-# text/vnd.esmertec.theme-descriptor
-text/vnd.fly fly
-text/vnd.fmi.flexstor flx
-text/vnd.graphviz gv
-text/vnd.in3d.3dml 3dml
-text/vnd.in3d.spot spot
-# text/vnd.iptc.newsml
-# text/vnd.iptc.nitf
-# text/vnd.latex-z
-# text/vnd.motorola.reflex
-# text/vnd.ms-mediapackage
-# text/vnd.net2phone.commcenter.command
-# text/vnd.si.uricatalogue
-text/vnd.sun.j2me.app-descriptor jad
-# text/vnd.trolltech.linguist
-# text/vnd.wap.si
-# text/vnd.wap.sl
-text/vnd.wap.wml wml
-text/vnd.wap.wmlscript wmls
-text/x-asm s asm
-text/x-c c cc cxx cpp h hh dic
-text/x-fortran f for f77 f90
-text/x-pascal p pas
-text/x-java-source java
-text/x-setext etx
-text/x-uuencode uu
-text/x-vcalendar vcs
-text/x-vcard vcf
-# text/xml
-# text/xml-external-parsed-entity
-video/3gpp 3gp
-# video/3gpp-tt
-video/3gpp2 3g2
-# video/bmpeg
-# video/bt656
-# video/celb
-# video/dv
-# video/example
-video/h261 h261
-video/h263 h263
-# video/h263-1998
-# video/h263-2000
-video/h264 h264
-video/jpeg jpgv
-# video/jpeg2000
-video/jpm jpm jpgm
-video/mj2 mj2 mjp2
-# video/mp1s
-# video/mp2p
-# video/mp2t
-video/mp4 mp4 mp4v mpg4
-# video/mp4v-es
-video/mpeg mpeg mpg mpe m1v m2v
-# video/mpeg4-generic
-# video/mpv
-# video/nv
-video/ogg ogv
-# video/parityfec
-# video/pointer
-video/quicktime qt mov
-# video/raw
-# video/rtp-enc-aescm128
-# video/rtx
-# video/smpte292m
-# video/ulpfec
-# video/vc1
-# video/vnd.cctv
-# video/vnd.dlna.mpeg-tts
-video/vnd.fvt fvt
-# video/vnd.hns.video
-# video/vnd.iptvforum.1dparityfec-1010
-# video/vnd.iptvforum.1dparityfec-2005
-# video/vnd.iptvforum.2dparityfec-1010
-# video/vnd.iptvforum.2dparityfec-2005
-# video/vnd.iptvforum.ttsavc
-# video/vnd.iptvforum.ttsmpeg2
-# video/vnd.motorola.video
-# video/vnd.motorola.videop
-video/vnd.mpegurl mxu m4u
-video/vnd.ms-playready.media.pyv pyv
-# video/vnd.nokia.interleaved-multimedia
-# video/vnd.nokia.videovoip
-# video/vnd.objectvideo
-# video/vnd.sealed.mpeg1
-# video/vnd.sealed.mpeg4
-# video/vnd.sealed.swf
-# video/vnd.sealedmedia.softseal.mov
-video/vnd.vivo viv
-video/x-f4v f4v
-video/x-fli fli
-video/x-flv flv
-video/x-m4v m4v
-video/x-ms-asf asf asx
-video/x-ms-wm wm
-video/x-ms-wmv wmv
-video/x-ms-wmx wmx
-video/x-ms-wvx wvx
-video/x-msvideo avi
-video/x-sgi-movie movie
-x-conference/x-cooltalk ice
+ text/html html htm shtml
+ text/css css
+ text/xml xml
+ image/gif gif
+ image/jpeg jpeg jpg
+ application/javascript js
+ application/atom+xml atom
+ application/rss+xml rss
-application/x-chrome-extension crx \ No newline at end of file
+ text/mathml mml
+ text/plain txt
+ text/vnd.sun.j2me.app-descriptor jad
+ text/vnd.wap.wml wml
+ text/x-component htc
+
+ image/png png
+ image/tiff tif tiff
+ image/vnd.wap.wbmp wbmp
+ image/x-icon ico
+ image/x-jng jng
+ image/x-ms-bmp bmp
+ image/svg+xml svg svgz
+ image/webp webp
+
+ application/font-woff woff
+ application/java-archive jar war ear
+ application/json json
+ application/mac-binhex40 hqx
+ application/msword doc
+ application/pdf pdf
+ application/postscript ps eps ai
+ application/rtf rtf
+ application/vnd.apple.mpegurl m3u8
+ application/vnd.ms-excel xls
+ application/vnd.ms-fontobject eot
+ application/vnd.ms-powerpoint ppt
+ application/vnd.wap.wmlc wmlc
+ application/vnd.google-earth.kml+xml kml
+ application/vnd.google-earth.kmz kmz
+ application/x-7z-compressed 7z
+ application/x-cocoa cco
+ application/x-java-archive-diff jardiff
+ application/x-java-jnlp-file jnlp
+ application/x-makeself run
+ application/x-perl pl pm
+ application/x-pilot prc pdb
+ application/x-rar-compressed rar
+ application/x-redhat-package-manager rpm
+ application/x-sea sea
+ application/x-shockwave-flash swf
+ application/x-stuffit sit
+ application/x-tcl tcl tk
+ application/x-x509-ca-cert der pem crt
+ application/x-xpinstall xpi
+ application/xhtml+xml xhtml
+ application/xspf+xml xspf
+ application/zip zip
+
+ application/octet-stream bin exe dll
+ application/octet-stream deb
+ application/octet-stream dmg
+ application/octet-stream iso img
+ application/octet-stream msi msp msm
+
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+ application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+
+ audio/midi mid midi kar
+ audio/mpeg mp3
+ audio/ogg ogg
+ audio/x-m4a m4a
+ audio/x-realaudio ra
+
+ video/3gpp 3gpp 3gp
+ video/mp2t ts
+ video/mp4 mp4
+ video/mpeg mpeg mpg
+ video/quicktime mov
+ video/webm webm
+ video/x-flv flv
+ video/x-m4v m4v
+ video/x-mng mng
+ video/x-ms-asf asx asf
+ video/x-ms-wmv wmv
+ video/x-msvideo avi
+
+application/x-chrome-extension crx
+application/dart dart \ No newline at end of file
diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt
index 41a8b4f17299..d5678fdd8977 100644
--- a/platform/platform-resources/src/brokenPlugins.txt
+++ b/platform/platform-resources/src/brokenPlugins.txt
@@ -2,16 +2,17 @@
// Each line contains plugin ID and list of versions that are broken.
// If plugin name or version contains a space you can quote it like in command line.
-NodeJS 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
-com.jetbrains.php 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
+NodeJS 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
+com.jetbrains.php 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
com.jetbrains.lang.ejs 131.17 131.12
com.jetbrains.twig 133.51 130.1639
-org.jetbrains.plugins.ruby 6.0.0.20140207
+org.jetbrains.plugins.ruby 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704
Pythonid 3.1
Karma 138.21 134.1163 134.1039 134.686 134.31
org.intellij.scala 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
org.jetbrains.kannotator 0.2.420
+org.jetbrains.kotlin 0.7.1360 0.7.1376 0.8.7
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
"JSTestDriver Plugin" 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
AngularJS 134.1094 0.1.8 0.1.9
-org.jetbrains.plugins.vagrant 0.1 \ No newline at end of file
+org.jetbrains.plugins.vagrant 0.1 0.2 \ No newline at end of file
diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml
index e0b733d74bdf..0e2e60d64fd7 100644
--- a/platform/platform-resources/src/componentSets/Platform.xml
+++ b/platform/platform-resources/src/componentSets/Platform.xml
@@ -134,10 +134,6 @@
</component>
<component>
- <implementation-class>com.intellij.util.net.ssl.CertificateManager</implementation-class>
- </component>
-
- <component>
<implementation-class>com.intellij.ide.SystemHealthMonitor</implementation-class>
<headless-implementation-class/>
</component>
diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml
index d42b30b322ad..58d6f3a76d27 100644
--- a/platform/platform-resources/src/idea/Keymap_Default.xml
+++ b/platform/platform-resources/src/idea/Keymap_Default.xml
@@ -90,9 +90,6 @@
<action id="Generate">
<keyboard-shortcut first-keystroke="alt INSERT"/>
</action>
- <action id="CloneElement">
- <keyboard-shortcut first-keystroke="shift F5"/>
- </action>
<action id="EditorChooseLookupItemReplace">
<keyboard-shortcut first-keystroke="TAB"/>
</action>
@@ -899,6 +896,9 @@
<action id="FileChooser.GotoHome">
<keyboard-shortcut first-keystroke="control 1"/>
</action>
+ <action id="FileChooser.GotoDesktop">
+ <keyboard-shortcut first-keystroke="control D"/>
+ </action>
<action id="FileChooser.GotoProject">
<keyboard-shortcut first-keystroke="control 2"/>
</action>
@@ -909,6 +909,7 @@
<keyboard-shortcut first-keystroke="alt INSERT"/>
<keyboard-shortcut first-keystroke="control N"/>
</action>
+
<action id="PopupHector">
<keyboard-shortcut first-keystroke="ctrl alt shift H"/>
</action>
diff --git a/platform/platform-resources/src/idea/Keymap_Netbeans.xml b/platform/platform-resources/src/idea/Keymap_Netbeans.xml
index a343ec152dfb..b38699989ca3 100644
--- a/platform/platform-resources/src/idea/Keymap_Netbeans.xml
+++ b/platform/platform-resources/src/idea/Keymap_Netbeans.xml
@@ -42,7 +42,6 @@
<keyboard-shortcut first-keystroke="control alt SPACE" />
<keyboard-shortcut first-keystroke="control alt BACK_SLASH" />
</action>
- <action id="CloneElement" />
<action id="CloseActiveTab" />
<action id="CloseAllEditors">
<keyboard-shortcut first-keystroke="shift control W" />
diff --git a/platform/platform-resources/src/idea/Keymap_VisualStudio.xml b/platform/platform-resources/src/idea/Keymap_VisualStudio.xml
index 7df5974cb7e8..ec5620e51383 100644
--- a/platform/platform-resources/src/idea/Keymap_VisualStudio.xml
+++ b/platform/platform-resources/src/idea/Keymap_VisualStudio.xml
@@ -205,6 +205,5 @@
<keyboard-shortcut first-keystroke="shift control alt UP"/>
</action>
<action id="CopyElement"/>
- <action id="CloneElement"/>
</keymap>
</component>
diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml
index af636ab5a3cf..65fa309fe3b9 100644
--- a/platform/platform-resources/src/idea/LangActions.xml
+++ b/platform/platform-resources/src/idea/LangActions.xml
@@ -120,7 +120,7 @@
<action id="GotoTypeDeclaration" class="com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction"/>
<action id="GotoSuperMethod" class="com.intellij.codeInsight.navigation.actions.GotoSuperAction"/>
<action id="GotoTest" class="com.intellij.testIntegration.GotoTestOrCodeAction"/>
- <action id="GotoRelated" class="com.intellij.ide.actions.GotoRelatedFileAction"/>
+ <action id="GotoRelated" class="com.intellij.ide.actions.GotoRelatedSymbolAction"/>
<separator/>
<action id="FileStructurePopup" class="com.intellij.ide.actions.ViewStructureAction"/>
<action id="ShowFilePath" class="com.intellij.ide.actions.ShowFilePathAction"/>
@@ -269,7 +269,6 @@
<separator/>
<action id="Move" class="com.intellij.refactoring.actions.MoveAction"/>
<action id="CopyElement" class="com.intellij.ide.actions.CopyElementAction"/>
- <action id="CloneElement" class="com.intellij.ide.actions.CloneElementAction"/>
<action id="SafeDelete" class="com.intellij.refactoring.actions.SafeDeleteAction"/>
<separator/>
<group id="IntroduceActionsGroup" popup="true">
@@ -638,6 +637,7 @@
<separator/>
<action id="ToggleLineBreakpoint" class="com.intellij.xdebugger.impl.actions.ToggleLineBreakpointAction"/>
<action id="ToggleTemporaryLineBreakpoint" class="com.intellij.xdebugger.impl.actions.ToggleTemporaryLineBreakpointAction"/>
+ <action id="ToggleBreakpointEnabled" class="com.intellij.xdebugger.impl.actions.ToggleBreakpointEnabledAction"/>
<action id="ViewBreakpoints" class="com.intellij.xdebugger.impl.actions.ViewBreakpointsAction" icon="AllIcons.Debugger.ViewBreakpoints"/>
<separator/>
@@ -681,6 +681,7 @@
<action id="XDebugger.AutoTooltip" class="com.intellij.xdebugger.impl.actions.ValueTooltipAutoShowAction"/>
<action id="XDebugger.ToggleSortValues" class="com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction" icon="AllIcons.ObjectBrowser.Sorted"/>
<action id="Debugger.MarkObject" class="com.intellij.xdebugger.impl.actions.MarkObjectAction"/>
+ <action id="Debugger.FocusOnBreakpoint" class="com.intellij.xdebugger.impl.actions.FocusOnBreakpointAction"/>
</group>
<group id="XDebugger.ToolWindow.TopToolbar">
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 85a834d97b37..9cebd282ded6 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -27,7 +27,7 @@
<action id="ContextHelp" class="com.intellij.ide.actions.ContextHelpAction"/>
<action id="RunGc" class="com.intellij.ide.actions.RunGcAction"/>
<action id="ShowPopupMenu" class="com.intellij.ide.actions.ShowPopupMenuAction"/>
- <action id="ShowColorPicker" class="com.intellij.ui.ShowColorPickerAction" text="Show Color Picker"/>
+ <action id="ShowColorPicker" class="com.intellij.ui.ShowColorPickerAction" text="Show Color Picker" icon="AllIcons.Ide.Pipette"/>
<action id="NextEditorTab" class="com.intellij.openapi.fileEditor.impl.SelectNextEditorTabAction"/>
<action id="PreviousEditorTab" class="com.intellij.openapi.fileEditor.impl.SelectPreviousEditorTabAction"/>
@@ -543,6 +543,8 @@
<group id="FileChooserToolbar">
<action id="FileChooser.GotoHome" class="com.intellij.openapi.fileChooser.actions.GotoHomeAction"
icon="AllIcons.Nodes.HomeFolder"/>
+ <action id="FileChooser.GotoDesktop" class="com.intellij.openapi.fileChooser.actions.GotoDesktopDirAction"
+ icon="AllIcons.Nodes.Desktop"/>
<action id="FileChooser.GotoProject" class="com.intellij.openapi.fileChooser.actions.GotoProjectDirectory"
icon="AllIcons.Nodes.IdeaProject"/>
<separator/>
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteLine-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteLine-after.txt
index c3981854ab58..dd90399d5874 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteLine-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteLine-after.txt
@@ -1,2 +1,3 @@
-<caret>blah
-<caret>blah \ No newline at end of file
+blah<caret>
+yet <caret>an<caret>other <caret>line
+blah \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt
index 0e8f561530eb..a9d628d0c856 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt
@@ -1,2 +1,3 @@
-s<caret>text<caret>o<caret>r text
-an<caret>er l<caret>yet a<caret>her line \ No newline at end of file
+s<caret> text<caret>o<caret>r text
+an<caret>er l<caret>
+yet a<caret>her line \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt
index 1b3f82a9edf6..c48a5ad7f48a 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt
@@ -1,2 +1,2 @@
-Ab<caret>Dabra<caret>Hum<caret>ump Hu<caret>mp
+Ab<caret>CaDabra<caret>Hum<caret>ump Hu<caret>mp
<caret> \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt
index b66dd51f46f7..37984912c5bc 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt
@@ -1,3 +1,3 @@
-<caret>some <caret>t
+<caret>t
o<caret>er t<caret>t
<caret> line<caret>yet another line \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt
index fb348125e7a7..6168f195986e 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt
@@ -1,6 +1,6 @@
some
<caret>te
- <caret>xt
+<caret>xt
other
<caret>
diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt
index 309b65c1e7d3..4a2968934c3c 100644
--- a/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt
+++ b/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt
@@ -1,2 +1,2 @@
-so <caret>me t <caret>t
+so <caret>me t <caret>t
<caret> <caret> text \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/richcopy/BlockSelection.html b/platform/platform-tests/testData/editor/richcopy/BlockSelection.html
index 6d79208d30e3..15929be92edb 100644
--- a/platform/platform-tests/testData/editor/richcopy/BlockSelection.html
+++ b/platform/platform-tests/testData/editor/richcopy/BlockSelection.html
@@ -1,3 +1 @@
-<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body><pre style="background-color:#ffffff;color:#000000;font-family:'___PLATFORM_SPECIFIC___';font-size:___PLATFORM_SPECIFIC___pt;"> <span style="color:#000080;font-weight:bold;">int </span>field;
-
- <span style="color:#000080;font-weight:bold;">public static void </span>main(String[] args) {</pre></body></html> \ No newline at end of file
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body><pre style="background-color:#ffffff;color:#000000;font-family:'___PLATFORM_SPECIFIC___';font-size:___PLATFORM_SPECIFIC___pt;">&#32;<span style="color:#000080;font-weight:bold;">int&#32;</span>field;<br><br>&#32;<span style="color:#000080;font-weight:bold;">public&#32;static&#32;void&#32;</span>main(String[]&#32;args)&#32;{</pre></body></html> \ No newline at end of file
diff --git a/platform/platform-tests/testData/editor/richcopy/NormalSelection.html b/platform/platform-tests/testData/editor/richcopy/NormalSelection.html
index 6c4f8dc96153..aa4e743e1600 100644
--- a/platform/platform-tests/testData/editor/richcopy/NormalSelection.html
+++ b/platform/platform-tests/testData/editor/richcopy/NormalSelection.html
@@ -1,8 +1 @@
-<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body><pre style="background-color:#ffffff;color:#000000;font-family:'___PLATFORM_SPECIFIC___';font-size:___PLATFORM_SPECIFIC___pt;"><span style="color:#000080;font-weight:bold;">public class </span>Basic {
- <span style="color:#000080;font-weight:bold;">int </span>field;
-
- <span style="color:#000080;font-weight:bold;">public static void </span>main(String[] args) {
- System.out.println(<span style="color:#008000;font-weight:bold;">"Hello</span><span style="color:#000080;font-weight:bold;">\t</span><span style="color:#008000;font-weight:bold;">world!"</span>);
- }
-}
-</pre></body></html> \ No newline at end of file
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body><pre style="background-color:#ffffff;color:#000000;font-family:'___PLATFORM_SPECIFIC___';font-size:___PLATFORM_SPECIFIC___pt;"><span style="color:#000080;font-weight:bold;">public&#32;class&#32;</span>Basic&#32;{<br>&#32;&#32;<span style="color:#000080;font-weight:bold;">int&#32;</span>field;<br><br>&#32;&#32;<span style="color:#000080;font-weight:bold;">public&#32;static&#32;void&#32;</span>main(String[]&#32;args)&#32;{<br>&#32;&#32;&#32;&#32;System.out.println(<span style="color:#008000;font-weight:bold;">"Hello</span><span style="color:#000080;font-weight:bold;">\t</span><span style="color:#008000;font-weight:bold;">world!"</span>);<br>&#32;&#32;}<br>}<br></pre></body></html> \ No newline at end of file
diff --git a/platform/platform-tests/testSrc/com/intellij/application/options/codeInsight/editor/quotes/SelectionQuotingTypedHandlerTest.java b/platform/platform-tests/testSrc/com/intellij/application/options/codeInsight/editor/quotes/SelectionQuotingTypedHandlerTest.java
index c023cae974b2..0092d115c8c1 100644
--- a/platform/platform-tests/testSrc/com/intellij/application/options/codeInsight/editor/quotes/SelectionQuotingTypedHandlerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/application/options/codeInsight/editor/quotes/SelectionQuotingTypedHandlerTest.java
@@ -108,7 +108,7 @@ public class SelectionQuotingTypedHandlerTest extends LightPlatformCodeInsightFi
public void testMultipleCarets() {
doTest("\"",
"aa<caret>a <selection><caret>bbb</selection> c<selection>c<caret>c</selection>",
- "aa<caret>a \"<selection><caret>bbb</selection>\" c\"<selection><caret>cc</selection>\"");
+ "aa\"<caret>a \"<selection><caret>bbb</selection>\" c\"<selection><caret>cc</selection>\"");
}
private void doTest(@NotNull final String cs, @NotNull String before, @NotNull String expected) {
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
index 98ded2cdf13a..a90148799f5d 100644
--- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
@@ -1,33 +1,23 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+
package com.intellij.codeInsight.actions;
import com.intellij.lang.LanguageFormatting;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.MutablePicoContainer;
import java.io.IOException;
+import java.util.Collection;
import java.util.Set;
import static com.intellij.psi.search.GlobalSearchScopesCore.directoryScope;
@@ -208,10 +198,50 @@ public class ReformatFilesWithFiltersTest extends LightPlatformTestCase {
assertWasNotFormatted(java2, php2, js1, js2, js3);
}
+ public void testIDEA126830() throws IOException {
+ TestFileStructure fileTree = new TestFileStructure(getModule(), myWorkingDirectory);
+
+ fileTree.createDirectoryAndMakeItCurrent("src");
+ PsiFile java2 = fileTree.addTestFile("Test2.java", "empty content");
+ PsiFile php2 = fileTree.addTestFile("Pair2.php", "empty content");
+ PsiFile js2 = fileTree.addTestFile("Pair2.js", "empty content");
+
+ PsiDirectory test = fileTree.createDirectoryAndMakeItCurrent("test");
+ PsiFile testJava1 = fileTree.addTestFile("testJava1.java", "empty content");
+ PsiFile testPhp1 = fileTree.addTestFile("testPhp1.php", "empty content");
+ PsiFile testJs1 = fileTree.addTestFile("testJs1.js", "empty content");
+
+ GlobalSearchScope testScope = directoryScope(test, true);
+
+ Logger logger = Logger.getInstance(getClass());
+ logFiles(logger, "Previously formatted files: ", myMockCodeStyleManager.getFormattedFiles());
+
+ reformatWithRearrange(myWorkingDirectory, testScope);
+ logFiles(logger, "Currently formatted files: ", myMockCodeStyleManager.getFormattedFiles());
+ logFiles(logger, "Should be formatted", ContainerUtil.newArrayList(testJava1, testPhp1, testJs1));
+
+ assertWasFormatted(testJava1, testPhp1, testJs1);
+ assertWasNotFormatted(java2, php2, js2);
+
+ reformatAndOptimize(myWorkingDirectory, testScope);
+ assertWasFormatted(testJava1, testPhp1, testJs1);
+ assertWasNotFormatted(java2, php2, js2);
+ }
+
+ private void logFiles(Logger log, String message, Collection<PsiFile> files) {
+ StringBuilder builder;
+ builder = new StringBuilder();
+ builder.append(message).append('\n');
+ for (PsiFile file : files) {
+ builder.append(file).append('\n');
+ }
+ log.info(builder.toString());
+ }
+
public void assertWasFormatted(PsiFile... files) {
final Set<PsiFile> formattedFiles = myMockCodeStyleManager.getFormattedFiles();
for (PsiFile file : files) {
- assertTrue(file.getName() + "should be formatted", formattedFiles.contains(file));
+ assertTrue(file.getName() + " should be formatted", formattedFiles.contains(file));
}
}
@@ -230,6 +260,24 @@ public class ReformatFilesWithFiltersTest extends LightPlatformTestCase {
reformatDirectory(directory, null, scope);
}
+ public void reformatWithRearrange(@NotNull PsiDirectory directory, @Nullable SearchScope scope) {
+ myMockCodeStyleManager.clearFormattedFiles();
+ AbstractLayoutCodeProcessor processor = new ReformatCodeProcessor(getProject(), directory, true, false);
+ ReformatCodeAction.registerScopeFilter(processor, scope);
+
+ processor = new RearrangeCodeProcessor(processor, null);
+ processor.run();
+ }
+
+ private void reformatAndOptimize(@NotNull PsiDirectory workingDirectory, @NotNull GlobalSearchScope scope) {
+ myMockCodeStyleManager.clearFormattedFiles();
+ AbstractLayoutCodeProcessor processor = new ReformatCodeProcessor(getProject(), workingDirectory, true, false);
+ ReformatCodeAction.registerScopeFilter(processor, scope);
+
+ processor = new OptimizeImportsProcessor(processor);
+ processor.run();
+ }
+
public void reformatDirectory(@NotNull PsiDirectory directory, @Nullable String mask, @Nullable SearchScope scope) {
myMockCodeStyleManager.clearFormattedFiles();
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/folding/impl/CompositeFoldingBuilderTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/folding/impl/CompositeFoldingBuilderTest.java
new file mode 100644
index 000000000000..000ab69e0335
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/folding/impl/CompositeFoldingBuilderTest.java
@@ -0,0 +1,91 @@
+
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.folding.impl;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.folding.*;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.impl.AbstractEditorTest;
+import com.intellij.openapi.fileTypes.PlainTextLanguage;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.TestFileType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+import static com.intellij.testFramework.PlatformTestCase.initPlatformLangPrefix;
+
+public class CompositeFoldingBuilderTest extends AbstractEditorTest {
+ static {
+ initPlatformLangPrefix();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ init("Some plain text to fold", TestFileType.TEXT);
+ }
+
+ public void testAllowOnlyOneDescriptorPerTextRange() {
+ final FoldingBuilder first = createDummyFoldingBuilder("plain", "mountain");
+ final FoldingBuilder second = createDummyFoldingBuilder("plain", "tree");
+
+ LanguageFolding.INSTANCE.addExplicitExtension(PlainTextLanguage.INSTANCE, first);
+ LanguageFolding.INSTANCE.addExplicitExtension(PlainTextLanguage.INSTANCE, second);
+
+ try {
+ FoldingUpdate.FoldingMap foldingMap = FoldingUpdate.getFoldingsFor(getProject(), getFile(), getEditor().getDocument(), false);
+ Collection<FoldingDescriptor> descriptors = foldingMap.get(getFile());
+
+ assert descriptors.size() == 1: "Only one descriptor allowed for the same text range. Descriptors: " + descriptors;
+ }
+ finally {
+ LanguageFolding.INSTANCE.removeExplicitExtension(PlainTextLanguage.INSTANCE, first);
+ LanguageFolding.INSTANCE.removeExplicitExtension(PlainTextLanguage.INSTANCE, second);
+ }
+ }
+
+ @NotNull
+ private FoldingBuilder createDummyFoldingBuilder(final String textToFold, final String placeholderText) {
+ return new CustomFoldingBuilder() {
+ @Override
+ protected void buildLanguageFoldRegions(
+ @NotNull List<FoldingDescriptor> descriptors,
+ @NotNull PsiElement root,
+ @NotNull Document document,
+ boolean quick)
+ {
+ final int index = root.getText().indexOf(textToFold);
+ descriptors.add(new NamedFoldingDescriptor(root, index, index + textToFold.length(), null, placeholderText));
+ }
+
+ @Override
+ protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) {
+ return "";
+ }
+
+ @Override
+ protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) {
+ return true;
+ }
+ };
+ }
+
+
+}
diff --git a/platform/platform-tests/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java b/platform/platform-tests/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java
index 6c0a9f10886b..ed3c995edf48 100644
--- a/platform/platform-tests/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/ide/bookmarks/BookmarkManagerTest.java
@@ -21,10 +21,12 @@ import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.testFramework.LeakHunter;
import com.intellij.testFramework.TestFileType;
import org.jetbrains.annotations.NonNls;
+import org.picocontainer.ComponentAdapter;
import java.io.IOException;
import java.util.ArrayList;
@@ -69,6 +71,12 @@ public class BookmarkManagerTest extends AbstractEditorTest {
}
public void testBookmarkLineRemove() throws IOException {
+ List<ComponentAdapter> adapters = getProject().getPicoContainer().getComponentAdaptersOfType(ChangeListManagerImpl.class);
+ System.out.println(adapters.size() + " adapters:");
+ for (ComponentAdapter adapter : adapters) {
+ System.out.println(adapter);
+ }
+
@NonNls String text =
"public class Test {\n" +
" public void test() {\n" +
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java
index 1c05f47b16ed..26be81d2f341 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretTest.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.TestFileType;
import java.awt.event.InputEvent;
@@ -305,4 +306,18 @@ public class EditorMultiCaretTest extends AbstractEditorTest {
"brown\n" +
"fox");
}
+
+ public void testCaretPositionsRecalculationOnDocumentChange() throws Exception {
+ init("\n" +
+ "<selection><caret>word</selection>\n" +
+ "some long prefix <selection><caret>word</selection>-suffix", TestFileType.TEXT);
+ EditorTestUtil.configureSoftWraps(myEditor, 17); // wrapping right before 'word-suffix'
+
+ delete();
+
+ checkResultByText("\n" +
+ "<caret>\n" +
+ "some long prefix <caret>-suffix");
+ verifySoftWrapPositions(19);
+ }
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java
index 63e040def381..deb63c13abf8 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java
@@ -20,6 +20,8 @@ import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.TestFileType;
+import java.io.IOException;
+
public class EditorActionTest extends AbstractEditorTest {
public void testDownWithSelectionWhenCaretsAreAllowedInsideTabs() throws Exception {
init("<caret>text",
@@ -69,4 +71,35 @@ public class EditorActionTest extends AbstractEditorTest {
executeAction("EditorTab");
checkResultByText("some <caret>text");
}
+
+ public void testLineDeleteWithSelectionEndAtLineStart() throws IOException {
+ String text =
+ "line 1\n" +
+ "<selection>line 2\n" +
+ "</selection>line 3";
+ init(text, TestFileType.TEXT);
+ deleteLine();
+ checkResultByText(
+ "line 1\n" +
+ "line 3"
+ );
+ }
+
+ public void testDeleteLastLine() throws IOException {
+ String text =
+ "1\n" +
+ "2<caret>\n" +
+ "3";
+ init(text, TestFileType.TEXT);
+
+ deleteLine();
+ deleteLine();
+ checkResultByText("1");
+ }
+
+ public void testDeleteLastNonEmptyLine() throws IOException {
+ init("<caret>1\n", TestFileType.TEXT);
+ deleteLine();
+ checkResultByText("");
+ }
} \ No newline at end of file
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java
index d8a740c49a7a..34a08c0483bb 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/SelectUnselectOccurrenceActionsTest.java
@@ -59,8 +59,8 @@ public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsigh
"another text here");
executeSelectAllAction();
checkResult("some <selection>t<caret>ext</selection>\n" +
- "some texts\n" +
- "some texts\n" +
+ "some <selection>t<caret>ext</selection>s\n" +
+ "some <selection>t<caret>ext</selection>s\n" +
"another <selection>t<caret>ext</selection> here");
assertEquals(0, hintCount);
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/richcopy/SyntaxInfoConstructionTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/richcopy/SyntaxInfoConstructionTest.java
index 1712fd8c93e8..b7811e0ae40d 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/richcopy/SyntaxInfoConstructionTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/richcopy/SyntaxInfoConstructionTest.java
@@ -301,7 +301,7 @@ public class SyntaxInfoConstructionTest extends LightPlatformCodeInsightFixtureT
TextWithMarkupProcessor processor = new TextWithMarkupProcessor() {
@Override
- void createResult(SyntaxInfo syntaxInfo) {
+ void createResult(SyntaxInfo syntaxInfo, Editor editor) {
final ColorRegistry colorRegistry = syntaxInfo.getColorRegistry();
assertEquals(JBColor.BLACK, colorRegistry.dataById(syntaxInfo.getDefaultForeground()));
assertEquals(JBColor.WHITE, colorRegistry.dataById(syntaxInfo.getDefaultBackground()));
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java
index b959aeccd245..30ccd554e5b7 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java
@@ -56,10 +56,12 @@ public class FileTypesTest extends PlatformTestCase {
super.setUp();
myFileTypeManager = (FileTypeManagerImpl)FileTypeManagerEx.getInstanceEx();
myOldIgnoredFilesList = myFileTypeManager.getIgnoredFilesList();
+ myFileTypeManager.reDetectAsync(true);
}
@Override
protected void tearDown() throws Exception {
+ myFileTypeManager.reDetectAsync(false);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -304,11 +306,13 @@ public class FileTypesTest extends PlatformTestCase {
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof PlainTextFileType);
VfsUtil.saveText(vFile, "TYPE:IDEA_MODULE");
+ UIUtil.dispatchAllInvocationEvents();
myFileTypeManager.drainReDetectQueue();
UIUtil.dispatchAllInvocationEvents();
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof ModuleFileType);
VfsUtil.saveText(vFile, "TYPE:IDEA_PROJECT");
+ UIUtil.dispatchAllInvocationEvents();
myFileTypeManager.drainReDetectQueue();
UIUtil.dispatchAllInvocationEvents();
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof ProjectFileType);
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java
index aa06177ea8e6..0acabe1288bb 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/VfsUtilTest.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.IoTestUtil;
@@ -262,13 +263,13 @@ public class VfsUtilTest extends PlatformLangTestCase {
public void testDirAttributeRefreshes() throws IOException {
File tempDir = createTempDirectory();
- VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir);
+ VirtualFile vDir = refreshAndFindFile(tempDir);
assertNotNull(vDir);
assertTrue(vDir.isDirectory());
File file = FileUtil.createTempFile(tempDir, "xxx", "yyy", true);
assertNotNull(file);
- VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ VirtualFile vFile = refreshAndFindFile(file);
assertNotNull(vFile);
assertFalse(vFile.isDirectory());
@@ -278,11 +279,20 @@ public class VfsUtilTest extends PlatformLangTestCase {
assertTrue(created);
assertTrue(file.exists());
- VirtualFile vFile2 = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ VirtualFile vFile2 = refreshAndFindFile(file);
assertNotNull(vFile2);
assertTrue(vFile2.isDirectory());
}
+ private static VirtualFile refreshAndFindFile(final File file) {
+ return UIUtil.invokeAndWaitIfNeeded(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ }
+ });
+ }
+
public void testPresentableUrlSurvivesDeletion() throws IOException {
final VirtualFile file = createTempFile("txt", null, "content", Charset.defaultCharset());
String url = file.getPresentableUrl();
@@ -360,7 +370,7 @@ public class VfsUtilTest extends PlatformLangTestCase {
public void testFindChildByNamePerformance() throws IOException {
File tempDir = createTempDirectory();
- final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir);
+ final VirtualFile vDir = refreshAndFindFile(tempDir);
assertNotNull(vDir);
assertTrue(vDir.isDirectory());
@@ -398,7 +408,7 @@ public class VfsUtilTest extends PlatformLangTestCase {
public void testFindRootWithDenormalizedPath() throws IOException {
File tempJar = IoTestUtil.createTestJar();
- VirtualFile jar = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempJar);
+ VirtualFile jar = refreshAndFindFile(tempJar);
assertNotNull(jar);
JarFileSystem fs = JarFileSystem.getInstance();
@@ -410,7 +420,7 @@ public class VfsUtilTest extends PlatformLangTestCase {
public void testFindRootPerformance() throws IOException {
File tempJar = IoTestUtil.createTestJar();
- final VirtualFile jar = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempJar);
+ final VirtualFile jar = refreshAndFindFile(tempJar);
assertNotNull(jar);
final JarFileSystem fs = JarFileSystem.getInstance();
@@ -440,7 +450,7 @@ public class VfsUtilTest extends PlatformLangTestCase {
assertTrue(new File(tempDir, "CssInvalidElement").createNewFile());
assertTrue(new File(tempDir, "extFiles").createNewFile());
- VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir);
+ VirtualFile vDir = refreshAndFindFile(tempDir);
assertNotNull(vDir);
assertTrue(vDir.isDirectory());
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java
index 571e4b9ed7d2..1fcbc63df05d 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java
@@ -152,6 +152,35 @@ public class VirtualFilePointerTest extends PlatformLangTestCase {
}
}
+ public void testPathNormalization() throws Exception {
+ checkFileName("///", "");
+ }
+ public void testPathNormalization2() throws Exception {
+ checkFileName("\\\\", "/");
+ }
+ public void testPathNormalization3() throws Exception {
+ checkFileName("//", "/////");
+ }
+
+ private void checkFileName(String prefix, String suffix) throws IOException {
+ final File tempDirectory = createTempDirectory();
+
+ final VirtualFile temp = getVirtualFile(tempDirectory);
+ String name = "toCreate.txt";
+ final VirtualFilePointer fileToCreatePointer = createPointerByFile(new File(tempDirectory.getPath() + prefix + name +suffix), null);
+ assertFalse(fileToCreatePointer.isValid());
+ assertNull(fileToCreatePointer.getFile());
+
+ VirtualFile child = createChildData(temp, name);
+
+ assertTrue(fileToCreatePointer.isValid());
+ assertEquals(child, fileToCreatePointer.getFile());
+
+ delete(child);
+ assertFalse(fileToCreatePointer.isValid());
+ assertNull(fileToCreatePointer.getFile());
+ }
+
public void testMovePointedFile() throws Exception {
File tempDirectory = createTempDirectory();
final File moveTarget = new File(tempDirectory, "moveTarget");
@@ -605,34 +634,37 @@ public class VirtualFilePointerTest extends PlatformLangTestCase {
};
Disposable disposable = Disposer.newDisposable();
VirtualFileManager.getInstance().addVirtualFileListener(listener, disposable);
- int N = Timings.adjustAccordingToMySpeed(1000, false);
- System.out.println("N = " + N);
- for (int i=0;i< N;i++) {
- assertNotNull(pointer.getFile());
- FileUtil.delete(ioPtrBase);
- doVfsRefresh();
-
- // ptr is now null, cached as map
-
- final VirtualFile v = LocalFileSystem.getInstance().findFileByIoFile(ioSandPtr);
- new WriteCommandAction.Simple(getProject()) {
- @Override
- protected void run() throws Throwable {
- v.delete(this); //inc FS modCount
- LocalFileSystem.getInstance().findFileByIoFile(ioSand).createChildData(this, ioSandPtr.getName());
- }
- }.execute().throwException();
+ try {
+ int N = Timings.adjustAccordingToMySpeed(1000, false);
+ System.out.println("N = " + N);
+ for (int i=0;i< N;i++) {
+ assertNotNull(pointer.getFile());
+ FileUtil.delete(ioPtrBase);
+ doVfsRefresh();
- // ptr is still null
+ // ptr is now null, cached as map
- assertTrue(ioPtrBase.mkdirs());
- assertTrue(ioPtr.createNewFile());
+ final VirtualFile v = LocalFileSystem.getInstance().findFileByIoFile(ioSandPtr);
+ new WriteCommandAction.Simple(getProject()) {
+ @Override
+ protected void run() throws Throwable {
+ v.delete(this); //inc FS modCount
+ LocalFileSystem.getInstance().findFileByIoFile(ioSand).createChildData(this, ioSandPtr.getName());
+ }
+ }.execute().throwException();
- stressRead(pointer);
- doVfsRefresh();
- }
+ // ptr is still null
+
+ assertTrue(ioPtrBase.mkdirs());
+ assertTrue(ioPtr.createNewFile());
- Disposer.dispose(disposable); // unregister listener early
+ stressRead(pointer);
+ doVfsRefresh();
+ }
+ }
+ finally {
+ Disposer.dispose(disposable); // unregister listener early
+ }
}
private static void stressRead(@NotNull final VirtualFilePointer pointer) {
@@ -665,7 +697,6 @@ public class VirtualFilePointerTest extends PlatformLangTestCase {
}
public void testManyPointersUpdatePerformance() throws IOException {
- FilePointerPartNode.pushDebug(false, disposable);
LoggingListener listener = new LoggingListener();
final List<VFileEvent> events = new ArrayList<VFileEvent>();
final File ioTempDir = createTempDirectory();
@@ -685,16 +716,17 @@ public class VirtualFilePointerTest extends PlatformLangTestCase {
}
}).assertTiming();
}
+
public void testMultipleCreationOfTheSamePointerPerformance() throws IOException {
- FilePointerPartNode.pushDebug(false, disposable);
final LoggingListener listener = new LoggingListener();
- final VirtualFilePointer thePointer = myVirtualFilePointerManager.create(VfsUtilCore.pathToUrl("/a/b/c/d/e"), disposable, listener);
+ final String url = VfsUtilCore.pathToUrl("/a/b/c/d/e");
+ final VirtualFilePointer thePointer = myVirtualFilePointerManager.create(url, disposable, listener);
TempFileSystem.getInstance();
- PlatformTestUtil.startPerformanceTest("same url vfp create", 500, new ThrowableRunnable() {
+ PlatformTestUtil.startPerformanceTest("same url vfp create", 5000, new ThrowableRunnable() {
@Override
public void run() throws Throwable {
- for (int i=0; i<1000000; i++) {
- VirtualFilePointer pointer = myVirtualFilePointerManager.create(VfsUtilCore.pathToUrl("/a/b/c/d/e"), disposable, listener);
+ for (int i=0; i<10000000; i++) {
+ VirtualFilePointer pointer = myVirtualFilePointerManager.create(url, disposable, listener);
assertSame(pointer, thePointer);
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java
index f15f19d26ac8..189ad1b6eb59 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.*;
-import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
+import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.testFramework.PlatformLangTestCase;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
@@ -436,7 +436,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
File subDir = createTestDir(targetDir, "sub");
File file = createTestFile(subDir, "test.txt");
File rootFile = createSubst(targetDir.getPath());
- VirtualDirectoryImpl.allowRootAccess(rootFile.getPath());
+ VfsRootAccess.allowRootAccess(rootFile.getPath());
VirtualFile vfsRoot = myFileSystem.findFileByIoFile(rootFile);
try {
@@ -478,7 +478,7 @@ public class FileWatcherTest extends PlatformLangTestCase {
((NewVirtualFile)vfsRoot).markDirty();
myFileSystem.refresh(false);
}
- VirtualDirectoryImpl.disallowRootAccess(rootFile.getPath());
+ VfsRootAccess.disallowRootAccess(rootFile.getPath());
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/JarFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/JarFileSystemTest.java
index 98fe1c708825..5a836febfdf2 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/JarFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/JarFileSystemTest.java
@@ -18,8 +18,6 @@ package com.intellij.openapi.vfs.local;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.IoTestUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -29,6 +27,7 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.testFramework.PlatformLangTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -40,7 +39,7 @@ import static com.intellij.testFramework.PlatformTestUtil.assertPathsEqual;
public class JarFileSystemTest extends PlatformLangTestCase {
public void testFindFile() throws IOException {
- String rtJarPath = getRtJarPath();
+ String rtJarPath = PlatformTestUtil.getRtJarPath();
VirtualFile jarRoot = findByPath(rtJarPath + JarFileSystem.JAR_SEPARATOR);
assertTrue(jarRoot.isDirectory());
@@ -60,7 +59,7 @@ public class JarFileSystemTest extends PlatformLangTestCase {
}
public void testMetaInf() {
- VirtualFile jarRoot = findByPath(getRtJarPath() + JarFileSystem.JAR_SEPARATOR);
+ VirtualFile jarRoot = findByPath(PlatformTestUtil.getRtJarPath() + JarFileSystem.JAR_SEPARATOR);
assertTrue(jarRoot.isDirectory());
VirtualFile metaInf = jarRoot.findChild("META-INF");
@@ -119,7 +118,7 @@ public class JarFileSystemTest extends PlatformLangTestCase {
}
public void testJarRootForLocalFile() throws Exception {
- String rtJarPath = getRtJarPath();
+ String rtJarPath = PlatformTestUtil.getRtJarPath();
VirtualFile rtJarFile = LocalFileSystem.getInstance().findFileByPath(rtJarPath);
assertNotNull(rtJarFile);
@@ -136,11 +135,6 @@ public class JarFileSystemTest extends PlatformLangTestCase {
assertNull(nonJarRoot);
}
- private static String getRtJarPath() {
- String home = System.getProperty("java.home");
- return SystemInfo.isAppleJvm ? FileUtil.toCanonicalPath(home + "/../Classes/classes.jar") : home + "/lib/rt.jar";
- }
-
private static VirtualFile findByPath(String path) {
VirtualFile file = JarFileSystem.getInstance().findFileByPath(path);
assertNotNull(file);
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
index e4a8d1efd4b3..66c10c26b528 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.newvfs.*;
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
@@ -310,7 +311,7 @@ public class LocalFileSystemTest extends PlatformLangTestCase {
}
String parent = FileUtil.toSystemIndependentName(file.getParent());
- VirtualDirectoryImpl.allowRootAccess(parent);
+ VfsRootAccess.allowRootAccess(parent);
try {
VirtualFile virtualFile = myFS.refreshAndFindFileByIoFile(file);
assertNotNull(virtualFile);
@@ -322,7 +323,7 @@ public class LocalFileSystemTest extends PlatformLangTestCase {
assertEquals(FileAttributes.HIDDEN, attributes.flags);
}
finally {
- VirtualDirectoryImpl.disallowRootAccess(parent);
+ VfsRootAccess.disallowRootAccess(parent);
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
index ec40982f10bb..0388aed9b612 100644
--- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
+++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.groovy
@@ -410,6 +410,7 @@ public class NameUtilMatchingTest extends UsefulTestCase {
assertMatches("foba", "Foo4Bar");
assertMatches("*TEST-* ", "TEST-001");
assertMatches("*TEST-0* ", "TEST-001");
+ assertMatches("*v2 ", "VARCHAR2");
}
public void testSpecialSymbols() {
@@ -521,12 +522,6 @@ public class NameUtilMatchingTest extends UsefulTestCase {
assertPreference("*e", "fileIndex", "file", NameUtil.MatchingCaseSensitivity.NONE);
}
- public void "test first letter case match is important"() {
- assertPreference("*pim", "PNGImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
- assertPreference("*pim", "PImageDecoder", "posIdMap", NameUtil.MatchingCaseSensitivity.NONE)
- assertPreference("*er", "Error", "exchangeRequest", NameUtil.MatchingCaseSensitivity.NONE)
- }
-
public void testPreferences() {
assertPreference(" fb", "FooBar", "_fooBar", NameUtil.MatchingCaseSensitivity.NONE);
assertPreference("*foo", "barFoo", "foobar");
@@ -570,6 +565,14 @@ public class NameUtilMatchingTest extends UsefulTestCase {
assertNoPreference(" path", "getAbsolutePath", "findPath", NameUtil.MatchingCaseSensitivity.FIRST_LETTER);
}
+ public void testPreferStartMatching() {
+ assertPreference("*tree", "FooTree", "Tree", NameUtil.MatchingCaseSensitivity.NONE);
+ }
+
+ public void testPreferContiguousMatching() {
+ assertPreference("*mappablejs", "mappable-js.scope.js", "MappableJs.js", NameUtil.MatchingCaseSensitivity.NONE);
+ }
+
public void testMeaningfulMatchingDegree() {
assertTrue(caseInsensitiveMatcher(" EUC-").matchingDegree("x-EUC-TW") > Integer.MIN_VALUE);
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
index 5a0ee9d46a42..59391a4f0065 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.openapi.module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.util.graph.Graph;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
@@ -30,7 +31,7 @@ import java.util.List;
/**
* Provides services for working with the modules of a project.
*/
-public abstract class ModuleManager {
+public abstract class ModuleManager extends SimpleModificationTracker {
/**
* Returns the module manager instance for the current project.
*
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java
index 69e9c9263264..69c7b53224e0 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java
@@ -19,7 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,7 +32,7 @@ import java.util.Set;
/**
* Allows to query and modify the list of root files and directories belonging to a project.
*/
-public abstract class ProjectRootManager implements ModificationTracker {
+public abstract class ProjectRootManager extends SimpleModificationTracker {
/**
* Returns the project root manager instance for the specified project.
*
@@ -72,7 +72,6 @@ public abstract class ProjectRootManager implements ModificationTracker {
/**
* Unlike getContentRoots(), this includes the project base dir. Is this really necessary?
* TODO: remove this method?
- * @return
*/
public abstract VirtualFile[] getContentRootsFromAllModules();
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java
index 9cabfb68416b..c19ba91e3346 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java
@@ -67,7 +67,7 @@ import java.util.*;
/**
* @author max
*/
-public abstract class ModuleManagerImpl extends ModuleManager implements ProjectComponent, PersistentStateComponent<Element>, ModificationTracker {
+public abstract class ModuleManagerImpl extends ModuleManager implements ProjectComponent, PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.module.impl.ModuleManagerImpl");
public static final Key<String> DISPOSED_MODULE_NAME = Key.create("DisposedNeverAddedModuleName");
private static final String IML_EXTENSION = ".iml";
@@ -84,7 +84,6 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
@NonNls private static final String ATTRIBUTE_FILEURL = "fileurl";
@NonNls public static final String ATTRIBUTE_FILEPATH = "filepath";
@NonNls private static final String ATTRIBUTE_GROUP = "group";
- private long myModificationCount;
public static ModuleManagerImpl getInstanceImpl(Project project) {
return (ModuleManagerImpl)getInstance(project);
@@ -117,11 +116,6 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
}
@Override
- public long getModificationCount() {
- return myModificationCount;
- }
-
- @Override
public Element getState() {
final Element e = new Element("state");
writeExternal(e);
@@ -288,7 +282,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
}
}
- fireErrors(errors);
+ onModuleLoadErrors(errors);
showUnknownModuleTypeNotification(modulesWithUnknownTypes);
@@ -327,7 +321,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
}
}
- private void fireErrors(final List<ModuleLoadingErrorDescription> errors) {
+ protected void onModuleLoadErrors(final List<ModuleLoadingErrorDescription> errors) {
if (errors.isEmpty()) return;
myModuleModel.myModulesCache = null;
@@ -343,6 +337,10 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
}
}
+ fireModuleLoadErrors(errors);
+ }
+
+ protected void fireModuleLoadErrors(List<ModuleLoadingErrorDescription> errors) {
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
throw new RuntimeException(errors.get(0).getDescription());
}
@@ -468,7 +466,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
@Override
@NotNull
public Module newModule(@NotNull String filePath, final String moduleTypeId) {
- myModificationCount++;
+ incModificationCount();
final ModifiableModuleModel modifiableModel = getModifiableModel();
final Module module = modifiableModel.newModule(filePath, moduleTypeId);
modifiableModel.commit();
@@ -478,7 +476,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
@Override
@NotNull
public Module loadModule(@NotNull String filePath) throws InvalidDataException, IOException, JDOMException, ModuleWithNameAlreadyExists {
- myModificationCount++;
+ incModificationCount();
final ModifiableModuleModel modifiableModel = getModifiableModel();
final Module module = modifiableModel.loadModule(filePath);
modifiableModel.commit();
@@ -941,7 +939,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Project
private void commitModel(final ModuleModelImpl moduleModel, final Runnable runnable) {
myModuleModel.myModulesCache = null;
- myModificationCount++;
+ incModificationCount();
ApplicationManager.getApplication().assertWriteAccessAllowed();
final Collection<Module> oldModules = myModuleModel.myPathToModule.values();
final Collection<Module> newModules = moduleModel.myPathToModule.values();
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
index cadd8915bfb6..3bf16fcca67c 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -140,8 +141,13 @@ public class ModuleRootModificationUtil {
});
}
- public static void updateModel(@NotNull Module module, @NotNull Consumer<ModifiableRootModel> task) {
- final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+ public static void updateModel(@NotNull final Module module, @NotNull Consumer<ModifiableRootModel> task) {
+ final ModifiableRootModel model = ApplicationManager.getApplication().runReadAction(new Computable<ModifiableRootModel>() {
+ @Override
+ public ModifiableRootModel compute() {
+ return ModuleRootManager.getInstance(module).getModifiableModel();
+ }
+ });
try {
task.consume(model);
doWriteAction(new Runnable() {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
index 97d7d24f1a1e..85a098341e4e 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -66,7 +66,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
private String myProjectSdkName;
private String myProjectSdkType;
- private long myModificationCount = 0;
@NonNls private static final String ATTRIBUTE_VERSION = "version";
private final OrderRootsCache myRootsCache;
@@ -418,7 +417,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
clearScopesCaches();
- myModificationCount++;
+ incModificationCount();
PsiManager psiManager = PsiManager.getInstance(myProject);
psiManager.dropResolveCaches();
@@ -525,7 +524,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void afterLibraryAdded(final Library newLibrary) {
- myModificationCount++;
+ incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
@@ -538,7 +537,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void afterLibraryRenamed(final Library library) {
- myModificationCount++;
+ incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
@@ -551,7 +550,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void beforeLibraryRemoved(final Library library) {
- myModificationCount++;
+ incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
@@ -564,7 +563,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void afterLibraryRemoved(final Library library) {
- myModificationCount++;
+ incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
@@ -675,9 +674,4 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
}
}
}
-
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
}
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 8b325c32304d..2d74782822db 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -336,7 +336,7 @@ tab.name.all.facets=All Facets
action.name.facet.navigate=Navigate
error.message.unknown.facet.type.0=Unknown facet type: ''{0}''
-error.message.cannot.load.facet.condiguration.0=Cannot load facet condiguration: {0}
+error.message.cannot.load.facet.configuration.0=Cannot load facet configuration: {0}
error.message.facet.type.isn.t.specified=Facet type isn''t specified
error.message.0.facet.must.be.placed.under.1.facet={0} facet must be placed under {1} facet
error.message.0.cannot.be.placed.under.1={0} cannot be placed under {1}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgent.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgent.java
index 90bef40ece63..27c7228c185b 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgent.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,17 +16,10 @@
package com.intellij.remoteServer.agent.util;
import com.intellij.remoteServer.agent.RemoteAgent;
-import com.intellij.remoteServer.agent.annotation.FinalCall;
+import com.intellij.remoteServer.agent.annotation.ChildCall;
-/**
- * @author michael.golubev
- */
-public interface CloudAgent<Config extends CloudAgentConfig> extends RemoteAgent {
-
- void connect(Config config, CloudAgentCallback callback, CloudAgentLogger logger);
-
- @FinalCall
- void disconnect();
+public interface CloudAgent extends RemoteAgent {
- void getDeployments(CloudAgentGetDeploymentsCallback callback);
+ @ChildCall
+ CloudRemoteApplication[] getApplications();
}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentApplication.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentApplication.java
new file mode 100644
index 000000000000..062bd24976df
--- /dev/null
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentApplication.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.agent.util;
+
+import com.intellij.remoteServer.agent.annotation.AsyncCall;
+
+public interface CloudAgentApplication {
+
+ @AsyncCall
+ void undeploy(CloudAgentDeploymentCallback callback);
+}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentBase.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentBase.java
new file mode 100644
index 000000000000..9963a9dd5715
--- /dev/null
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentBase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.agent.util;
+
+import com.intellij.remoteServer.agent.annotation.ChildCall;
+import com.intellij.remoteServer.agent.annotation.FinalCall;
+
+public interface CloudAgentBase<Config extends CloudAgentConfig> extends CloudAgent {
+
+ void connect(Config config, CloudAgentCallback callback, CloudAgentLogger logger, CloudAgentErrorHandler errorHandler);
+
+ @FinalCall
+ void disconnect();
+
+ @ChildCall
+ CloudAgentApplication createApplication(String applicationName);
+}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentDeployment.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentDeployment.java
index 7f99e4f3d328..427e645333f2 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentDeployment.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentDeployment.java
@@ -20,11 +20,8 @@ import com.intellij.remoteServer.agent.annotation.AsyncCall;
/**
* @author michael.golubev
*/
-public interface CloudAgentDeployment {
+public interface CloudAgentDeployment extends CloudAgentApplication {
@AsyncCall
void deploy(CloudAgentDeploymentCallback callback);
-
- @AsyncCall
- void undeploy(CloudAgentDeploymentCallback callback);
}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentWithDeployment.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentWithDeployment.java
index 1076527dd05a..27533ffd1bb8 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentWithDeployment.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudAgentWithDeployment.java
@@ -23,7 +23,7 @@ import com.intellij.remoteServer.agent.annotation.ChildCall;
public interface CloudAgentWithDeployment<Config extends CloudAgentConfig,
DeploymentConfig extends CloudAgentDeploymentConfig,
LoggingHandler extends CloudAgentLoggingHandler>
- extends CloudAgent<Config> {
+ extends CloudAgentBase<Config> {
@ChildCall
CloudAgentDeployment createDeployment(DeploymentConfig config, LoggingHandler loggingHandler);
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitAgent.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitAgent.java
index 630782a49384..cc9867477c7e 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitAgent.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitAgent.java
@@ -15,22 +15,19 @@
*/
package com.intellij.remoteServer.agent.util;
-import com.intellij.remoteServer.agent.RemoteAgent;
import com.intellij.remoteServer.agent.annotation.ChildCall;
import com.intellij.remoteServer.agent.annotation.FinalCall;
/**
* @author michael.golubev
*/
-public interface CloudGitAgent<C extends CloudAgentConfigBase, D extends CloudGitAgentDeployment> extends RemoteAgent {
+public interface CloudGitAgent<C extends CloudAgentConfigBase, D extends CloudGitAgentDeployment> extends CloudAgent {
void connect(C config, CloudAgentErrorHandler errorHandler, CloudAgentLogger logger);
@FinalCall
void disconnect();
- DeploymentData[] getDeployments();
-
@ChildCall
D createDeployment(String deploymentName, CloudLoggingHandler loggingHandler);
}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitApplication.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitApplication.java
index a258bc649ec8..a1e6694eaed9 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitApplication.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudGitApplication.java
@@ -18,7 +18,7 @@ package com.intellij.remoteServer.agent.util;
/**
* @author michael.golubev
*/
-public interface CloudGitApplication extends CloudApplication {
+public interface CloudGitApplication extends CloudRemoteApplication {
String getGitUrl();
}
diff --git a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudApplication.java b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudRemoteApplication.java
index 7e5576531c00..1be575c82177 100644
--- a/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudApplication.java
+++ b/platform/remote-servers/agent-rt/src/com/intellij/remoteServer/agent/util/CloudRemoteApplication.java
@@ -18,7 +18,7 @@ package com.intellij.remoteServer.agent.util;
/**
* @author michael.golubev
*/
-public interface CloudApplication {
+public interface CloudRemoteApplication {
String getName();
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java
index b057fb30a7fa..3f5e4ba42b0b 100644
--- a/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/runtime/deployment/ServerRuntimeInstance.java
@@ -4,6 +4,7 @@ import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguratio
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.runtime.RemoteOperationCallback;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author nik
@@ -16,6 +17,14 @@ public abstract class ServerRuntimeInstance<D extends DeploymentConfiguration> {
public abstract void computeDeployments(@NotNull ComputeDeploymentsCallback callback);
@NotNull
+ public String getDeploymentName(@NotNull DeploymentSource source, D configuration) {
+ return getDeploymentName(source);
+ }
+
+ /**
+ * @deprecated use {@link #getDeploymentName(com.intellij.remoteServer.configuration.deployment.DeploymentSource, D configuration)} instead
+ */
+ @NotNull
public String getDeploymentName(@NotNull DeploymentSource source) {
return source.getPresentableName();
}
@@ -28,6 +37,9 @@ public abstract class ServerRuntimeInstance<D extends DeploymentConfiguration> {
public interface ComputeDeploymentsCallback extends RemoteOperationCallback {
void addDeployment(@NotNull String deploymentName);
+
+ void addDeployment(@NotNull String deploymentName, @Nullable DeploymentRuntime deploymentRuntime);
+
void succeeded();
}
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
index 3e260227abe1..71b368031233 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/agent/impl/ThreadInvocationHandler.java
@@ -10,10 +10,7 @@ import com.intellij.remoteServer.agent.impl.util.SequentialTaskExecutor;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.Nullable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import java.lang.reflect.*;
import java.util.Map;
import java.util.concurrent.Callable;
@@ -79,35 +76,20 @@ public class ThreadInvocationHandler implements InvocationHandler {
return cached;
}
+ Object result;
Class<?> childClass = child.getClass();
- Class<?>[] childInterfaces = childClass.getInterfaces();
- LOG.assertTrue(childInterfaces.length == 1, "Child class is expected to implement single child interface");
- Class<?> childInterface = childInterfaces[0];
-
- Class<?> callerChildInterface;
- try {
- callerChildInterface = myCallerClassLoader.loadClass(childInterface.getName());
- }
- catch (ClassNotFoundException e) {
- LOG.error(e);
- return null;
- }
-
- Object preWrappedChild;
- if (myPreWrapperFactory == null) {
- preWrappedChild = child;
+ if (childClass.isArray()) {
+ Class<?> componentType = childClass.getComponentType();
+ int length = Array.getLength(child);
+ result = Array.newInstance(componentType, length);
+ for (int i = 0; i < length; i++) {
+ Array.set(result, i, createChildProxy(Array.get(child, i)));
+ }
}
else {
- preWrappedChild = Proxy.newProxyInstance(myCallerClassLoader,
- new Class[]{callerChildInterface},
- myPreWrapperFactory.createWrapperInvocationHandler(child));
+ result = createChildProxy(child);
}
- Object result = Proxy.newProxyInstance(myCallerClassLoader,
- new Class[]{callerChildInterface},
- new ThreadInvocationHandler(myTaskExecutor, myCallerClassLoader, preWrappedChild,
- myPreWrapperFactory));
-
myChild2Wrapped.put(child, result);
return result;
}
@@ -150,4 +132,35 @@ public class ThreadInvocationHandler implements InvocationHandler {
}
}
}
+
+ private Object createChildProxy(Object child) {
+ Class<?> childClass = child.getClass();
+ Class<?>[] childInterfaces = childClass.getInterfaces();
+ LOG.assertTrue(childInterfaces.length == 1, "Child class is expected to implement single child interface");
+ Class<?> childInterface = childInterfaces[0];
+
+ Class<?> callerChildInterface;
+ try {
+ callerChildInterface = myCallerClassLoader.loadClass(childInterface.getName());
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ return null;
+ }
+
+ Object preWrappedChild;
+ if (myPreWrapperFactory == null) {
+ preWrappedChild = child;
+ }
+ else {
+ preWrappedChild = Proxy.newProxyInstance(myCallerClassLoader,
+ new Class[]{callerChildInterface},
+ myPreWrapperFactory.createWrapperInvocationHandler(child));
+ }
+
+ return Proxy.newProxyInstance(myCallerClassLoader,
+ new Class[]{callerChildInterface},
+ new ThreadInvocationHandler(myTaskExecutor, myCallerClassLoader, preWrappedChild,
+ myPreWrapperFactory));
+ }
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
index c633976df2be..68cbafb202b6 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/DeployToServerState.java
@@ -67,18 +67,13 @@ public class DeployToServerState<S extends ServerConfiguration, D extends Deploy
else {
debugConnector = null;
}
- connection.computeDeployments(new Runnable() {
- @Override
- public void run() {
- connection.deploy(new DeploymentTaskImpl(mySource, myConfiguration, project, debugConnector, myEnvironment),
- new ParameterizedRunnable<String>() {
- @Override
- public void run(String s) {
- RemoteServersView.getInstance(project).showDeployment(connection, s);
- }
- });
- }
- });
+ connection.deploy(new DeploymentTaskImpl(mySource, myConfiguration, project, debugConnector, myEnvironment),
+ new ParameterizedRunnable<String>() {
+ @Override
+ public void run(String s) {
+ RemoteServersView.getInstance(project).showDeployment(connection, s);
+ }
+ });
return null;
}
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
index fe43f2aa4f4d..5c0e27634041 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionImpl.java
@@ -19,6 +19,7 @@ import com.intellij.remoteServer.runtime.deployment.*;
import com.intellij.remoteServer.runtime.deployment.debug.DebugConnectionData;
import com.intellij.remoteServer.runtime.deployment.debug.DebugConnectionDataNotAvailableException;
import com.intellij.remoteServer.runtime.deployment.debug.DebugConnector;
+import com.intellij.util.Consumer;
import com.intellij.util.ParameterizedRunnable;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +39,7 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
private volatile ConnectionStatus myStatus = ConnectionStatus.DISCONNECTED;
private volatile String myStatusText;
private volatile ServerRuntimeInstance<D> myRuntimeInstance;
- private final Map<String, Deployment> myRemoteDeployments = new HashMap<String, Deployment>();
+ private final Map<String, DeploymentImpl> myRemoteDeployments = new HashMap<String, DeploymentImpl>();
private final Map<String, DeploymentImpl> myLocalDeployments = new HashMap<String, DeploymentImpl>();
private final Map<String, DeploymentLogManagerImpl> myLogManagers = new ConcurrentHashMap<String, DeploymentLogManagerImpl>();
@@ -110,7 +111,7 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
@Override
public void connected(@NotNull ServerRuntimeInstance<D> instance) {
DeploymentSource source = task.getSource();
- String deploymentName = instance.getDeploymentName(source);
+ String deploymentName = instance.getDeploymentName(source, task.getConfiguration());
DeploymentImpl deployment;
synchronized (myLocalDeployments) {
deployment = new DeploymentImpl(deploymentName, DeploymentStatus.DEPLOYING, null, null, task);
@@ -149,18 +150,23 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
private void computeDeployments(ServerRuntimeInstance<D> instance, final Runnable onFinished) {
instance.computeDeployments(new ServerRuntimeInstance.ComputeDeploymentsCallback() {
- private final List<Deployment> myDeployments = new ArrayList<Deployment>();
+ private final List<DeploymentImpl> myDeployments = new ArrayList<DeploymentImpl>();
@Override
public void addDeployment(@NotNull String deploymentName) {
- myDeployments.add(new DeploymentImpl(deploymentName, DeploymentStatus.DEPLOYED, null, null, null));
+ addDeployment(deploymentName, null);
+ }
+
+ @Override
+ public void addDeployment(@NotNull String deploymentName, @Nullable DeploymentRuntime deploymentRuntime) {
+ myDeployments.add(new DeploymentImpl(deploymentName, DeploymentStatus.DEPLOYED, null, deploymentRuntime, null));
}
@Override
public void succeeded() {
synchronized (myRemoteDeployments) {
myRemoteDeployments.clear();
- for (Deployment deployment : myDeployments) {
+ for (DeploymentImpl deployment : myDeployments) {
myRemoteDeployments.put(deployment.getName(), deployment);
}
}
@@ -183,25 +189,57 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
@Override
public void undeploy(@NotNull Deployment deployment, @NotNull final DeploymentRuntime runtime) {
final String deploymentName = deployment.getName();
- final DeploymentImpl localDeployment;
+ final DeploymentImpl deploymentImpl;
+ final Map<String, DeploymentImpl> deploymentsMap;
synchronized (myLocalDeployments) {
- localDeployment = myLocalDeployments.get(deploymentName);
- if (localDeployment != null) {
- localDeployment.changeState(DeploymentStatus.DEPLOYED, DeploymentStatus.UNDEPLOYING, null, null);
+ synchronized (myRemoteDeployments) {
+ DeploymentImpl localDeployment = myLocalDeployments.get(deploymentName);
+ if (localDeployment != null) {
+ deploymentImpl = localDeployment;
+ deploymentsMap = myLocalDeployments;
+ }
+ else {
+ DeploymentImpl remoteDeployment = myRemoteDeployments.get(deploymentName);
+ if (remoteDeployment != null) {
+ deploymentImpl = remoteDeployment;
+ deploymentsMap = myRemoteDeployments;
+ }
+ else {
+ deploymentImpl = null;
+ deploymentsMap = null;
+ }
+ }
+ if (deploymentImpl != null) {
+ deploymentImpl.changeState(DeploymentStatus.DEPLOYED, DeploymentStatus.UNDEPLOYING, null, null);
+ }
}
}
myEventDispatcher.queueDeploymentsChanged(this);
- final LoggingHandlerImpl loggingHandler = myLogManagers.get(deploymentName).getMainLoggingHandler();
- loggingHandler.printlnSystemMessage("Undeploying '" + deploymentName + "'...");
+ DeploymentLogManagerImpl logManager = myLogManagers.get(deploymentName);
+ final LoggingHandlerImpl loggingHandler = logManager == null ? null : logManager.getMainLoggingHandler();
+ final Consumer<String> logConsumer = new Consumer<String>() {
+ @Override
+ public void consume(String message) {
+ if (loggingHandler == null) {
+ LOG.info(message);
+ }
+ else {
+ loggingHandler.printlnSystemMessage(message);
+ }
+ }
+ };
+
+ logConsumer.consume("Undeploying '" + deploymentName + "'...");
runtime.undeploy(new DeploymentRuntime.UndeploymentTaskCallback() {
@Override
public void succeeded() {
- loggingHandler.printlnSystemMessage("'" + deploymentName + "' has been undeployed successfully.");
- synchronized (myLocalDeployments) {
- if (localDeployment != null &&
- localDeployment.changeState(DeploymentStatus.UNDEPLOYING, DeploymentStatus.NOT_DEPLOYED, null, null)) {
- myLocalDeployments.remove(deploymentName);
+ logConsumer.consume("'" + deploymentName + "' has been undeployed successfully.");
+ if (deploymentImpl != null) {
+ synchronized (deploymentsMap) {
+ if (deploymentImpl.changeState(DeploymentStatus.UNDEPLOYING, DeploymentStatus.NOT_DEPLOYED, null, null)) {
+ deploymentsMap.remove(deploymentName);
+ }
}
}
myLogManagers.remove(deploymentName);
@@ -211,10 +249,10 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
@Override
public void errorOccurred(@NotNull String errorMessage) {
- loggingHandler.printlnSystemMessage("Failed to undeploy '" + deploymentName + "': " + errorMessage);
- synchronized (myLocalDeployments) {
- if (localDeployment != null) {
- localDeployment.changeState(DeploymentStatus.UNDEPLOYING, DeploymentStatus.DEPLOYED, errorMessage, runtime);
+ logConsumer.consume("Failed to undeploy '" + deploymentName + "': " + errorMessage);
+ if (deploymentImpl != null) {
+ synchronized (deploymentsMap) {
+ deploymentImpl.changeState(DeploymentStatus.UNDEPLOYING, DeploymentStatus.DEPLOYED, errorMessage, runtime);
}
}
myEventDispatcher.queueDeploymentsChanged(ServerConnectionImpl.this);
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
index 71f04e2265f1..f12e646a72b9 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
@@ -1,10 +1,12 @@
package com.intellij.remoteServer.impl.runtime;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.ServerConfiguration;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnectionManager;
+import com.intellij.util.Alarm;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -17,6 +19,9 @@ import java.util.Map;
* @author nik
*/
public class ServerConnectionManagerImpl extends ServerConnectionManager {
+
+ private static final int POLL_DEPLOYMENTS_DELAY = 2000;
+
private final Map<RemoteServer<?>, ServerConnection> myConnections = new HashMap<RemoteServer<?>, ServerConnection>();
private final ServerConnectionEventDispatcher myEventDispatcher = new ServerConnectionEventDispatcher();
@@ -29,10 +34,29 @@ public class ServerConnectionManagerImpl extends ServerConnectionManager {
connection = doCreateConnection(server, this);
myConnections.put(server, connection);
myEventDispatcher.fireConnectionCreated(connection);
+ pollDeployments(connection);
}
return connection;
}
+ private void pollDeployments(final ServerConnection connection) {
+ connection.computeDeployments(new Runnable() {
+
+ @Override
+ public void run() {
+ new Alarm().addRequest(new Runnable() {
+
+ @Override
+ public void run() {
+ if (connection == getConnection(connection.getServer())) {
+ pollDeployments(connection);
+ }
+ }
+ }, POLL_DEPLOYMENTS_DELAY, ModalityState.any());
+ }
+ });
+ }
+
@NotNull
@Override
public <C extends ServerConfiguration> ServerConnection createTemporaryConnection(@NotNull RemoteServer<C> server) {
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
index df649453ee4e..f860d6dfa98c 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
@@ -108,7 +108,7 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
Set<ServersTreeStructure.RemoteServerNode> nodes = getSelectedRemoteServerNodes();
if (nodes.size() == 1) {
RemoteServer<?> server = nodes.iterator().next().getValue();
- ServerConnectionManager.getInstance().getOrCreateConnection(server).computeDeployments(EmptyRunnable.INSTANCE);
+ ServerConnectionManager.getInstance().getOrCreateConnection(server);
return true;
}
return false;
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java
index 96cd0fa87c56..4cb1c01943be 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java
@@ -255,8 +255,7 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
@Override
public void startServer(@NotNull Executor executor) {
- ServerConnection<?> connection = ServerConnectionManager.getInstance().getOrCreateConnection(getValue());
- connection.computeDeployments(EmptyRunnable.INSTANCE);
+ ServerConnectionManager.getInstance().getOrCreateConnection(getValue());
}
@Override
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntime.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntime.java
new file mode 100644
index 000000000000..093cfb50bcc0
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntime.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.util;
+
+import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime;
+
+public abstract class CloudApplicationRuntime extends DeploymentRuntime {
+
+ private final String myApplicationName;
+
+ public CloudApplicationRuntime(String applicationName) {
+ myApplicationName = applicationName;
+ }
+
+ public String getApplicationName() {
+ return myApplicationName;
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeBase.java
new file mode 100644
index 000000000000..a4689b16d57a
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeBase.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.util;
+
+import com.intellij.remoteServer.agent.util.CloudAgentApplication;
+import com.intellij.remoteServer.agent.util.CloudAgentDeploymentCallback;
+import com.intellij.remoteServer.runtime.ServerTaskExecutor;
+import com.intellij.util.ThrowableRunnable;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class CloudApplicationRuntimeBase extends CloudApplicationRuntime {
+
+ private final ServerTaskExecutor myTaskExecutor;
+
+ public CloudApplicationRuntimeBase(ServerTaskExecutor taskExecutor, String applicationName) {
+ super(applicationName);
+ myTaskExecutor = taskExecutor;
+ }
+
+ @Override
+ public void undeploy(@NotNull final UndeploymentTaskCallback callback) {
+ myTaskExecutor.submit(new ThrowableRunnable<Exception>() {
+
+ @Override
+ public void run() throws Exception {
+ getApplication().undeploy(new CloudAgentDeploymentCallback() {
+ @Override
+ public void succeeded() {
+ callback.succeeded();
+ }
+
+ @Override
+ public void errorOccurred(String errorMessage) {
+ callback.errorOccurred(errorMessage);
+ }
+ });
+ }
+ }, callback);
+ }
+
+ protected abstract CloudAgentApplication getApplication();
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeImpl.java
new file mode 100644
index 000000000000..a3d780ab8cc4
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudApplicationRuntimeImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.util;
+
+import com.intellij.remoteServer.agent.util.CloudAgentApplication;
+import com.intellij.remoteServer.agent.util.CloudAgentBase;
+import com.intellij.remoteServer.runtime.ServerTaskExecutor;
+
+public class CloudApplicationRuntimeImpl extends CloudApplicationRuntimeBase {
+
+ private final CloudAgentApplication myAgentApplication;
+
+ public CloudApplicationRuntimeImpl(ServerTaskExecutor taskExecutor, CloudAgentBase agent, String applicationName) {
+ super(taskExecutor, applicationName);
+ myAgentApplication = agent.createApplication(applicationName);
+ }
+
+ @Override
+ protected CloudAgentApplication getApplication() {
+ return myAgentApplication;
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudConnectionTask.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudConnectionTask.java
index bd83b9d27d48..82492e130f0e 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudConnectionTask.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudConnectionTask.java
@@ -37,7 +37,7 @@ public abstract class CloudConnectionTask<
T,
SC extends ServerConfigurationBase,
DC extends DeploymentConfiguration,
- SR extends CloudServerRuntimeInstance<DC>> extends CloudRuntimeTask<T, DC, SR> {
+ SR extends CloudServerRuntimeInstance<DC, ?, ?>> extends CloudRuntimeTask<T, DC, SR> {
private final RemoteServer<SC> myServer;
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudDeploymentRuntime.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudDeploymentRuntime.java
index d21c319ad6ca..1ddf9b3cb7d6 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudDeploymentRuntime.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudDeploymentRuntime.java
@@ -15,75 +15,43 @@
*/
package com.intellij.remoteServer.util;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Ref;
-import com.intellij.remoteServer.agent.util.CloudApplication;
-import com.intellij.remoteServer.agent.util.CloudGitAgentDeployment;
-import com.intellij.remoteServer.agent.util.CloudLoggingHandler;
+import com.intellij.remoteServer.agent.util.CloudRemoteApplication;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.runtime.deployment.DeploymentLogManager;
-import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime;
import com.intellij.remoteServer.runtime.deployment.DeploymentTask;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
import com.intellij.remoteServer.runtime.log.LoggingHandler;
-import com.intellij.util.ThrowableRunnable;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author michael.golubev
*/
-public abstract class CloudDeploymentRuntime extends DeploymentRuntime {
+public abstract class CloudDeploymentRuntime extends CloudGitApplicationRuntime {
- private final CloudMultiSourceServerRuntimeInstance myServerRuntime;
private final DeploymentTask myTask;
- private final CloudGitAgentDeployment myDeployment;
- private final String myApplicationName;
- private final String myPresentableName;
- private final CloudLoggingHandler myLoggingHandler;
- @Nullable private final DeploymentLogManager myLogManager;
-
public CloudDeploymentRuntime(CloudMultiSourceServerRuntimeInstance serverRuntime,
DeploymentSource source,
DeploymentTask<? extends CloudDeploymentNameConfiguration> task,
@Nullable DeploymentLogManager logManager) throws ServerRuntimeException {
- myServerRuntime = serverRuntime;
+ super(serverRuntime,
+ task.getConfiguration().getDeploymentSourceName(source),
+ logManager);
myTask = task;
-
- myLogManager = logManager;
- myLoggingHandler = logManager == null ? new CloudSilentLoggingHandlerImpl() : new CloudLoggingHandlerImpl(logManager);
-
- CloudDeploymentNameConfiguration deploymentConfiguration = task.getConfiguration();
- myApplicationName = deploymentConfiguration.getDeploymentSourceName(source);
-
- myPresentableName = source.getPresentableName();
-
- myDeployment = serverRuntime.getAgent().createDeployment(myApplicationName, myLoggingHandler);
- }
-
- protected CloudMultiSourceServerRuntimeInstance getServerRuntime() {
- return myServerRuntime;
}
protected DeploymentTask getTask() {
return myTask;
}
- @Nullable
- protected DeploymentLogManager getLogManager() {
- return myLogManager;
- }
-
public void deploy(ServerRuntimeInstance.DeploymentOperationCallback callback) {
try {
- CloudApplication application = deploy();
+ CloudRemoteApplication application = deploy();
- if (myLogManager != null) {
- LoggingHandler loggingHandler = myLogManager.getMainLoggingHandler();
+ DeploymentLogManager logManager = getLogManager();
+ if (logManager != null) {
+ LoggingHandler loggingHandler = logManager.getMainLoggingHandler();
loggingHandler.print("Application is available at ");
loggingHandler.printHyperlink(application.getWebUrl());
loggingHandler.print("\n");
@@ -96,72 +64,9 @@ public abstract class CloudDeploymentRuntime extends DeploymentRuntime {
}
}
- @Override
- public void undeploy(final @NotNull UndeploymentTaskCallback callback) {
- myServerRuntime.getTaskExecutor().submit(new ThrowableRunnable<Exception>() {
-
- @Override
- public void run() throws Exception {
- try {
- if (!confirmUndeploy()) {
- throw new ServerRuntimeException("Undeploy cancelled");
- }
-
- undeploy();
-
- callback.succeeded();
- }
- catch (ServerRuntimeException e) {
- callback.errorOccurred(e.getMessage());
- }
- }
- }, callback);
- }
-
- public CloudGitAgentDeployment getDeployment() {
- return myDeployment;
- }
-
public Project getProject() {
return myTask.getProject();
}
- public String getApplicationName() {
- return myApplicationName;
- }
-
- public AgentTaskExecutor getAgentTaskExecutor() {
- return myServerRuntime.getAgentTaskExecutor();
- }
-
- public CloudLoggingHandler getLoggingHandler() {
- return myLoggingHandler;
- }
-
- public boolean confirmUndeploy() {
- final Ref<Boolean> confirmed = new Ref<Boolean>(false);
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
-
- @Override
- public void run() {
- String title = CloudBundle.getText("cloud.undeploy.confirm.title");
- while (true) {
- String password = Messages.showPasswordDialog(CloudBundle.getText("cloud.undeploy.confirm.message", myPresentableName), title);
- if (password == null) {
- return;
- }
- if (password.equals(myServerRuntime.getConfiguration().getPassword())) {
- confirmed.set(true);
- return;
- }
- Messages.showErrorDialog(CloudBundle.getText("cloud.undeploy.confirm.password.incorrect"), title);
- }
- }
- }, ModalityState.defaultModalityState());
- return confirmed.get();
- }
-
- public abstract CloudApplication deploy() throws ServerRuntimeException;
-
- public abstract void undeploy() throws ServerRuntimeException;
+ public abstract CloudRemoteApplication deploy() throws ServerRuntimeException;
}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudGitApplicationRuntime.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudGitApplicationRuntime.java
new file mode 100644
index 000000000000..990167d951e4
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudGitApplicationRuntime.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.util;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Ref;
+import com.intellij.remoteServer.agent.util.CloudGitAgentDeployment;
+import com.intellij.remoteServer.agent.util.CloudLoggingHandler;
+import com.intellij.remoteServer.runtime.deployment.DeploymentLogManager;
+import com.intellij.util.ThrowableRunnable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class CloudGitApplicationRuntime extends CloudApplicationRuntime {
+
+ private final CloudMultiSourceServerRuntimeInstance myServerRuntime;
+ private final DeploymentLogManager myLogManager;
+ private final CloudLoggingHandler myLoggingHandler;
+
+ private final CloudGitAgentDeployment myDeployment;
+
+ public CloudGitApplicationRuntime(CloudMultiSourceServerRuntimeInstance serverRuntime,
+ String applicationName,
+ @Nullable DeploymentLogManager logManager) {
+ super(applicationName);
+ myServerRuntime = serverRuntime;
+ myLogManager = logManager;
+ myLoggingHandler = logManager == null ? new CloudSilentLoggingHandlerImpl() : new CloudLoggingHandlerImpl(logManager);
+ myDeployment = serverRuntime.getAgent().createDeployment(applicationName, myLoggingHandler);
+ }
+
+ protected CloudMultiSourceServerRuntimeInstance getServerRuntime() {
+ return myServerRuntime;
+ }
+
+ protected DeploymentLogManager getLogManager() {
+ return myLogManager;
+ }
+
+ protected CloudLoggingHandler getLoggingHandler() {
+ return myLoggingHandler;
+ }
+
+ public AgentTaskExecutor getAgentTaskExecutor() {
+ return getServerRuntime().getAgentTaskExecutor();
+ }
+
+ public CloudGitAgentDeployment getDeployment() {
+ return myDeployment;
+ }
+
+ @Override
+ public void undeploy(final @NotNull UndeploymentTaskCallback callback) {
+ getServerRuntime().getTaskExecutor().submit(new ThrowableRunnable<Exception>() {
+
+ @Override
+ public void run() throws Exception {
+ try {
+ if (!confirmUndeploy()) {
+ throw new ServerRuntimeException("Undeploy cancelled");
+ }
+
+ undeploy();
+
+ callback.succeeded();
+ }
+ catch (ServerRuntimeException e) {
+ callback.errorOccurred(e.getMessage());
+ }
+ }
+ }, callback);
+ }
+
+
+ public void undeploy() throws ServerRuntimeException {
+ getAgentTaskExecutor().execute(new Computable<Object>() {
+
+ @Override
+ public Object compute() {
+ getDeployment().deleteApplication();
+ return null;
+ }
+ });
+ }
+
+ private boolean confirmUndeploy() {
+ final Ref<Boolean> confirmed = new Ref<Boolean>(false);
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ String title = CloudBundle.getText("cloud.undeploy.confirm.title");
+ while (true) {
+ String password = Messages.showPasswordDialog(CloudBundle.getText("cloud.undeploy.confirm.message", getApplicationName()), title);
+ if (password == null) {
+ return;
+ }
+ if (password.equals(getServerRuntime().getConfiguration().getPassword())) {
+ confirmed.set(true);
+ return;
+ }
+ Messages.showErrorDialog(CloudBundle.getText("cloud.undeploy.confirm.password.incorrect"), title);
+ }
+ }
+ }, ModalityState.defaultModalityState());
+ return confirmed.get();
+ }
+}
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudMultiSourceServerRuntimeInstance.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudMultiSourceServerRuntimeInstance.java
index 8db26a7ad661..3fd3f24b190c 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudMultiSourceServerRuntimeInstance.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudMultiSourceServerRuntimeInstance.java
@@ -4,11 +4,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.remoteServer.ServerType;
-import com.intellij.remoteServer.agent.RemoteAgentManager;
import com.intellij.remoteServer.agent.util.CloudAgentConfigBase;
import com.intellij.remoteServer.agent.util.CloudAgentLogger;
import com.intellij.remoteServer.agent.util.CloudGitAgent;
-import com.intellij.remoteServer.agent.util.DeploymentData;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.runtime.ServerConnector;
@@ -31,16 +29,11 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
AC extends CloudAgentConfigBase,
A extends CloudGitAgent<AC, ?>,
SC extends AC>
- extends CloudServerRuntimeInstance<DC> {
+ extends CloudServerRuntimeInstance<DC, A, SC> {
private static final Logger LOG = Logger.getInstance("#" + CloudMultiSourceServerRuntimeInstance.class.getName());
- private final A myAgent;
- private final AgentTaskExecutor myAgentTaskExecutor;
-
private final ServerType<?> myServerType;
- private final SC myConfiguration;
- private final ServerTaskExecutor myTasksExecutor;
public CloudMultiSourceServerRuntimeInstance(ServerType<?> serverType,
SC configuration,
@@ -51,20 +44,21 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
String specificJarPath,
Class<A> agentInterface,
String agentClassName) throws Exception {
+ super(configuration,
+ tasksExecutor,
+ libraries,
+ commonJarClasses,
+ specificsModuleName,
+ specificJarPath,
+ agentInterface,
+ agentClassName);
+
myServerType = serverType;
- myConfiguration = configuration;
- myTasksExecutor = tasksExecutor;
-
- RemoteAgentManager agentManager = RemoteAgentManager.getInstance();
- myAgent = agentManager.createAgent(agentManager.createReflectiveThreadProxyFactory(getClass().getClassLoader()),
- libraries,
- commonJarClasses,
- specificsModuleName,
- specificJarPath,
- agentInterface,
- agentClassName,
- getClass());
- myAgentTaskExecutor = new AgentTaskExecutor();
+ }
+
+ @Override
+ public A getAgent() {
+ return super.getAgent();
}
@NotNull
@@ -74,37 +68,37 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
}
public void connect(final ServerConnector.ConnectionCallback<DC> callback) {
- myAgentTaskExecutor.execute(new Computable() {
-
- @Override
- public Object compute() {
- doConnect(myConfiguration,
- new CloudAgentLogger() {
-
- @Override
- public void debugEx(Exception e) {
- LOG.debug(e);
- }
-
- @Override
- public void debug(String message) {
- LOG.debug(message);
- }
- });
- return null;
- }
- }, new CallbackWrapper() {
-
- @Override
- public void onSuccess(Object result) {
- callback.connected(CloudMultiSourceServerRuntimeInstance.this);
- }
-
- @Override
- public void onError(String message) {
- callback.errorOccurred(message);
- }
- }
+ getAgentTaskExecutor().execute(new Computable() {
+
+ @Override
+ public Object compute() {
+ doConnect(getConfiguration(),
+ new CloudAgentLogger() {
+
+ @Override
+ public void debugEx(Exception e) {
+ LOG.debug(e);
+ }
+
+ @Override
+ public void debug(String message) {
+ LOG.debug(message);
+ }
+ });
+ return null;
+ }
+ }, new CallbackWrapper() {
+
+ @Override
+ public void onSuccess(Object result) {
+ callback.connected(CloudMultiSourceServerRuntimeInstance.this);
+ }
+
+ @Override
+ public void onError(String message) {
+ callback.errorOccurred(message);
+ }
+ }
);
}
@@ -112,7 +106,7 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
public void deploy(@NotNull final DeploymentTask<DC> task,
@NotNull final DeploymentLogManager logManager,
@NotNull final ServerRuntimeInstance.DeploymentOperationCallback callback) {
- myTasksExecutor.submit(new ThrowableRunnable<Exception>() {
+ getTaskExecutor().submit(new ThrowableRunnable<Exception>() {
@Override
public void run() throws Exception {
@@ -122,61 +116,16 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
}
@Override
- public void computeDeployments(@NotNull final ServerRuntimeInstance.ComputeDeploymentsCallback callback) {
- myTasksExecutor.submit(new ThrowableRunnable<Exception>() {
- @Override
- public void run() throws Exception {
- myAgentTaskExecutor.execute(new Computable<DeploymentData[]>() {
-
- @Override
- public DeploymentData[] compute() {
- return myAgent.getDeployments();
- }
- },
- new CallbackWrapper<DeploymentData[]>() {
-
- @Override
- public void onSuccess(DeploymentData[] deployments) {
- for (DeploymentData deployment : deployments) {
- callback.addDeployment(deployment.getName());
- }
- callback.succeeded();
- }
-
- @Override
- public void onError(String message) {
- callback.errorOccurred(message);
- }
- }
- );
- }
- }, callback);
- }
-
- @Override
public void disconnect() {
- myTasksExecutor.submit(new Runnable() {
+ getTaskExecutor().submit(new Runnable() {
@Override
public void run() {
- myAgent.disconnect();
+ getAgent().disconnect();
}
});
}
- @Override
- public ServerTaskExecutor getTaskExecutor() {
- return myTasksExecutor;
- }
-
- protected final A getAgent() {
- return myAgent;
- }
-
- protected final AgentTaskExecutor getAgentTaskExecutor() {
- return myAgentTaskExecutor;
- }
-
public CloudDeploymentRuntime createDeploymentRuntime(final DeployToServerRunConfiguration<?, DC> runConfiguration)
throws ServerRuntimeException {
return createDeploymentRuntime(runConfiguration.getDeploymentSource(),
@@ -225,8 +174,9 @@ public abstract class CloudMultiSourceServerRuntimeInstance<
throw new ServerRuntimeException("Unknown deployment source");
}
- public CloudConfigurationBase getConfiguration() {
- return (CloudConfigurationBase)myConfiguration;
+ @Override
+ protected CloudApplicationRuntime createApplicationRuntime(String applicationName) {
+ return new CloudGitApplicationRuntime(this, applicationName, null);
}
protected abstract void doConnect(SC configuration, CloudAgentLogger logger);
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRuntimeTask.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRuntimeTask.java
index 64194856c121..1e0326471d75 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRuntimeTask.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRuntimeTask.java
@@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicReference;
public abstract class CloudRuntimeTask<
T,
DC extends DeploymentConfiguration,
- SR extends CloudServerRuntimeInstance<DC>> {
+ SR extends CloudServerRuntimeInstance<DC, ?, ?>> {
private static final Logger LOG = Logger.getInstance("#" + CloudRuntimeTask.class.getName());
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java
index 89bd2179404a..65bd9066ca3b 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudServerRuntimeInstance.java
@@ -15,14 +15,108 @@
*/
package com.intellij.remoteServer.util;
+import com.intellij.openapi.util.Computable;
+import com.intellij.remoteServer.agent.RemoteAgentManager;
+import com.intellij.remoteServer.agent.util.CloudAgent;
+import com.intellij.remoteServer.agent.util.CloudAgentConfigBase;
+import com.intellij.remoteServer.agent.util.CloudRemoteApplication;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.runtime.ServerTaskExecutor;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
+import com.intellij.util.ThrowableRunnable;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
/**
* @author michael.golubev
*/
-public abstract class CloudServerRuntimeInstance<DC extends DeploymentConfiguration> extends ServerRuntimeInstance<DC> {
+public abstract class CloudServerRuntimeInstance
+ <DC extends DeploymentConfiguration,
+ A extends CloudAgent,
+ SC extends CloudAgentConfigBase>
+ extends ServerRuntimeInstance<DC> {
+
+ private final A myAgent;
+ private final SC myConfiguration;
+ private final ServerTaskExecutor myTasksExecutor;
+
+ private final AgentTaskExecutor myAgentTaskExecutor;
+
+ public CloudServerRuntimeInstance(SC configuration,
+ ServerTaskExecutor tasksExecutor,
+ List<File> libraries,
+ List<Class<?>> commonJarClasses,
+ String specificsModuleName,
+ String specificJarPath,
+ Class<A> agentInterface,
+ String agentClassName) throws Exception {
+ myConfiguration = configuration;
+ myTasksExecutor = tasksExecutor;
+
+ RemoteAgentManager agentManager = RemoteAgentManager.getInstance();
+ myAgent = agentManager.createAgent(agentManager.createReflectiveThreadProxyFactory(getClass().getClassLoader()),
+ libraries,
+ commonJarClasses,
+ specificsModuleName,
+ specificJarPath,
+ agentInterface,
+ agentClassName,
+ getClass());
+
+ myAgentTaskExecutor = new AgentTaskExecutor();
+ }
+
+ public SC getConfiguration() {
+ return myConfiguration;
+ }
+
+ public ServerTaskExecutor getTaskExecutor() {
+ return myTasksExecutor;
+ }
+
+ public A getAgent() {
+ return myAgent;
+ }
+
+ protected final AgentTaskExecutor getAgentTaskExecutor() {
+ return myAgentTaskExecutor;
+ }
+
+ @Override
+ public void computeDeployments(@NotNull final ServerRuntimeInstance.ComputeDeploymentsCallback callback) {
+ getTaskExecutor().submit(new ThrowableRunnable<Exception>() {
+
+ @Override
+ public void run() throws Exception {
+ try {
+ for (CloudApplicationRuntime application : getApplications()) {
+ callback.addDeployment(application.getApplicationName(), application);
+ }
+ callback.succeeded();
+ }
+ catch (ServerRuntimeException e) {
+ callback.errorOccurred(e.getMessage());
+ }
+ }
+ }, callback);
+ }
+
+ private List<CloudApplicationRuntime> getApplications() throws ServerRuntimeException {
+ return getAgentTaskExecutor().execute(new Computable<List<CloudApplicationRuntime>>() {
+
+ @Override
+ public List<CloudApplicationRuntime> compute() {
+ List<CloudApplicationRuntime> result = new ArrayList<CloudApplicationRuntime>();
+ for (CloudRemoteApplication application : getAgent().getApplications()) {
+ result.add(createApplicationRuntime(application.getName()));
+ }
+ return result;
+ }
+ });
+ }
- public abstract ServerTaskExecutor getTaskExecutor();
+ protected abstract CloudApplicationRuntime createApplicationRuntime(String applicationName);
}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/HasUrl.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/HasUrl.java
new file mode 100644
index 000000000000..56f51c5d6d51
--- /dev/null
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/HasUrl.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.debugger;
+
+import com.intellij.util.Url;
+import org.jetbrains.annotations.NotNull;
+
+
+public interface HasUrl {
+ @NotNull
+ Url getUrl();
+}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/Script.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/Script.java
index 354a51387a50..e44d308977d3 100755
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/Script.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/Script.java
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.sourcemap.SourceMap;
-public interface Script extends UserDataHolderEx {
+public interface Script extends UserDataHolderEx, HasUrl {
void setSourceMap(SourceMap sourceMap);
enum Type {
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java
index 76157af7b808..c16ffe5d4b81 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java
@@ -19,13 +19,10 @@ public interface ScriptManager {
boolean containsScript(Script script);
/**
- * Demands that script text should be replaced with a new one if possible. VM may get resumed
- * after this command (this is defined by {@link ChangeDescription#isStackModified()}). In this
- * case a standard 'suspended' notification is expected in a moment.
- *
- * @param newSource new text of script
+ * Demands that script text should be replaced with a new one if possible. VM may get resumed after this command
*/
- AsyncResult<?> setSourceOnRemote(@NotNull Script script, @NotNull String newSource, boolean preview);
+ @NotNull
+ AsyncResult<?> setSourceOnRemote(@NotNull Script script, @NotNull CharSequence newSource, boolean preview);
void forEachScript(@NotNull Processor<Script> scriptProcessor);
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java
index dc452a2b7b64..e9ac90a7d023 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java
@@ -13,7 +13,7 @@ public interface ValueModifier {
// it works quickly and we don't want to complicate our code and debugger SDK
ActionCallback setValue(@NotNull Variable variable, String newValue, @NotNull EvaluateContext evaluateContext);
- ActionCallback setValue(@NotNull Variable variable, Value newValue, @NotNull EvaluateContext evaluateContext);
+ ActionCallback setValue(@NotNull Variable variable, @NotNull Value newValue, @NotNull EvaluateContext evaluateContext);
@NotNull
AsyncResult<Value> evaluateGet(@NotNull Variable variable, @NotNull EvaluateContext evaluateContext);
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifierUtil.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifierUtil.java
index b5edb7fa3282..d71261c5286b 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifierUtil.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifierUtil.java
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.values.Value;
+import org.jetbrains.io.JsonUtil;
import java.util.Collections;
import java.util.List;
@@ -12,21 +13,6 @@ import java.util.regex.Pattern;
public final class ValueModifierUtil {
private static final Pattern KEY_NOTATION_PROPERTY_NAME_PATTERN = Pattern.compile("[\\p{L}_$]+[\\d\\p{L}_$]*");
- private static final String[] REPLACEMENT_CHARS;
-
- static {
- REPLACEMENT_CHARS = new String[128];
- for (int i = 0; i <= 31; i++) {
- REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int)i);
- }
- REPLACEMENT_CHARS['"'] = "\\\"";
- REPLACEMENT_CHARS['\\'] = "\\\\";
- REPLACEMENT_CHARS['\t'] = "\\t";
- REPLACEMENT_CHARS['\b'] = "\\b";
- REPLACEMENT_CHARS['\n'] = "\\n";
- REPLACEMENT_CHARS['\r'] = "\\r";
- REPLACEMENT_CHARS['\f'] = "\\f";
- }
public static ActionCallback setValue(@NotNull final Variable variable, String newValue, @NotNull final EvaluateContext evaluateContext, @NotNull final ValueModifier modifier) {
final ActionCallback callback = new ActionCallback();
@@ -77,44 +63,9 @@ public final class ValueModifierUtil {
builder.append(name);
}
else {
- escape(name, builder);
+ JsonUtil.escape(name, builder);
}
builder.append(']');
}
}
-
- public static void escape(CharSequence value, StringBuilder sb) {
- int length = value.length();
- sb.ensureCapacity(sb.capacity() + length + 2);
- sb.append('"');
- int last = 0;
- for (int i = 0; i < length; i++) {
- char c = value.charAt(i);
- String replacement;
- if (c < 128) {
- replacement = REPLACEMENT_CHARS[c];
- if (replacement == null) {
- continue;
- }
- }
- else if (c == '\u2028') {
- replacement = "\\u2028";
- }
- else if (c == '\u2029') {
- replacement = "\\u2029";
- }
- else {
- continue;
- }
- if (last < i) {
- sb.append(value, last, i);
- }
- sb.append(replacement);
- last = i + 1;
- }
- if (last < length) {
- sb.append(value, last, length);
- }
- sb.append('"');
- }
} \ No newline at end of file
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java
index e97386f90614..5d5aa818bcd5 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java
@@ -42,6 +42,15 @@ public abstract class MappingList {
return middle;
}
else if (column < getColumn(mapping)) {
+ if (column == 0 || column == -1) {
+ // find first
+ int firstIndex = middle;
+ while (firstIndex > 0 && getLine(mappings.get(firstIndex - 1)) == line) {
+ firstIndex--;
+ }
+ return firstIndex;
+ }
+
if (middle == 0) {
return -1;
}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/PrimitiveValue.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/PrimitiveValue.java
index 12655e4ba921..f03565f2defa 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/PrimitiveValue.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/PrimitiveValue.java
@@ -4,6 +4,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PrimitiveValue extends ValueBase {
+ public static final PrimitiveValue NULL_VALUE = new PrimitiveValue(ValueType.NULL, "null");
+ public static final PrimitiveValue UNDEFINED_VALUE = new PrimitiveValue(ValueType.UNDEFINED, "undefined");
+
private final String valueString;
public PrimitiveValue(@NotNull ValueType type, @NotNull String valueString) {
diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandCallbackWithResponseBase.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandCallbackWithResponseBase.java
index a0889cfc6ce6..aad3023ad340 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandCallbackWithResponseBase.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandCallbackWithResponseBase.java
@@ -20,8 +20,8 @@ abstract class CommandCallbackWithResponseBase<SUCCESS_RESPONSE, C extends Actio
onSuccess(resultReader.<RESULT>readResult(methodName, response));
}
catch (Throwable e) {
- callback.reject(e.getMessage());
MessageManager.LOG.error(e);
+ callback.reject(e.getMessage());
}
}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java
index b014cbefacf8..8df0824db5ae 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java
@@ -26,6 +26,11 @@ public interface CommandSender<ERROR_DETAILS> {
@NotNull RequestWithResponse message,
@NotNull PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer);
+ <RESULT, MAIN_RESULT> AsyncResult<MAIN_RESULT> send(@NotNull AsyncResult<MAIN_RESULT> result,
+ @NotNull RequestWithResponse message,
+ @NotNull PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer,
+ @Nullable ErrorConsumer<AsyncResult<MAIN_RESULT>, ERROR_DETAILS> errorConsumer);
+
<RESULT, MAIN_RESULT> AsyncResult<MAIN_RESULT> send(@NotNull RequestWithResponse message,
@NotNull PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer);
} \ No newline at end of file
diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageHandler.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageHandler.java
index fb6cabb9a577..1b87843c7168 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageHandler.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageHandler.java
@@ -2,7 +2,6 @@ package org.jetbrains.rpc;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.AsyncResult;
-import com.intellij.util.BooleanFunction;
import com.intellij.util.Function;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.NotNull;
@@ -17,10 +16,7 @@ public abstract class MessageHandler<INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPON
private final AtomicInteger currentSequence = new AtomicInteger();
protected final MessageManager<Request, INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPONSE, ERROR_DETAILS> messageManager;
- private final BooleanFunction<Request> out;
-
- protected MessageHandler(@NotNull BooleanFunction<Request> out) {
- this.out = out;
+ protected MessageHandler() {
messageManager = new MessageManager<Request, INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPONSE, ERROR_DETAILS>(this);
}
@@ -33,11 +29,6 @@ public abstract class MessageHandler<INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPON
}
@Override
- public boolean write(@NotNull Request message) {
- return out.fun(message);
- }
-
- @Override
public final int getUpdatedSequence(Request message) {
int id = currentSequence.incrementAndGet();
message.finalize(id);
@@ -83,7 +74,16 @@ public abstract class MessageHandler<INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPON
public final <RESULT, TRANSFORMED_RESULT> AsyncResult<TRANSFORMED_RESULT> send(@NotNull AsyncResult<TRANSFORMED_RESULT> result,
@NotNull RequestWithResponse message,
@NotNull PairConsumer<RESULT, AsyncResult<TRANSFORMED_RESULT>> consumer) {
- messageManager.send(message, new NestedCommandCallbackWithResponse<SUCCESS_RESPONSE, RESULT, TRANSFORMED_RESULT, ERROR_DETAILS>(result, message.getMethodName(), consumer));
+ messageManager.send(message, new NestedCommandCallbackWithResponse<SUCCESS_RESPONSE, RESULT, TRANSFORMED_RESULT, ERROR_DETAILS>(result, message.getMethodName(), consumer, null));
+ return result;
+ }
+
+ @Override
+ public final <RESULT, TRANSFORMED_RESULT> AsyncResult<TRANSFORMED_RESULT> send(@NotNull AsyncResult<TRANSFORMED_RESULT> result,
+ @NotNull RequestWithResponse message,
+ @NotNull PairConsumer<RESULT, AsyncResult<TRANSFORMED_RESULT>> consumer,
+ @Nullable ErrorConsumer<AsyncResult<TRANSFORMED_RESULT>, ERROR_DETAILS> errorConsumer) {
+ messageManager.send(message, new NestedCommandCallbackWithResponse<SUCCESS_RESPONSE, RESULT, TRANSFORMED_RESULT, ERROR_DETAILS>(result, message.getMethodName(), consumer, errorConsumer));
return result;
}
} \ No newline at end of file
diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/NestedCommandCallbackWithResponse.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/NestedCommandCallbackWithResponse.java
index ee5640ce91d9..d089bda2b0e5 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/rpc/NestedCommandCallbackWithResponse.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/NestedCommandCallbackWithResponse.java
@@ -2,13 +2,14 @@ package org.jetbrains.rpc;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.PairConsumer;
+import org.jetbrains.annotations.Nullable;
final class NestedCommandCallbackWithResponse<SUCCESS_RESPONSE, RESULT, MAIN_RESULT, ERROR_DETAILS>
extends CommandCallbackWithResponseBase<SUCCESS_RESPONSE, AsyncResult<MAIN_RESULT>, RESULT, ERROR_DETAILS> {
private final PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer;
- public NestedCommandCallbackWithResponse(AsyncResult<MAIN_RESULT> result, String methodName, PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer) {
- super(result, methodName, null);
+ public NestedCommandCallbackWithResponse(AsyncResult<MAIN_RESULT> result, String methodName, PairConsumer<RESULT, AsyncResult<MAIN_RESULT>> consumer, @Nullable ErrorConsumer<AsyncResult<MAIN_RESULT>, ERROR_DETAILS> errorConsumer) {
+ super(result, methodName, errorConsumer);
this.consumer = consumer;
}
diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java
index 0aff6f3a8511..53fa54a3e9c3 100644
--- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java
+++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.java
@@ -100,4 +100,10 @@ public class BasicDebuggerViewSupport implements DebuggerViewSupport, MemberFilt
public String normalizeMemberName(@NotNull Variable variable) {
return variable.getName();
}
+
+ @Override
+ @Nullable
+ public Value transformErrorOnGetUsedReferenceValue(@Nullable Value value, @Nullable String error) {
+ return value;
+ }
} \ No newline at end of file
diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.java
index 3070bd326858..cf24d062cada 100644
--- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.java
+++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.java
@@ -53,4 +53,7 @@ public interface DebuggerViewSupport {
@NotNull
String normalizeMemberName(@NotNull Variable variable);
+
+ @Nullable
+ Value transformErrorOnGetUsedReferenceValue(@Nullable Value value, @Nullable String error);
} \ No newline at end of file
diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java
index 5b9e67113c62..352b67351f63 100644
--- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java
+++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java
@@ -150,11 +150,27 @@ public final class VariableView extends XNamedValue implements VariableContext {
if (!(variable instanceof ObjectProperty) || ((ObjectProperty)variable).getGetter() == null) {
// it is "used" expression (WEB-6779 Debugger/Variables: Automatically show used variables)
- ObsolescentAsyncResults.consume(getEvaluateContext().evaluate(variable.getName()), node, new PairConsumer<Value, XValueNode>() {
+ getEvaluateContext().evaluate(variable.getName()).doWhenDone(new Consumer<Value>() {
@Override
- public void consume(Value value, XValueNode node) {
- VariableView.this.value = value;
- computePresentation(value, node);
+ public void consume(Value value) {
+ if (!node.isObsolete()) {
+ VariableView.this.value = value;
+ computePresentation(value, node);
+ }
+ }
+ }).doWhenRejected(new PairConsumer<Value, String>() {
+ @Override
+ public void consume(Value value, String error) {
+ if (!node.isObsolete()) {
+ value = getViewSupport().transformErrorOnGetUsedReferenceValue(value, error);
+ if (value == null) {
+ node.setPresentation(getIcon(), null, error, false);
+ }
+ else {
+ VariableView.this.value = value;
+ computePresentation(value, node);
+ }
+ }
}
});
return;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonUtil.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonUtil.java
index 5d91638f0ef7..ebc46a882d57 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonUtil.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonUtil.java
@@ -2,6 +2,7 @@ package org.jetbrains.io;
import com.intellij.util.SmartList;
import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -9,6 +10,57 @@ import java.util.List;
import java.util.Map;
public class JsonUtil {
+ private static final String[] REPLACEMENT_CHARS;
+
+ static {
+ REPLACEMENT_CHARS = new String[128];
+ for (int i = 0; i <= 31; i++) {
+ REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int)i);
+ }
+ REPLACEMENT_CHARS['"'] = "\\\"";
+ REPLACEMENT_CHARS['\\'] = "\\\\";
+ REPLACEMENT_CHARS['\t'] = "\\t";
+ REPLACEMENT_CHARS['\b'] = "\\b";
+ REPLACEMENT_CHARS['\n'] = "\\n";
+ REPLACEMENT_CHARS['\r'] = "\\r";
+ REPLACEMENT_CHARS['\f'] = "\\f";
+ }
+
+ public static void escape(@NotNull CharSequence value, @NotNull StringBuilder sb) {
+ int length = value.length();
+ sb.ensureCapacity(sb.capacity() + length + 2);
+ sb.append('"');
+ int last = 0;
+ for (int i = 0; i < length; i++) {
+ char c = value.charAt(i);
+ String replacement;
+ if (c < 128) {
+ replacement = REPLACEMENT_CHARS[c];
+ if (replacement == null) {
+ continue;
+ }
+ }
+ else if (c == '\u2028') {
+ replacement = "\\u2028";
+ }
+ else if (c == '\u2029') {
+ replacement = "\\u2029";
+ }
+ else {
+ continue;
+ }
+ if (last < i) {
+ sb.append(value, last, i);
+ }
+ sb.append(replacement);
+ last = i + 1;
+ }
+ if (last < length) {
+ sb.append(value, last, length);
+ }
+ sb.append('"');
+ }
+
public static <T> List<T> nextList(JsonReaderEx reader) {
reader.beginArray();
if (!reader.hasNext()) {
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
index a0c85a33eab2..aa1d19f1bad2 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
@@ -6,6 +6,7 @@ import gnu.trove.TDoubleArrayList;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
import gnu.trove.TLongArrayList;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.io.JsonReaderEx;
import java.util.ArrayList;
@@ -103,12 +104,12 @@ public final class JsonReaders {
}
}
- public static String convertRawEnumName(String enumValue) {
+ public static String convertRawEnumName(@NotNull String enumValue) {
StringBuilder builder = new StringBuilder(enumValue.length() + 4);
boolean prevIsLowerCase = false;
for (int i = 0; i < enumValue.length(); i++) {
char c = enumValue.charAt(i);
- if (c == '-') {
+ if (c == '-' || c == ' ') {
builder.append('_');
continue;
}
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.java
index be4cfccad15c..7381eea575f3 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/OutMessage.java
@@ -5,13 +5,14 @@ import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.io.JsonUtil;
import java.io.IOException;
-import java.io.StringWriter;
import java.util.List;
import java.util.Map;
public abstract class OutMessage {
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private final StringWriter stringWriter = new StringWriter();
public final JsonWriter writer = new JsonWriter(stringWriter);
@@ -149,7 +150,7 @@ public abstract class OutMessage {
}
}
- protected final void writeSingletonIntArray(@NotNull String name, @NotNull int value) {
+ protected final void writeSingletonIntArray(@NotNull String name, int value) {
try {
beginArguments();
writer.name(name);
@@ -180,7 +181,7 @@ public abstract class OutMessage {
isNotFirst = true;
}
- StringBuffer buffer = item.stringWriter.getBuffer();
+ StringBuilder buffer = item.stringWriter.getBuffer();
if (!item.finalized) {
item.finalized = true;
try {
@@ -217,7 +218,7 @@ public abstract class OutMessage {
public static void prepareWriteRaw(OutMessage message, String name) throws IOException {
message.writer.name(name).nullValue();
- StringBuffer myBuffer = message.stringWriter.getBuffer();
+ StringBuilder myBuffer = message.stringWriter.getBuffer();
myBuffer.delete(myBuffer.length() - "null".length(), myBuffer.length());
}
@@ -230,7 +231,7 @@ public abstract class OutMessage {
beginArguments();
prepareWriteRaw(this, name);
- StringBuffer buffer = value.stringWriter.getBuffer();
+ StringBuilder buffer = value.stringWriter.getBuffer();
if (!value.finalized) {
value.close();
}
@@ -284,6 +285,18 @@ public abstract class OutMessage {
}
}
+ protected final void writeString(String name, CharSequence value) {
+ if (value != null) {
+ try {
+ prepareWriteRaw(this, name);
+ JsonUtil.escape(value, stringWriter.getBuffer());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
protected final void writeNullableString(String name, String value) {
try {
beginArguments();
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/StringWriter.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/StringWriter.java
new file mode 100644
index 000000000000..e72b2e291b26
--- /dev/null
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/StringWriter.java
@@ -0,0 +1,81 @@
+package org.jetbrains.jsonProtocol;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class StringWriter extends Writer {
+ private final StringBuilder builder;
+
+ public StringWriter() {
+ builder = new StringBuilder();
+ lock = builder;
+ }
+
+ public StringWriter(int initialSize) {
+ if (initialSize < 0) {
+ throw new IllegalArgumentException("Negative buffer size");
+ }
+
+ builder = new StringBuilder(initialSize);
+ lock = builder;
+ }
+
+ @Override
+ public void write(int c) {
+ builder.append((char)c);
+ }
+
+ @Override
+ public void write(@NotNull char[] chars, int off, int len) {
+ builder.append(chars, off, len);
+ }
+
+ @Override
+ public void write(@NotNull String string) {
+ builder.append(string);
+ }
+
+ @Override
+ public void write(@NotNull String str, int off, int length) {
+ builder.append(str, off, off + length);
+ }
+
+ @Override
+ public StringWriter append(CharSequence charSequence) {
+ builder.append(charSequence);
+ return this;
+ }
+
+ @Override
+ public StringWriter append(CharSequence charSequence, int start, int end) {
+ builder.append(charSequence, start, end);
+ return this;
+ }
+
+ @Override
+ public StringWriter append(char c) {
+ write(c);
+ return this;
+ }
+
+ public String toString() {
+ return builder.toString();
+ }
+
+ public StringBuilder getBuffer() {
+ return builder;
+ }
+
+ /**
+ * Flush the stream.
+ */
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+} \ No newline at end of file
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
index 92a3a6bf0c78..eabc8d8e4337 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
@@ -60,9 +60,23 @@ class FieldProcessor<T> {
private MethodHandler processFieldGetterMethod(Method m, String fieldName) {
Type genericReturnType = m.getGenericReturnType();
- boolean nullable = m.getAnnotation(JsonNullable.class) != null ||
- (genericReturnType == String.class && ((m.getAnnotation(JsonField.class) != null && m.getAnnotation(JsonField.class).optional())
- || m.getAnnotation(JsonOptionalField.class) != null));
+ boolean nullable;
+ if (m.getAnnotation(JsonNullable.class) != null) {
+ nullable = true;
+ }
+ else if (genericReturnType == String.class || genericReturnType == Enum.class) {
+ JsonField jsonField = m.getAnnotation(JsonField.class);
+ if (jsonField != null) {
+ nullable = jsonField.optional() && !jsonField.allowAnyPrimitiveValue() && !jsonField.allowAnyPrimitiveValueAndMap();
+ }
+ else {
+ nullable = m.getAnnotation(JsonOptionalField.class) != null;
+ }
+ }
+ else {
+ nullable = false;
+ }
+
ValueReader fieldTypeParser = reader.getFieldTypeParser(genericReturnType, nullable, false, m);
if (fieldTypeParser != InterfaceReader.VOID_PARSER) {
fieldLoaders.add(new FieldLoader(fieldName, fieldTypeParser));
diff --git a/platform/smRunner/testSrc/com/intellij/internal/statistic/beans/ConvertUsagesUtilTest.java b/platform/smRunner/testSrc/com/intellij/internal/statistic/beans/ConvertUsagesUtilTest.java
new file mode 100644
index 000000000000..976fb293fcaa
--- /dev/null
+++ b/platform/smRunner/testSrc/com/intellij/internal/statistic/beans/ConvertUsagesUtilTest.java
@@ -0,0 +1,12 @@
+package com.intellij.internal.statistic.beans;
+
+import junit.framework.TestCase;
+
+public class ConvertUsagesUtilTest extends TestCase {
+
+ public void testEscapeDescriptorName() throws Exception {
+ ConvertUsagesUtil.assertDescriptorName(ConvertUsagesUtil.escapeDescriptorName("'Copy'_on_Steroids"));
+ ConvertUsagesUtil.assertDescriptorName(ConvertUsagesUtil.escapeDescriptorName("Some config name"));
+ ConvertUsagesUtil.assertDescriptorName(ConvertUsagesUtil.escapeDescriptorName("\"config\""));
+ }
+} \ No newline at end of file
diff --git a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
index 81ddd327a275..b3811750841d 100644
--- a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
+++ b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
@@ -54,17 +54,18 @@ public class GroupBasedTestClassFilter extends TestClassesFilter {
private final Map<String, List<Pattern>> myPatterns = new HashMap<String, List<Pattern>>();
private final List<Pattern> myAllPatterns = new ArrayList<Pattern>();
private final List<Pattern> myTestGroupPatterns;
- private final String myTestGroupName;
+ private boolean myAllExcludeDefinedGroup;
private GroupBasedTestClassFilter(Map<String, List<String>> filters, String testGroupName) {
- myTestGroupName = testGroupName;
+ //empty group means all patterns from each defined group should be excluded
+ myAllExcludeDefinedGroup = isAllExcludeDefinedGroup(testGroupName);
for (String groupName : filters.keySet()) {
List<String> filterList = filters.get(groupName);
addPatterns(groupName, filterList);
}
- myTestGroupPatterns = collectPatternsFor(myTestGroupName);
+ myTestGroupPatterns = collectPatternsFor(testGroupName);
}
private void addPatterns(String groupName, List<String> filterList) {
@@ -157,8 +158,7 @@ public class GroupBasedTestClassFilter extends TestClassesFilter {
@Override
public boolean matches(String className) {
boolean result = matchesAnyPattern(myTestGroupPatterns, className);
- //null group means all patterns from each defined group should be excluded
- if (isAllExcludeDefinedGroup(myTestGroupName)) {
+ if (myAllExcludeDefinedGroup) {
return !result;
}
else {
diff --git a/platform/testFramework/src/com/intellij/TestAll.java b/platform/testFramework/src/com/intellij/TestAll.java
index d827982ba31e..626cf12dbe12 100644
--- a/platform/testFramework/src/com/intellij/TestAll.java
+++ b/platform/testFramework/src/com/intellij/TestAll.java
@@ -28,7 +28,7 @@ import com.intellij.idea.RecordExecution;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.testFramework.*;
import com.intellij.tests.ExternalClasspathClassLoader;
import com.intellij.util.ArrayUtil;
@@ -44,25 +44,14 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
-@SuppressWarnings({"HardCodedStringLiteral", "CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"})
+@SuppressWarnings({"HardCodedStringLiteral", "CallToPrintStackTrace", "UseOfSystemOutOrSystemErr", "TestOnlyProblems", "BusyWait"})
public class TestAll implements Test {
static {
Logger.setFactory(TestLoggerFactory.class);
}
- private final TestCaseLoader myTestCaseLoader;
- private long myStartTime = 0;
- private boolean myInterruptedByOutOfTime = false;
- private long myLastTestStartTime = 0;
- private String myLastTestClass;
- private int myRunTests = -1;
- private boolean mySavingMemorySnapshot;
-
private static final int SAVE_MEMORY_SNAPSHOT = 1;
private static final int START_GUARD = 2;
private static final int RUN_GC = 4;
@@ -70,11 +59,10 @@ public class TestAll implements Test {
private static final int FILTER_CLASSES = 16;
public static int ourMode = SAVE_MEMORY_SNAPSHOT /*| START_GUARD | RUN_GC | CHECK_MEMORY*/ | FILTER_CLASSES;
+
private static final boolean PERFORMANCE_TESTS_ONLY = System.getProperty(TestCaseLoader.PERFORMANCE_TESTS_ONLY_FLAG) != null;
- private int myLastTestTestMethodCount = 0;
- public static final int MAX_FAILURE_TEST_COUNT = 150;
- private TestRecorder myTestRecorder;
+ private static final int MAX_FAILURE_TEST_COUNT = 150;
private static final Filter PERFORMANCE_ONLY = new Filter() {
@Override
@@ -103,18 +91,98 @@ public class TestAll implements Test {
}
};
+ private final TestCaseLoader myTestCaseLoader;
+ private long myStartTime = 0;
+ private boolean myInterruptedByOutOfTime = false;
+ private long myLastTestStartTime = 0;
+ private String myLastTestClass;
+ private int myRunTests = -1;
+ private boolean mySavingMemorySnapshot;
+ private int myLastTestTestMethodCount = 0;
+ private TestRecorder myTestRecorder;
+
+ public TestAll(String packageRoot) throws Throwable {
+ this(packageRoot, getClassRoots());
+ }
+
+ public TestAll(String packageRoot, String... classRoots) throws IOException, ClassNotFoundException {
+ String classFilterName = "tests/testGroups.properties";
+ if (Boolean.getBoolean("idea.ignore.predefined.groups") || (ourMode & FILTER_CLASSES) == 0) {
+ classFilterName = "";
+ }
+
+ myTestCaseLoader = new TestCaseLoader(classFilterName, isPerformanceTestsRun());
+ myTestCaseLoader.addFirstTest(Class.forName("_FirstInSuiteTest"));
+ myTestCaseLoader.addLastTest(Class.forName("_LastInSuiteTest"));
+ fillTestCases(myTestCaseLoader, packageRoot, classRoots);
+ }
+
+ public static String[] getClassRoots() {
+ String testRoots = System.getProperty("test.roots");
+ if (testRoots != null) {
+ System.out.println("Collecting tests from roots specified by test.roots property: " + testRoots);
+ return testRoots.split(";");
+ }
+ String[] roots = ExternalClasspathClassLoader.getRoots();
+ if (roots != null) {
+ if (Comparing.equal(System.getProperty(TestCaseLoader.SKIP_COMMUNITY_TESTS), "true")) {
+ System.out.println("Skipping community tests");
+ Set<String> set = normalizePaths(roots);
+ set.removeAll(normalizePaths(ExternalClasspathClassLoader.getExcludeRoots()));
+ roots = ArrayUtil.toStringArray(set);
+ }
+
+ System.out.println("Collecting tests from roots specified by classpath.file property: " + Arrays.toString(roots));
+ return roots;
+ }
+ else {
+ final ClassLoader loader = TestAll.class.getClassLoader();
+ if (loader instanceof URLClassLoader) {
+ final URL[] urls = ((URLClassLoader)loader).getURLs();
+ final String[] classLoaderRoots = new String[urls.length];
+ for (int i = 0; i < urls.length; i++) {
+ classLoaderRoots[i] = VfsUtilCore.urlToPath(VfsUtilCore.convertFromUrl(urls[i]));
+ }
+ System.out.println("Collecting tests from " + Arrays.toString(classLoaderRoots));
+ return classLoaderRoots;
+ }
+ return System.getProperty("java.class.path").split(File.pathSeparator);
+ }
+ }
+
+ private static Set<String> normalizePaths(String[] array) {
+ Set<String> answer = new LinkedHashSet<String>(array.length);
+ for (String path : array) {
+ answer.add(path.replace('\\', '/'));
+ }
+ return answer;
+ }
+
+ public static void fillTestCases(TestCaseLoader testCaseLoader, String packageRoot, String... classRoots) throws IOException {
+ for (String classRoot : classRoots) {
+ int oldCount = testCaseLoader.getClasses().size();
+ ClassFinder classFinder = new ClassFinder(new File(FileUtil.toSystemDependentName(classRoot)), packageRoot);
+ testCaseLoader.loadTestCases(classFinder.getClasses());
+ int newCount = testCaseLoader.getClasses().size();
+ if (newCount != oldCount) {
+ System.out.println("Loaded " + (newCount - oldCount) + " tests from class root " + classRoot);
+ }
+ }
+
+ if (testCaseLoader.getClasses().size() == 1) {
+ testCaseLoader.clearClasses();
+ }
+
+ log("Number of test classes found: " + testCaseLoader.getClasses().size());
+ }
+
@Override
public int countTestCases() {
- List<Class> classes = myTestCaseLoader.getClasses();
-
int count = 0;
-
- for (final Object aClass : classes) {
- Class testCaseClass = (Class)aClass;
- Test test = getTest(testCaseClass);
+ for (Object aClass : myTestCaseLoader.getClasses()) {
+ Test test = getTest((Class)aClass);
if (test != null) count += test.countTestCases();
}
-
return count;
}
@@ -190,12 +258,13 @@ public class TestAll implements Test {
@Override
public void run(final TestResult testResult) {
loadTestRecorder();
+
List<Class> classes = myTestCaseLoader.getClasses();
int totalTests = classes.size();
- for (final Class aClass : classes) {
+ for (Class<?> aClass : classes) {
boolean recording = false;
if (myTestRecorder != null && shouldRecord(aClass)) {
- myTestRecorder.beginRecording(aClass, (RecordExecution) aClass.getAnnotation(RecordExecution.class));
+ myTestRecorder.beginRecording(aClass, aClass.getAnnotation(RecordExecution.class));
recording = true;
}
try {
@@ -208,14 +277,12 @@ public class TestAll implements Test {
}
if (testResult.shouldStop()) break;
}
+
tryGc(10);
}
- private boolean shouldRecord(Class aClass) {
- if (aClass.getAnnotation(RecordExecution.class) != null) {
- return true;
- }
- return false;
+ private static boolean shouldRecord(Class<?> aClass) {
+ return aClass.getAnnotation(RecordExecution.class) != null;
}
private void loadTestRecorder() {
@@ -225,53 +292,43 @@ public class TestAll implements Test {
Class<?> recorderClass = Class.forName(recorderClassName);
myTestRecorder = (TestRecorder) recorderClass.newInstance();
}
- catch (ClassNotFoundException e) {
- System.out.println("CNFE loading test recorder class: " + e);
- }
- catch (InstantiationException e) {
- System.out.println("InstantiationException loading test recorder class: " + e);
- }
- catch (IllegalAccessException e) {
- System.out.println("IAE loading test recorder class: " + e);
+ catch (Exception e) {
+ System.out.println("Error loading test recorder class '" + recorderClassName + "': " + e);
}
}
}
private void runNextTest(final TestResult testResult, int totalTests, Class testCaseClass) {
myRunTests++;
- if (!checkAvaliableMemory(35, testResult)) {
+ if (!checkAvailableMemory(35, testResult)) {
testResult.stop();
return;
}
+
if (testResult.errorCount() + testResult.failureCount() > MAX_FAILURE_TEST_COUNT) {
- addErrorMessage(testResult, "Too many errors. Tests stopped. Total " + myRunTests + " of " + totalTests + " tests run");
+ addErrorMessage(testResult, "Too many errors. Executed: " + myRunTests + " of " + totalTests);
testResult.stop();
return;
}
+
if (myStartTime == 0) {
- boolean ourClassLoader = getClass().getClassLoader().getClass().getName().startsWith("com.intellij.");
- if (!ourClassLoader) {
+ String loaderName = getClass().getClassLoader().getClass().getName();
+ if (!loaderName.startsWith("com.intellij.")) {
beforeFirstTest();
}
}
else {
if (myInterruptedByOutOfTime) {
- addErrorMessage(testResult,
- "Current Test Interrupted: OUT OF TIME! Class = " + myLastTestClass + " Total " + myRunTests + " of " +
- totalTests +
- " tests run");
+ addErrorMessage(testResult, "Time out in " + myLastTestClass + ". Executed: " + myRunTests + " of " + totalTests);
testResult.stop();
return;
}
}
log("\nRunning " + testCaseClass.getName());
- final Test test = getTest(testCaseClass);
-
+ Test test = getTest(testCaseClass);
if (test == null) return;
- myLastTestClass = null;
-
myLastTestClass = testCaseClass.getName();
myLastTestStartTime = System.currentTimeMillis();
myLastTestTestMethodCount = test.countTestCases();
@@ -279,24 +336,25 @@ public class TestAll implements Test {
try {
test.run(testResult);
}
- catch (Throwable t) {
- if (t instanceof OutOfMemoryError) {
- if ((ourMode & SAVE_MEMORY_SNAPSHOT) != 0) {
- try {
- mySavingMemorySnapshot = true;
- log("OutOfMemoryError detected. Saving memory snapshot started");
- }
- finally {
- log("Saving memory snapshot finished");
- mySavingMemorySnapshot = false;
- }
+ catch (OutOfMemoryError t) {
+ if ((ourMode & SAVE_MEMORY_SNAPSHOT) != 0) {
+ try {
+ mySavingMemorySnapshot = true;
+ log("OutOfMemoryError detected. Saving memory snapshot started");
+ }
+ finally {
+ log("Saving memory snapshot finished");
+ mySavingMemorySnapshot = false;
}
}
testResult.addError(test, t);
}
+ catch (Throwable t) {
+ testResult.addError(test, t);
+ }
}
- private boolean checkAvaliableMemory(int neededMemory, TestResult testResult) {
+ private boolean checkAvailableMemory(int neededMemory, TestResult testResult) {
if ((ourMode & CHECK_MEMORY) == 0) return true;
boolean possibleOutOfMemoryError = possibleOutOfMemory(neededMemory);
@@ -349,9 +407,7 @@ public class TestAll implements Test {
try {
adapter.filter(isPerformanceTestsRun() ? PERFORMANCE_ONLY : NO_PERFORMANCE);
}
- catch (NoTestsRemainException e1) {
- // Ignore
- }
+ catch (NoTestsRemainException ignored) { }
}
return adapter;
}
@@ -391,11 +447,11 @@ public class TestAll implements Test {
}
private static boolean hasPerformance(String name) {
- return name.toLowerCase().contains("performance");
+ return name.toLowerCase(Locale.US).contains("performance");
}
@Nullable
- private static Method safeFindMethod(Class klass, String name) {
+ private static Method safeFindMethod(Class<?> klass, String name) {
try {
return klass.getMethod(name);
}
@@ -404,100 +460,25 @@ public class TestAll implements Test {
}
}
- private static Set<String> normalizePaths(String[] array) {
- Set<String> answer = new LinkedHashSet<String>(array.length);
- for (String path : array) {
- answer.add(path.replace('\\', '/'));
- }
- return answer;
- }
-
- public static String[] getClassRoots() {
- String testRoots = System.getProperty("test.roots");
- if (testRoots != null) {
- System.out.println("Collecting tests from roots specified by test.roots property: " + testRoots);
- return testRoots.split(";");
- }
- String[] roots = ExternalClasspathClassLoader.getRoots();
- if (roots != null) {
- if (Comparing.equal(System.getProperty(TestCaseLoader.SKIP_COMMUNITY_TESTS), "true")) {
- System.out.println("Skipping community tests");
- Set<String> set = normalizePaths(roots);
- set.removeAll(normalizePaths(ExternalClasspathClassLoader.getExcludeRoots()));
- roots = set.toArray(new String[set.size()]);
- }
-
- System.out.println("Collecting tests from roots specified by classpath.file property: " + Arrays.toString(roots));
- return roots;
- }
- else {
- final ClassLoader loader = TestAll.class.getClassLoader();
- if (loader instanceof URLClassLoader) {
- final URL[] urls = ((URLClassLoader)loader).getURLs();
- final String[] classLoaderRoots = new String[urls.length];
- for (int i = 0; i < urls.length; i++) {
- classLoaderRoots[i] = VfsUtil.urlToPath(VfsUtil.convertFromUrl(urls[i]));
- }
- System.out.println("Collecting tests from classloader: " + Arrays.toString(classLoaderRoots));
- return classLoaderRoots;
- }
- return System.getProperty("java.class.path").split(File.pathSeparator);
- }
- }
-
- public TestAll(String packageRoot) throws Throwable {
- this(packageRoot, getClassRoots());
- }
-
- public TestAll(String packageRoot, String... classRoots) throws IOException, ClassNotFoundException {
- String classFilterName = "tests/testGroups.properties";
- if (Boolean.parseBoolean(System.getProperty("idea.ignore.predefined.groups")) || (ourMode & FILTER_CLASSES) == 0) {
- classFilterName = "";
- }
- myTestCaseLoader = new TestCaseLoader(classFilterName, isPerformanceTestsRun());
- myTestCaseLoader.addFirstTest(Class.forName("_FirstInSuiteTest"));
- myTestCaseLoader.addLastTest(Class.forName("_LastInSuiteTest"));
-
- fillTestCases(myTestCaseLoader, packageRoot, classRoots);
- }
-
- public static void fillTestCases(TestCaseLoader testCaseLoader, String packageRoot, String... classRoots) throws IOException {
- for (String classRoot : classRoots) {
- int oldCount = testCaseLoader.getClasses().size();
- ClassFinder classFinder = new ClassFinder(new File(FileUtil.toSystemDependentName(classRoot)), packageRoot);
- testCaseLoader.loadTestCases(classFinder.getClasses());
- int newCount = testCaseLoader.getClasses().size();
- if (newCount != oldCount) {
- System.out.println("Loaded " + (newCount - oldCount) + " tests from class root " + classRoot);
- }
- }
-
- if (testCaseLoader.getClasses().size() == 1) {
- testCaseLoader.clearClasses();
- }
-
- log("Number of test classes found: " + testCaseLoader.getClasses().size());
- }
-
- private static void log(String message) {
- TeamCityLogger.info(message);
- }
-
- // [myakovlev] Do not delete - it is for debugging
- public static void tryGc(int times) {
+ private static void tryGc(int times) {
if ((ourMode & RUN_GC) == 0) return;
- for (int qqq = 1; qqq < times; qqq++) {
+ for (int i = 1; i < times; i++) {
try {
- Thread.sleep(qqq * 1000);
+ Thread.sleep(i * 1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
+
System.gc();
- //long mem = Runtime.getRuntime().totalMemory();
- log("Runtime.getRuntime().totalMemory() = " + Runtime.getRuntime().totalMemory());
+
+ long mem = Runtime.getRuntime().totalMemory();
+ log("Runtime.getRuntime().totalMemory() = " + mem);
}
}
+ private static void log(String message) {
+ TeamCityLogger.info(message);
+ }
}
diff --git a/platform/testFramework/src/com/intellij/TestCaseLoader.java b/platform/testFramework/src/com/intellij/TestCaseLoader.java
index 21d1ca207f9d..a81a2d2a1370 100644
--- a/platform/testFramework/src/com/intellij/TestCaseLoader.java
+++ b/platform/testFramework/src/com/intellij/TestCaseLoader.java
@@ -25,6 +25,7 @@
package com.intellij;
import com.intellij.idea.Bombed;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.TestRunnerUtil;
@@ -32,21 +33,17 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.*;
-import java.util.List;
@SuppressWarnings({"HardCodedStringLiteral", "UseOfSystemOutOrSystemErr", "CallToPrintStackTrace", "TestOnlyProblems"})
public class TestCaseLoader {
- /** Holds name of JVM property that is assumed to define target test group name. */
- private static final String TARGET_TEST_GROUP = "idea.test.group";
-
- /** Holds name of JVM property that is assumed to define filtering rules for test classes. */
- private static final String TARGET_TEST_PATTERNS = "idea.test.patterns";
-
+ public static final String TARGET_TEST_GROUP = "idea.test.group";
+ public static final String TARGET_TEST_PATTERNS = "idea.test.patterns";
public static final String PERFORMANCE_TESTS_ONLY_FLAG = "idea.performance.tests";
public static final String SKIP_COMMUNITY_TESTS = "idea.skip.community.tests";
@@ -93,11 +90,6 @@ public class TestCaseLoader {
}
}
- /*
- * Adds <code>testCaseClass</code> to the list of classes
- * if the class is a test case we wish to load. Calls
- * <code>shouldLoadTestCase ()</code> to determine that.
- */
void addClassIfTestCase(Class testCaseClass) {
if (shouldAddTestCase(testCaseClass, true) &&
testCaseClass != myFirstTestClass && testCaseClass != myLastTestClass &&
@@ -118,9 +110,6 @@ public class TestCaseLoader {
myLastTestClass = aClass;
}
- /**
- * Determine if we should load this test case.
- */
private boolean shouldAddTestCase(final Class<?> testCaseClass, boolean testForExcluded) {
if ((testCaseClass.getModifiers() & Modifier.ABSTRACT) != 0) return false;
if (testForExcluded && shouldExcludeTestClass(testCaseClass)) return false;
@@ -131,23 +120,17 @@ public class TestCaseLoader {
try {
final Method suiteMethod = testCaseClass.getMethod("suite");
if (Test.class.isAssignableFrom(suiteMethod.getReturnType()) && (suiteMethod.getModifiers() & Modifier.STATIC) != 0) {
- //System.out.println("testCaseClass = " + testCaseClass);
return true;
}
}
- catch (NoSuchMethodException e) {
- // can't be
- }
+ catch (NoSuchMethodException ignored) { }
return TestRunnerUtil.isJUnit4TestClass(testCaseClass);
}
- /*
- * Determine if we should exclude this test case.
- */
private boolean shouldExcludeTestClass(Class testCaseClass) {
String className = testCaseClass.getName();
- if (className.toLowerCase().contains("performance") && !myIsPerformanceTestsRun) return true;
+ if (className.toLowerCase(Locale.US).contains("performance") && !myIsPerformanceTestsRun) return true;
return !myTestClassesFilter.matches(className) || isBombed(testCaseClass);
}
@@ -158,7 +141,6 @@ public class TestCaseLoader {
if (PlatformTestUtil.isRotten(bombedAnnotation)) {
String message = "Disarm the stale bomb for '" + method + "' in class '" + method.getDeclaringClass() + "'";
System.err.println(message);
- //Assert.fail(message);
}
return !PlatformTestUtil.bombExplodes(bombedAnnotation);
}
@@ -169,7 +151,6 @@ public class TestCaseLoader {
if (PlatformTestUtil.isRotten(bombedAnnotation)) {
String message = "Disarm the stale bomb for '" + testCaseClass + "'";
System.err.println(message);
- // Assert.fail(message);
}
return !PlatformTestUtil.bombExplodes(bombedAnnotation);
}
@@ -200,30 +181,15 @@ public class TestCaseLoader {
private static final List<String> ourRankList = getTeamCityRankList();
private static List<String> getTeamCityRankList() {
- final String filePath = System.getProperty("teamcity.tests.recentlyFailedTests.file", null);
- if (filePath == null) {
- return Collections.emptyList();
- }
-
- try {
- final List<String> result = new ArrayList<String>();
- final BufferedReader reader = new BufferedReader(new FileReader(filePath));
+ String filePath = System.getProperty("teamcity.tests.recentlyFailedTests.file", null);
+ if (filePath != null) {
try {
- do {
- final String className = reader.readLine();
- if (className == null) break;
- result.add(className);
- }
- while (true);
- return result;
- }
- finally {
- reader.close();
+ return FileUtil.loadLines(filePath);
}
+ catch (IOException ignored) { }
}
- catch (IOException e) {
- return Collections.emptyList();
- }
+
+ return Collections.emptyList();
}
private int getRank(Class aClass) {
diff --git a/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java b/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
index 2afd09168420..4daee2640c27 100644
--- a/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
+++ b/platform/testFramework/src/com/intellij/psi/formatter/FormatterTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,10 +15,8 @@
*/
package com.intellij.psi.formatter;
-import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.impl.CodeFoldingPassFactory;
import com.intellij.lang.Language;
-import com.intellij.mock.MockProgressIndicator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.CommandProcessor;
@@ -42,6 +40,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.LocalTimeCounter;
@@ -199,7 +198,7 @@ public abstract class FormatterTestCase extends LightPlatformTestCase {
assertEquals(file.getText(), document.getText());
if (false && doCheckDocumentUpdate()) {
- makeFolding(file, editor);
+ EditorTestUtil.runTextEditorHighlightingPass(editor, CodeFoldingPassFactory.class);
}
try {
if (doReformatRangeTest) {
@@ -225,13 +224,6 @@ public abstract class FormatterTestCase extends LightPlatformTestCase {
assertEquals(textAfter, file.getText());
}
- protected static void makeFolding(final PsiFile file, final EditorImpl editor) {
- final CodeFoldingPassFactory factory = getProject().getComponent(CodeFoldingPassFactory.class);
- final TextEditorHighlightingPass highlightingPass = factory.createHighlightingPass(file, editor);
- highlightingPass.collectInformation(new MockProgressIndicator());
- highlightingPass.doApplyInformationToEditor();
- }
-
@SuppressWarnings({"UNUSED_SYMBOL"})
private void checkPsi(final PsiFile file, String textAfter) {
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
diff --git a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
index 374af22f1c91..d42e639438c2 100644
--- a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
@@ -15,7 +15,10 @@
*/
package com.intellij.testFramework;
+import com.intellij.codeHighlighting.TextEditorHighlightingPass;
+import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.ide.DataManager;
+import com.intellij.mock.MockProgressIndicator;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -32,13 +35,17 @@ import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapDrawingType;
import com.intellij.openapi.editor.impl.softwrap.SoftWrapPainter;
import com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
import org.junit.Assert;
import java.awt.*;
@@ -155,6 +162,7 @@ public class EditorTestUtil {
*
* @return whether any actual wraps of editor contents were created as a result of turning on soft wraps
*/
+ @TestOnly
public static boolean configureSoftWraps(Editor editor, final int charCountToWrapAt) {
int charWidthInPixels = 7;
// we're adding 1 to charCountToWrapAt, to account for wrap character width, and 1 to overall width to overcome wrapping logic subtleties
@@ -166,6 +174,7 @@ public class EditorTestUtil {
*
* @return whether any actual wraps of editor contents were created as a result of turning on soft wraps
*/
+ @TestOnly
public static boolean configureSoftWraps(Editor editor, final int visibleWidth, final int charWidthInPixels) {
editor.getSettings().setUseSoftWraps(true);
SoftWrapModelImpl model = (SoftWrapModelImpl)editor.getSoftWrapModel();
@@ -429,6 +438,20 @@ public class EditorTestUtil {
return ref.get();
}
+ public static <T extends TextEditorHighlightingPassFactory> void runTextEditorHighlightingPass(@NotNull Editor editor, @NotNull Class<T> passFactory) {
+ Project project = editor.getProject();
+ assertNotNull(project);
+ PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ PsiFile psiFile = psiDocumentManager.getPsiFile(editor.getDocument());
+ assertNotNull(psiFile);
+
+ T factory = project.getComponent(passFactory);
+ TextEditorHighlightingPass pass = factory.createHighlightingPass(psiFile, editor);
+ assertNotNull(pass);
+ pass.collectInformation(new MockProgressIndicator());
+ pass.applyInformationToEditor();
+ }
+
public static class CaretAndSelectionState {
public final List<CaretInfo> carets = new ArrayList<CaretInfo>();
@Nullable
diff --git a/platform/testFramework/src/com/intellij/testFramework/FileEditorManagerTestCase.java b/platform/testFramework/src/com/intellij/testFramework/FileEditorManagerTestCase.java
index 3968ece26cd0..77b93ac6f88f 100644
--- a/platform/testFramework/src/com/intellij/testFramework/FileEditorManagerTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/FileEditorManagerTestCase.java
@@ -49,6 +49,7 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
protected FileEditorManagerImpl myManager;
private FileEditorManager myOldManager;
+ @Override
public void setUp() throws Exception {
super.setUp();
myManager = new FileEditorManagerImpl(getProject(), DockManager.getInstance(getProject()), EditorHistoryManager.getInstance(getProject()));
@@ -87,7 +88,12 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
- myManager.getMainSplitters().openFiles();
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ myManager.getMainSplitters().openFiles();
+ }
+ });
}
});
while (true) {
diff --git a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
index 214442f53e6f..3b7d0e1d14a6 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LeakHunter.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FList;
import com.intellij.util.containers.Stack;
import com.intellij.util.io.PersistentEnumerator;
import com.intellij.util.ui.UIUtil;
@@ -206,7 +207,7 @@ public class LeakHunter {
while (backLink != null) {
String valueStr;
try {
- valueStr = String.valueOf(backLink.value);
+ valueStr = backLink.value instanceof FList ? "FList" : String.valueOf(backLink.value);
}
catch (Throwable e) {
valueStr = "("+e.getMessage()+" while computing .toString())";
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
index 01e0a7a09fb5..90c2ca11b49a 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
@@ -29,9 +29,7 @@ import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.ex.util.EditorUtil;
@@ -42,6 +40,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -65,7 +64,6 @@ import org.junit.runners.Parameterized;
import java.io.File;
import java.io.IOException;
-import java.lang.IllegalArgumentException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -213,10 +211,21 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
private static void setupEditorForInjectedLanguage() {
- Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
- if (editor instanceof EditorWindow) {
- myFile = ((EditorWindow)editor).getInjectedFile();
- myEditor = editor;
+ if (myEditor != null) {
+ final Ref<EditorWindow> editorWindowRef = new Ref<EditorWindow>();
+ myEditor.getCaretModel().runForEachCaret(new CaretAction() {
+ @Override
+ public void perform(Caret caret) {
+ Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
+ if (caret == myEditor.getCaretModel().getPrimaryCaret() && editor instanceof EditorWindow) {
+ editorWindowRef.set((EditorWindow)editor);
+ }
+ }
+ });
+ if (!editorWindowRef.isNull()) {
+ myEditor = editorWindowRef.get();
+ myFile = editorWindowRef.get().getInjectedFile();
+ }
}
}
@@ -410,7 +419,8 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE).execute(getEditor(), dataContext);
}
else {
- actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
+ // typed action is always executed in host editor context
+ actionManager.getTypedAction().actionPerformed(InjectedLanguageUtil.getTopLevelEditor(getEditor()), c, dataContext);
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index 42e7c7057962..33051b471049 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -37,6 +37,7 @@ import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationEx;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.UndoManager;
@@ -344,6 +345,8 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
try {
LightPlatformTestCase.super.setUp();
initApplication();
+ ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
+
ourApplication.setDataProvider(LightPlatformTestCase.this);
doSetup(new SimpleLightProjectDescriptor(getModuleType(), getProjectJDK()), configureLocalInspectionTools(),
myAvailableInspectionTools);
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index c72ff350db89..347661846e2a 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
@@ -48,8 +48,6 @@ import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.project.impl.TooManyProjectLeakedException;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.roots.impl.DirectoryIndex;
-import com.intellij.openapi.roots.impl.DirectoryIndexImpl;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EmptyRunnable;
@@ -142,7 +140,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
}
- private static String[] PREFIX_CANDIDATES = new String[] { "AppCode", "CppIde", "Python", "PyCharmCore", "UltimateLangXml", "Idea" };
+ private static final String[] PREFIX_CANDIDATES = {
+ "AppCode", "CppIde", "CidrCommon",
+ "Python", "PyCharmCore", "Ruby", "UltimateLangXml", "Idea" };
public static void autodetectPlatformPrefix() {
if (ourPlatformPrefixInitialized) {
@@ -410,8 +410,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
try {
Project project = getProject();
- DirectoryIndexImpl directoryIndex =
- project != null ? (DirectoryIndexImpl)DirectoryIndex.getInstance(project) : null;
disposeProject(result);
if (project != null) {
@@ -787,7 +785,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
setContentOnDisk(temp, bom, content, charset);
myFilesToDelete.add(temp);
- final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(temp);
+ final VirtualFile file = getVirtualFile(temp);
assert file != null : temp;
return file;
}
@@ -841,7 +839,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
protected static VirtualFile createChildData(@NotNull final VirtualFile dir, @NotNull @NonNls final String name) {
return new WriteAction<VirtualFile>() {
@Override
- protected void run(Result<VirtualFile> result) throws Throwable {
+ protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
result.setResult(dir.createChildData(null, name));
}
}.execute().throwException().getResultObject();
@@ -850,7 +848,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
protected static VirtualFile createChildDirectory(@NotNull final VirtualFile dir, @NotNull @NonNls final String name) {
return new WriteAction<VirtualFile>() {
@Override
- protected void run(Result<VirtualFile> result) throws Throwable {
+ protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
result.setResult(dir.createChildDirectory(null, name));
}
}.execute().throwException().getResultObject();
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
index 94e86e1ed74a..37fd23da6741 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
@@ -34,10 +34,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.ui.Queryable;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -445,6 +442,12 @@ public class PlatformTestUtil {
assertEquals(expected, actual);
}
+ @NotNull
+ public static String getRtJarPath() {
+ String home = System.getProperty("java.home");
+ return SystemInfo.isAppleJvm ? FileUtil.toCanonicalPath(home + "/../Classes/classes.jar") : home + "/lib/rt.jar";
+ }
+
public static class TestInfo {
private final ThrowableRunnable test; // runnable to measure
private final int expectedMs; // millis the test is expected to run
diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
index 9e9c9444f82a..0f746d43c6ca 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.testFramework;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.RunResult;
import com.intellij.openapi.application.WriteAction;
@@ -53,7 +54,6 @@ import org.junit.Assert;
import java.io.File;
import java.util.*;
-import static com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel;
@NonNls
public class PsiTestUtil {
@@ -119,7 +119,7 @@ public class PsiTestUtil {
}
public static void removeAllRoots(Module module, final Sdk jdk) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.clear();
@@ -133,7 +133,7 @@ public class PsiTestUtil {
}
public static void addSourceContentToRoots(Module module, @NotNull final VirtualFile vDir, final boolean testSource) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.addContentEntry(vDir).addSourceFolder(vDir, testSource);
@@ -157,7 +157,7 @@ public class PsiTestUtil {
public static <P extends JpsElement> void addSourceRoot(Module module, final VirtualFile vDir,
@NotNull final JpsModuleSourceRootType<P> rootType, final P properties) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@SuppressWarnings("unchecked")
@Override
public void consume(ModifiableRootModel model) {
@@ -180,7 +180,7 @@ public class PsiTestUtil {
}
public static ContentEntry addContentRoot(Module module, final VirtualFile vDir) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.addContentEntry(vDir);
@@ -198,10 +198,15 @@ public class PsiTestUtil {
}
public static void addExcludedRoot(Module module, final VirtualFile dir) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
- public void consume(ModifiableRootModel model) {
- findContentEntryWithAssertion(model, dir).addExcludeFolder(dir);
+ public void consume(final ModifiableRootModel model) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ findContentEntryWithAssertion(model, dir).addExcludeFolder(dir);
+ }
+ });
}
});
}
@@ -216,7 +221,7 @@ public class PsiTestUtil {
}
public static void removeContentEntry(Module module, final ContentEntry e) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.removeContentEntry(e);
@@ -225,7 +230,7 @@ public class PsiTestUtil {
}
public static void removeSourceRoot(Module module, final VirtualFile root) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
ContentEntry entry = findContentEntryWithAssertion(model, root);
@@ -240,7 +245,7 @@ public class PsiTestUtil {
}
public static void removeExcludedRoot(Module module, final VirtualFile root) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
ContentEntry entry = findContentEntryWithAssertion(model, root);
@@ -257,7 +262,7 @@ public class PsiTestUtil {
}
public static void addLibrary(final Module module, final String libName, final String libPath, final String... jarArr) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
addLibrary(module, model, libName, libPath, jarArr);
@@ -272,7 +277,7 @@ public class PsiTestUtil {
public static Library addProjectLibrary(final Module module, final String libName, final List<VirtualFile> classesRoots,
final List<VirtualFile> sourceRoots) {
final Ref<Library> result = Ref.create();
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
result.set(addProjectLibrary(module, model, libName, classesRoots, sourceRoots));
@@ -395,7 +400,7 @@ public class PsiTestUtil {
}
public static void setCompilerOutputPath(Module module, final String url, final boolean forTests) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
CompilerModuleExtension extension = model.getModuleExtension(CompilerModuleExtension.class);
@@ -411,7 +416,7 @@ public class PsiTestUtil {
}
public static void setExcludeCompileOutput(Module module, final boolean exclude) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(exclude);
@@ -420,7 +425,7 @@ public class PsiTestUtil {
}
public static void setJavadocUrls(Module module, final String... urls) {
- updateModel(module, new Consumer<ModifiableRootModel>() {
+ ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
model.getModuleExtension(JavaModuleExternalPaths.class).setJavadocUrls(urls);
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 898d9d04bd28..fa752b4643b0 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -19,14 +19,11 @@ import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.diagnostic.PerformanceWatcher;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.command.impl.StartMarkAction;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
@@ -38,14 +35,10 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
-import com.intellij.refactoring.rename.PsiElementRenameHandler;
-import com.intellij.refactoring.rename.RenameHandler;
-import com.intellij.refactoring.rename.RenameHandlerRegistry;
import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
import com.intellij.rt.execution.junit.FileComparisonFailure;
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
@@ -64,6 +57,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
+import javax.swing.Timer;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
@@ -75,6 +69,9 @@ import java.lang.reflect.Modifier;
import java.security.SecureRandom;
import java.util.*;
import java.util.List;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
@@ -141,8 +138,7 @@ public abstract class UsefulTestCase extends TestCase {
myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000));
FileUtil.resetCanonicalTempPathCache(myTempDir);
}
- //noinspection AssignmentToStaticFieldFromInstanceMethod
- DocumentImpl.CHECK_DOCUMENT_CONSISTENCY = !isPerformanceTest();
+ ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest());
}
@Override
@@ -178,13 +174,14 @@ public abstract class UsefulTestCase extends TestCase {
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
static {
- Class<?> aClass = null;
- Set<String> files = null;
+ Class<?> aClass;
try {
aClass = Class.forName("java.io.DeleteOnExitHook");
- files = ReflectionUtil.getField(aClass, null, Set.class, "files");
}
- catch (Exception ignored) { }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ Set<String> files = ReflectionUtil.getField(aClass, null, Set.class, "files");
DELETE_ON_EXIT_HOOK_CLASS = aClass;
DELETE_ON_EXIT_HOOK_DOT_FILES = files;
}
@@ -207,23 +204,11 @@ public abstract class UsefulTestCase extends TestCase {
}
private static void cleanupSwingDataStructures() throws Exception {
- Class<?> aClass = Class.forName("javax.swing.KeyboardManager");
-
- Method get = aClass.getMethod("getCurrentManager");
- get.setAccessible(true);
- Object manager = get.invoke(null);
- {
- Field mapF = aClass.getDeclaredField("componentKeyStrokeMap");
- mapF.setAccessible(true);
- Object map = mapF.get(manager);
- ((Map)map).clear();
- }
- {
- Field mapF = aClass.getDeclaredField("containerMap");
- mapF.setAccessible(true);
- Object map = mapF.get(manager);
- ((Map)map).clear();
- }
+ Object manager = ReflectionUtil.getDeclaredMethod(Class.forName("javax.swing.KeyboardManager"), "getCurrentManager").invoke(null);
+ Map componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
+ componentKeyStrokeMap.clear();
+ Map containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
+ containerMap.clear();
}
protected CompositeException checkForSettingsDamage() throws Exception {
@@ -777,26 +762,51 @@ public abstract class UsefulTestCase extends TestCase {
}
protected static void checkAllTimersAreDisposed() {
+ Field firstTimerF;
+ Object timerQueue;
+ Object timer;
try {
- Class<?> aClass = Class.forName("javax.swing.TimerQueue");
-
- Method inst = aClass.getDeclaredMethod("sharedInstance");
- inst.setAccessible(true);
- Object queue = inst.invoke(null);
- Field field = aClass.getDeclaredField("firstTimer");
- field.setAccessible(true);
- Object firstTimer = field.get(queue);
- if (firstTimer != null) {
+ Class<?> TimerQueueC = Class.forName("javax.swing.TimerQueue");
+ Method sharedInstance = TimerQueueC.getDeclaredMethod("sharedInstance");
+ sharedInstance.setAccessible(true);
+
+ firstTimerF = ReflectionUtil.getDeclaredField(TimerQueueC, "firstTimer");
+ timerQueue = sharedInstance.invoke(null);
+ if (firstTimerF == null) {
+ // jdk 8
+ DelayQueue delayQueue = ReflectionUtil.getField(TimerQueueC, timerQueue, DelayQueue.class, "queue");
+ timer = delayQueue.peek();
+ }
+ else {
+ // ancient jdk
+ firstTimerF.setAccessible(true);
+ timer = firstTimerF.get(timerQueue);
+ }
+ }
+ catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ if (timer != null) {
+ if (firstTimerF != null) {
+ ReflectionUtil.resetField(timerQueue, firstTimerF);
+ }
+ String text = "";
+ if (timer instanceof Delayed) {
+ long delay = ((Delayed)timer).getDelay(TimeUnit.MILLISECONDS);
+ text = "(delayed for "+delay+"ms)";
+ Method getTimer = ReflectionUtil.getDeclaredMethod(timer.getClass(), "getTimer");
+ getTimer.setAccessible(true);
try {
- fail("Not disposed Timer: " + firstTimer.toString() + "; queue:" + queue);
+ timer = getTimer.invoke(timer);
}
- finally {
- field.set(queue, null);
+ catch (Exception e) {
+ throw new RuntimeException(e);
}
}
- }
- catch (Throwable e) {
- // Ignore
+ Timer t = (Timer)timer;
+ text = "Timer (listeners: "+Arrays.asList(t.getActionListeners()) + ") "+text;
+
+ fail("Not disposed Timer: " + text + "; queue:" + timerQueue);
}
}
@@ -886,12 +896,11 @@ public abstract class UsefulTestCase extends TestCase {
while (aClass != null && aClass != Object.class) {
if (aClass.getAnnotation(annotationClass) != null) return true;
if (!methodChecked) {
- try {
- Method method = aClass.getDeclaredMethod(methodName);
+ Method method = ReflectionUtil.getDeclaredMethod(aClass, methodName);
+ if (method != null) {
if (method.getAnnotation(annotationClass) != null) return true;
methodChecked = true;
}
- catch (NoSuchMethodException ignored) { }
}
aClass = aClass.getSuperclass();
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
index 6a546467f327..e721401a82ba 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
@@ -252,7 +252,10 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
* @param filePaths the first file is tested only; the others are just copied along the first.
* @return highlighting duration in milliseconds.
*/
- long testHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, @TestDataFile @NonNls @NotNull String... filePaths);
+ long testHighlighting(boolean checkWarnings,
+ boolean checkInfos,
+ boolean checkWeakWarnings,
+ @TestDataFile @NonNls @NotNull String... filePaths);
long testHighlightingAllFiles(boolean checkWarnings,
boolean checkInfos,
@@ -377,7 +380,9 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
* Runs basic completion in caret position in fileBefore.
* Implies that there is only one completion variant and it was inserted automatically, and checks the result file text with fileAfter
*/
- void testCompletion(@TestDataFile @NonNls @NotNull String fileBefore, @NotNull @TestDataFile @NonNls String fileAfter, @NotNull String... additionalFiles);
+ void testCompletion(@TestDataFile @NonNls @NotNull String fileBefore,
+ @NotNull @TestDataFile @NonNls String fileAfter,
+ @NotNull String... additionalFiles);
void testCompletionTyping(@NotNull @TestDataFile @NonNls String fileBefore,
@NotNull String toType,
@@ -433,6 +438,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
/**
* @return null if the only item was auto-completed
+ * @see #completeBasicAllCarets()
*/
LookupElement[] completeBasic();
@@ -495,6 +501,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
/**
* Renames element at caret using injected {@link com.intellij.refactoring.rename.RenameHandler}s.
* Very close to {@link #renameElementAtCaret(String)} but uses handlers.
+ *
* @param newName new name for the element.
*/
void renameElementAtCaretUsingHandler(@NotNull String newName);
@@ -532,4 +539,21 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
* @param caresAboutInjection true if the fixture should look for an injection at caret, false otherwise.
*/
void setCaresAboutInjection(boolean caresAboutInjection);
+
+ /**
+ * Completes basically (see {@link #completeBasic()}) <strong>all</strong>
+ * carets (places marked with {@link #CARET_MARKER} in file. Example:
+ * <pre>
+ * PyC&lt;caret&gt; is IDE for Py&lt;caret&gt;
+ * </pre>
+ * should be completed to
+ * <pre>
+ * PyCharm is IDE for Python
+ * </pre>
+ * Actually, it works just like {@link #completeBasic()} but supports
+ * several {@link #CARET_MARKER}
+ *
+ * @see #completeBasic()
+ */
+ void completeBasicAllCarets();
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
index 890d69b4cda0..ce58f3071581 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -82,6 +82,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
@@ -185,7 +186,15 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
VirtualFile result;
+ final String path = fromFile.getPath();
if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
+ VfsRootAccess.allowRootAccess(path);
+ Disposer.register(myTestRootDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ VfsRootAccess.disallowRootAccess(path);
+ }
+ });
VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
if (fromVFile == null) {
fromVFile = myTempDirFixture.getFile(sourceFilePath);
@@ -217,7 +226,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
assert file != null : targetFile;
result = file;
}
- result.putUserData(VfsTestUtil.TEST_DATA_FILE_PATH, fromFile.getPath());
+ result.putUserData(VfsTestUtil.TEST_DATA_FILE_PATH, path);
return result;
}
@@ -231,20 +240,18 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
return myTempDirFixture.copyAll(fromFile.getPath(), targetPath);
}
- else {
- final File targetFile = new File(getTempDirPath() + "/" + targetPath);
- try {
- FileUtil.copyDir(fromFile, targetFile);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(targetFile);
- Assert.assertNotNull(file);
- file.refresh(false, true);
- return file;
+ final File targetFile = new File(getTempDirPath() + "/" + targetPath);
+ try {
+ FileUtil.copyDir(fromFile, targetFile);
}
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(targetFile);
+ Assert.assertNotNull(file);
+ file.refresh(false, true);
+ return file;
}
@NotNull
@@ -1026,14 +1033,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
super.completionFinished(offset1, offset2, indicator, items, hasModifiers);
}
};
- final Editor editor = getCompletionEditor();
- assert editor != null: "Editor is null";
- editor.getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(final Caret caret) {
- handler.invokeCompletion(getProject(), editor, invocationCount);
- }
- });
+ Editor editor = getCompletionEditor();
+ handler.invokeCompletion(getProject(), editor, invocationCount);
PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); // to compare with file text
}
}, null, null);
@@ -1054,6 +1055,28 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return complete(CompletionType.BASIC);
}
+
+ @Override
+ public void completeBasicAllCarets() {
+ final CaretModel caretModel = myEditor.getCaretModel();
+ final List<Caret> carets = caretModel.getAllCarets();
+
+ final Collection<Integer> originalOffsets = new ArrayList<Integer>(carets.size());
+
+ for (final Caret caret : carets) {
+ originalOffsets.add(caret.getOffset());
+ }
+ caretModel.removeSecondaryCarets();
+
+ int newOffset = 0; // To be incremented each time we complete something
+ for (final int originalOffset : originalOffsets) {
+ final int realOffsetBeforeCompletion = originalOffset + newOffset;
+ caretModel.moveToOffset(realOffsetBeforeCompletion);
+ completeBasic();
+ newOffset += (getCaretOffset() - realOffsetBeforeCompletion);
+ }
+ }
+
@Override
@Nullable
public LookupElement[] getLookupElements() {
@@ -1316,9 +1339,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public PsiFile configureByText(@NotNull final String fileName, @NotNull @NonNls final String text) {
assertInitialized();
- new WriteCommandAction(getProject()) {
+ return new WriteCommandAction<PsiFile>(getProject()) {
@Override
- protected void run(@NotNull Result result) throws Throwable {
+ protected void run(@NotNull Result<PsiFile> result) throws Throwable {
final VirtualFile vFile;
if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
final VirtualFile root = LightPlatformTestCase.getSourceRoot();
@@ -1343,9 +1366,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
VfsUtil.saveText(vFile, text);
configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile));
+ result.setResult(getFile());
}
- }.execute();
- return getFile();
+ }.execute().getResultObject();
}
@Override
@@ -1594,7 +1617,12 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public PsiFile getFile() {
- return myFile == null ? null : PsiManager.getInstance(getProject()).findFile(myFile);
+ return myFile == null ? null : ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Override
+ public PsiFile compute() {
+ return PsiManager.getInstance(getProject()).findFile(myFile);
+ }
+ });
}
public static List<IntentionAction> getAvailableIntentions(@NotNull final Editor editor, @NotNull final PsiFile file) {
diff --git a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
index 27a025c77e27..86958eee3461 100644
--- a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
+++ b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
@@ -92,7 +92,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "control ENTER", "EditorSplitLine", "ViewSource", "Console.Jdbc.Execute", "Console.Jpa.Execute", "Groovy.Shell.Execute"},
{ "control EQUALS", "ExpandAll", "ExpandRegion"},
{ "control F5", "Refresh", "Rerun"},
- { "control D", "CompareDirs", "EditorDuplicate", "CompareTwoFiles", "SendEOF"},
+ { "control D", "CompareDirs", "EditorDuplicate", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control M", "EditorScrollToCenter", "Vcs.ShowMessageHistory"},
{ "control N", "FileChooser.NewFolder", "GotoClass"},
{ "control P", "FileChooser.TogglePathShowing", "ParameterInfo"},
@@ -175,7 +175,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "control 2", "FileChooser.GotoProject", "GotoBookmark2", "DuplicatesForm.SendToRight"},
{ "control 3", "GotoBookmark3", "FileChooser.GotoModule"},
{ "control 5", "ChangeSplitOrientation", "GotoBookmark5"},
- { "control D", "CompareDirs", "$Delete", "CompareTwoFiles", "SendEOF"},
+ { "control D", "CompareDirs", "$Delete", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control K", "EditorCutLineEnd", "CheckinProject"},
{ "control N", "EditorDown", "FileChooser.NewFolder"},
{ "control P", "EditorUp", "FileChooser.TogglePathShowing"},
@@ -200,7 +200,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "alt INSERT", "FileChooser.NewFolder", "Generate", "NewElement"},
{ "control DIVIDE", "CommentByLineComment", "Images.Editor.ActualSize"},
{ "control F1", "ExternalJavaDoc", "ShowErrorDescription"},
- { "control F10", "RunToCursor", "javaee.UpdateRunningApplication"},
+ { "control F10", "RunToCursor", "javaee.UpdateRunningApplication", "liveedit.UpdateRunningApplication"},
{ "control F5", "Rerun", "Run"},
{ "control N", "FileChooser.NewFolder", "Generate", },
{ "control P", "FileChooser.TogglePathShowing", "Print"},
@@ -240,7 +240,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "alt HOME", "ViewNavigationBar", "ShowNavBar"},
{ "control F10", "ShowPopupMenu", "javaee.UpdateRunningApplication"},
{ "control F11", "Rerun", "ToggleBookmarkWithMnemonic"},
- { "control D", "CompareDirs", "EditorDeleteLine", "CompareTwoFiles", "SendEOF"},
+ { "control D", "CompareDirs", "EditorDeleteLine", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control N", "ShowPopupMenu", "FileChooser.NewFolder"},
{ "control P", "FileChooser.TogglePathShowing", "Print"},
{ "control R", "RunToCursor", "Console.TableResult.Reload", "org.jetbrains.plugins.ruby.rails.console.ReloadSources"},
@@ -276,7 +276,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "control 3", "ActivateProjectToolWindow", "FileChooser.GotoModule"},
{ "control BACK_SPACE", "EditorDeleteToWordStart", "ToggleDockMode"},
{ "control DIVIDE", "CommentByLineComment", "Images.Editor.ActualSize"},
- { "control D", "EditorDuplicate", "CompareDirs", "CompareTwoFiles", "SendEOF"},
+ { "control D", "EditorDuplicate", "CompareDirs", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control M", "Vcs.ShowMessageHistory", "Move"},
{ "control R", "RenameElement", "Console.TableResult.Reload", "org.jetbrains.plugins.ruby.rails.console.ReloadSources"},
{ "control SLASH", "CommentByLineComment", "Images.Editor.ActualSize"},
@@ -321,7 +321,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "control PERIOD", "EditorChooseLookupItemDot", "HippieCompletion"},
{ "meta 1", "FileChooser.GotoHome", "ShowIntentionActions", "DuplicatesForm.SendToLeft"},
{ "meta 3", "FileChooser.GotoModule", "GotoAction"},
- { "meta D", "EditorDeleteLine", "CompareTwoFiles", "CompareDirs", "SendEOF"},
+ { "meta D", "EditorDeleteLine", "CompareTwoFiles", "CompareDirs", "SendEOF", "FileChooser.GotoDesktop"},
{ "meta P", "FileChooser.TogglePathShowing", "Print"},
{ "meta R", "org.jetbrains.plugins.ruby.rails.console.ReloadSources", "RunToCursor"},
{ "meta U", "CommanderSwapPanels", "EvaluateExpression"},
@@ -438,9 +438,10 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
}
else {
if (failMessage.length() == 0) {
- failMessage.append("Shortcut '" + getText(shortcut) + "' conflicts found in keymap '" + keymap.getName() + "':\n");
+ failMessage.append("Shortcut '").append(getText(shortcut)).append("' conflicts found in keymap '")
+ .append(keymap.getName()).append("':\n");
}
- failMessage.append(def + "\n");
+ failMessage.append(def).append("\n");
}
}
if (OUTPUT_TEST_DATA) {
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java b/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
index f3a12618c51b..9be02ae51271 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/actions/AbstractRerunFailedTestsAction.java
@@ -139,9 +139,9 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
TestFrameworkRunningModel model = getModel();
if (model == null || model.getRoot() == null) return false;
final List<? extends AbstractTestProxy> myAllTests = model.getRoot().getAllTests();
- final GlobalSearchScope searchScope = model.getProperties().getScope();
+ final Filter filter = getFailuresFilter();
for (Object test : myAllTests) {
- if (getFilter(project, searchScope).shouldAccept((AbstractTestProxy)test)) return true;
+ if (filter.shouldAccept((AbstractTestProxy)test)) return true;
}
return false;
}
@@ -157,8 +157,12 @@ public class AbstractRerunFailedTestsAction extends AnAction implements AnAction
@NotNull
protected Filter getFilter(Project project, GlobalSearchScope searchScope) {
+ return getFailuresFilter();
+ }
+
+ protected Filter getFailuresFilter() {
if (TestConsoleProperties.INCLUDE_NON_STARTED_IN_RERUN_FAILED.value(myConsoleProperties)) {
- return Filter.NOT_PASSED.or(Filter.FAILED_OR_INTERRUPTED);
+ return Filter.NOT_PASSED.and(Filter.IGNORED.not()).or(Filter.FAILED_OR_INTERRUPTED);
}
return Filter.FAILED_OR_INTERRUPTED;
}
diff --git a/platform/usageView/src/com/intellij/usages/UsageInfoSearcherAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfoSearcherAdapter.java
index d448cbde9b46..36544a632602 100644
--- a/platform/usageView/src/com/intellij/usages/UsageInfoSearcherAdapter.java
+++ b/platform/usageView/src/com/intellij/usages/UsageInfoSearcherAdapter.java
@@ -26,7 +26,7 @@ import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
public abstract class UsageInfoSearcherAdapter implements UsageSearcher {
- protected void processUsages(final @NotNull Processor<Usage> processor, Project project) {
+ protected void processUsages(final @NotNull Processor<Usage> processor, @NotNull Project project) {
final Ref<UsageInfo[]> refUsages = new Ref<UsageInfo[]>();
final Ref<Boolean> dumbModeOccurred = new Ref<Boolean>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
diff --git a/platform/usageView/src/com/intellij/usages/UsageView.java b/platform/usageView/src/com/intellij/usages/UsageView.java
index 46906ba2fa22..a360e31ec50c 100644
--- a/platform/usageView/src/com/intellij/usages/UsageView.java
+++ b/platform/usageView/src/com/intellij/usages/UsageView.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,6 +17,7 @@ package com.intellij.usages;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.psi.search.SearchScope;
import com.intellij.usageView.UsageInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,6 +47,7 @@ public interface UsageView extends Disposable {
@Deprecated String USAGE_VIEW = USAGE_VIEW_KEY.getName();
DataKey<UsageInfo> USAGE_INFO_KEY = DataKey.create("UsageInfo");
+ DataKey<SearchScope> USAGE_SCOPE = DataKey.create("UsageScope");
DataKey<List<UsageInfo>> USAGE_INFO_LIST_KEY = DataKey.create("UsageInfo.List");
diff --git a/platform/usageView/src/com/intellij/usages/UsageViewManager.java b/platform/usageView/src/com/intellij/usages/UsageViewManager.java
index 3029c2e7aa7c..eadae931eb37 100644
--- a/platform/usageView/src/com/intellij/usages/UsageViewManager.java
+++ b/platform/usageView/src/com/intellij/usages/UsageViewManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -43,7 +43,7 @@ public abstract class UsageViewManager {
@NotNull
public abstract UsageView showUsages(@NotNull UsageTarget[] searchedFor, @NotNull Usage[] foundUsages, @NotNull UsageViewPresentation presentation);
- @Nullable ("in case no usages found or usage view not shown for one usage")
+ @Nullable ("returns null in case of no usages found or usage view not shown for one usage")
public abstract UsageView searchAndShowUsages(@NotNull UsageTarget[] searchFor,
@NotNull Factory<UsageSearcher> searcherFactory,
boolean showPanelIfOnlyOneUsage,
diff --git a/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java b/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java
index 832d59241fb8..c715c6a169c6 100644
--- a/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java
+++ b/platform/usageView/src/com/intellij/usages/UsageViewPresentation.java
@@ -56,11 +56,12 @@ public class UsageViewPresentation {
myTabText = tabText;
}
+ @NotNull
public String getScopeText() {
return myScopeText;
}
- public void setScopeText(String scopeText) {
+ public void setScopeText(@NotNull String scopeText) {
myScopeText = scopeText;
}
diff --git a/platform/usageView/src/com/intellij/usages/impl/NullUsage.java b/platform/usageView/src/com/intellij/usages/impl/NullUsage.java
index 10475ee67f5c..721e3faa15eb 100644
--- a/platform/usageView/src/com/intellij/usages/impl/NullUsage.java
+++ b/platform/usageView/src/com/intellij/usages/impl/NullUsage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,63 +16,12 @@
package com.intellij.usages.impl;
-import com.intellij.openapi.fileEditor.FileEditorLocation;
-import com.intellij.usages.Usage;
-import com.intellij.usages.UsagePresentation;
-import org.jetbrains.annotations.NotNull;
-
/**
* @author cdr
*/
-public class NullUsage implements Usage {
+public class NullUsage extends UsageAdapter {
public static final NullUsage INSTANCE = new NullUsage();
private NullUsage() {
}
-
- @Override
- @NotNull
- public UsagePresentation getPresentation() {
- throw new IllegalAccessError();
- }
-
- @Override
- public boolean isValid() {
- return false;
- }
-
- @Override
- public boolean isReadOnly() {
- return false;
- }
-
- @Override
- public FileEditorLocation getLocation() {
- return null;
- }
-
- @Override
- public void selectInEditor() {
-
- }
-
- @Override
- public void highlightInEditor() {
-
- }
-
- @Override
- public void navigate(final boolean requestFocus) {
-
- }
-
- @Override
- public boolean canNavigate() {
- return false;
- }
-
- @Override
- public boolean canNavigateToSource() {
- return false;
- }
}
diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
new file mode 100644
index 000000000000..8b065b30d167
--- /dev/null
+++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.usages.impl;
+
+import com.intellij.find.FindManager;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.util.ProgressWrapper;
+import com.intellij.openapi.progress.util.TooManyUsagesStatus;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Factory;
+import com.intellij.openapi.util.Segment;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.ui.HyperlinkAdapter;
+import com.intellij.usageView.UsageViewBundle;
+import com.intellij.usages.*;
+import com.intellij.util.Alarm;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.ui.RangeBlinker;
+import com.intellij.xml.util.XmlStringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import java.awt.event.ActionEvent;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+class SearchForUsagesRunnable implements Runnable {
+ @NonNls private static final String FIND_OPTIONS_HREF_TARGET = "FindOptions";
+ @NonNls private static final String SEARCH_IN_PROJECT_HREF_TARGET = "SearchInProject";
+ @NonNls private static final String LARGE_FILES_HREF_TARGET = "LargeFiles";
+ private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0);
+ private final AtomicReference<Usage> myFirstUsage = new AtomicReference<Usage>();
+ @NotNull
+ private final Project myProject;
+ private final AtomicReference<UsageViewImpl> myUsageViewRef;
+ private final UsageViewPresentation myPresentation;
+ private final UsageTarget[] mySearchFor;
+ private final Factory<UsageSearcher> mySearcherFactory;
+ private final FindUsagesProcessPresentation myProcessPresentation;
+ @NotNull private final SearchScope mySearchScope;
+ private final UsageViewManager.UsageViewStateListener myListener;
+ private final UsageViewManagerImpl myUsageViewManager;
+ private final AtomicInteger myOutOfScopeUsages = new AtomicInteger();
+
+ SearchForUsagesRunnable(@NotNull UsageViewManagerImpl usageViewManager,
+ @NotNull Project project,
+ @NotNull AtomicReference<UsageViewImpl> usageViewRef,
+ @NotNull UsageViewPresentation presentation,
+ @NotNull UsageTarget[] searchFor,
+ @NotNull Factory<UsageSearcher> searcherFactory,
+ @NotNull FindUsagesProcessPresentation processPresentation,
+ @NotNull SearchScope scope,
+ @Nullable UsageViewManager.UsageViewStateListener listener) {
+ myProject = project;
+ myUsageViewRef = usageViewRef;
+ myPresentation = presentation;
+ mySearchFor = searchFor;
+ mySearcherFactory = searcherFactory;
+ myProcessPresentation = processPresentation;
+ mySearchScope = scope;
+ myListener = listener;
+ myUsageViewManager = usageViewManager;
+ }
+
+ @NotNull
+ private static String createOptionsHtml(@NonNls UsageTarget[] searchFor) {
+ KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(searchFor);
+ String shortcutText = "";
+ if (shortcut != null) {
+ shortcutText = "&nbsp;(" + KeymapUtil.getShortcutText(shortcut) + ")";
+ }
+ return "<a href='" + FIND_OPTIONS_HREF_TARGET + "'>Find Options...</a>" + shortcutText;
+ }
+
+ @NotNull
+ private static String createSearchInProjectHtml() {
+ return "<a href='" + SEARCH_IN_PROJECT_HREF_TARGET + "'>Search in Project</a>";
+ }
+
+ private static void notifyByFindBalloon(final HyperlinkListener listener,
+ @NotNull final MessageType info,
+ @NotNull FindUsagesProcessPresentation processPresentation,
+ @NotNull final Project project,
+ @NotNull final List<String> lines) {
+ com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered
+
+ final Collection<PsiFile> largeFiles = processPresentation.getLargeFiles();
+ List<String> resultLines = new ArrayList<String>(lines);
+ HyperlinkListener resultListener = listener;
+ if (!largeFiles.isEmpty()) {
+ String shortMessage = "(<a href='" + LARGE_FILES_HREF_TARGET + "'>"
+ + UsageViewBundle.message("large.files.were.ignored", largeFiles.size()) + "</a>)";
+
+ resultLines.add(shortMessage);
+ resultListener = new HyperlinkAdapter(){
+ @Override
+ protected void hyperlinkActivated(HyperlinkEvent e) {
+ if (e.getDescription().equals(LARGE_FILES_HREF_TARGET)) {
+ String detailedMessage = detailedLargeFilesMessage(largeFiles);
+ List<String> strings = new ArrayList<String>(lines);
+ strings.add(detailedMessage);
+ ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
+ }
+ else if (listener != null) {
+ listener.hyperlinkUpdate(e);
+ }
+ }
+ };
+ }
+
+ ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener);
+ }
+
+ @NotNull
+ private static String wrapInHtml(@NotNull List<String> strings) {
+ return XmlStringUtil.wrapInHtml(StringUtil.join(strings, "<br>"));
+ }
+
+ @NotNull
+ private static String detailedLargeFilesMessage(@NotNull Collection<PsiFile> largeFiles) {
+ String message = "";
+ if (largeFiles.size() == 1) {
+ final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile();
+ message += "File " + presentableFileInfo(vFile) + " is ";
+ }
+ else {
+ message += "Files<br> ";
+
+ int counter = 0;
+ for (PsiFile file : largeFiles) {
+ final VirtualFile vFile = file.getVirtualFile();
+ message += presentableFileInfo(vFile) + "<br> ";
+ if (counter++ > 10) break;
+ }
+
+ message += "are ";
+ }
+
+ message += "too large and cannot be scanned";
+ return message;
+ }
+
+ @NotNull
+ private static String presentableFileInfo(@NotNull VirtualFile vFile) {
+ return getPresentablePath(vFile)
+ + "&nbsp;("
+ + UsageViewManagerImpl.presentableSize(UsageViewManagerImpl.getFileLength(vFile))
+ + ")";
+ }
+
+ @NotNull
+ private static String getPresentablePath(@NotNull final VirtualFile virtualFile) {
+ return "'" + ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return virtualFile.getPresentableUrl();
+ }
+ }) + "'";
+ }
+
+ @NotNull
+ private HyperlinkListener createGotToOptionsListener(@NotNull final UsageTarget[] targets) {
+ return new HyperlinkAdapter() {
+ @Override
+ protected void hyperlinkActivated(HyperlinkEvent e) {
+ if (e.getDescription().equals(FIND_OPTIONS_HREF_TARGET)) {
+ FindManager.getInstance(myProject).showSettingsAndFindUsages(targets);
+ }
+ }
+ };
+ }
+ @NotNull
+ private HyperlinkListener createSearchInProjectListener() {
+ return new HyperlinkAdapter() {
+ @Override
+ protected void hyperlinkActivated(HyperlinkEvent e) {
+ if (e.getDescription().equals(SEARCH_IN_PROJECT_HREF_TARGET)) {
+ PsiElement psiElement = getPsiElement(mySearchFor);
+ if (psiElement != null) {
+ FindManager.getInstance(myProject).findUsagesInScope(psiElement, GlobalSearchScope.projectScope(myProject));
+ }
+ }
+ }
+ };
+ }
+
+ private static PsiElement getPsiElement(UsageTarget[] searchFor) {
+ if (!(searchFor[0] instanceof PsiElementUsageTarget)) return null;
+ return ((PsiElementUsageTarget)searchFor[0]).getElement();
+ }
+
+ private static void flashUsageScriptaculously(@NotNull final Usage usage) {
+ if (!(usage instanceof UsageInfo2UsageAdapter)) {
+ return;
+ }
+ UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage;
+
+ Editor editor = usageInfo.openTextEditor(true);
+ if (editor == null) return;
+ TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
+
+ RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6);
+ List<Segment> segments = new ArrayList<Segment>();
+ CommonProcessors.CollectProcessor<Segment> processor = new CommonProcessors.CollectProcessor<Segment>(segments);
+ usageInfo.processRangeMarkers(processor);
+ rangeBlinker.resetMarkers(segments);
+ rangeBlinker.startBlinking();
+ }
+
+ private UsageViewImpl getUsageView(ProgressIndicator indicator) {
+ UsageViewImpl usageView = myUsageViewRef.get();
+ if (usageView != null) return usageView;
+ int usageCount = myUsageCountWithoutDefinition.get();
+ if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
+ usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
+ usageView.associateProgress(indicator);
+ if (myUsageViewRef.compareAndSet(null, usageView)) {
+ openView(usageView);
+ final Usage firstUsage = myFirstUsage.get();
+ if (firstUsage != null) {
+ final UsageViewImpl finalUsageView = usageView;
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ finalUsageView.appendUsage(firstUsage);
+ }
+ });
+ }
+ }
+ else {
+ Disposer.dispose(usageView);
+ }
+ return myUsageViewRef.get();
+ }
+ return null;
+ }
+
+ private void openView(@NotNull final UsageViewImpl usageView) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (myProject.isDisposed()) return;
+ myUsageViewManager.addContent(usageView, myPresentation);
+ if (myListener != null) {
+ myListener.usageViewCreated(usageView);
+ }
+ myUsageViewManager.showToolWindow(false);
+ }
+ });
+ }
+
+ @Override
+ public void run() {
+ AtomicBoolean findUsagesStartedShown = new AtomicBoolean();
+ searchUsages(findUsagesStartedShown);
+ endSearchForUsages(findUsagesStartedShown);
+ }
+
+ private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
+ ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
+ TooManyUsagesStatus.createFor(indicator);
+ Alarm findUsagesStartedBalloon = new Alarm();
+ findUsagesStartedBalloon.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, myProject,
+ Collections.singletonList(UsageViewManagerImpl.getProgressTitle(myPresentation)));
+ findStartedBalloonShown.set(true);
+ }
+ }, 300, ModalityState.NON_MODAL);
+ UsageSearcher usageSearcher = mySearcherFactory.create();
+
+ usageSearcher.generate(new Processor<Usage>() {
+ @Override
+ public boolean process(final Usage usage) {
+ ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
+ if (indicator != null && indicator.isCanceled()) return false;
+
+ if (!UsageViewManagerImpl.isInScope(usage, mySearchScope)) {
+ myOutOfScopeUsages.incrementAndGet();
+ return true;
+ }
+
+ boolean incrementCounter = !UsageViewManager.isSelfUsage(usage, mySearchFor);
+
+ if (incrementCounter) {
+ final int usageCount = myUsageCountWithoutDefinition.incrementAndGet();
+ if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
+ myFirstUsage.compareAndSet(null, usage);
+ }
+
+ final UsageViewImpl usageView = getUsageView(indicator);
+
+ TooManyUsagesStatus tooManyUsagesStatus;
+ if (usageCount > UsageLimitUtil.USAGES_LIMIT && (tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator)).switchTooManyUsagesStatus()) {
+ UsageViewManagerImpl.showTooManyUsagesWarning(myProject, tooManyUsagesStatus, indicator, myPresentation, usageCount, usageView);
+ }
+
+ if (usageView != null) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ usageView.appendUsage(usage);
+ }
+ });
+ }
+ }
+ return indicator == null || !indicator.isCanceled();
+ }
+ });
+ if (getUsageView(indicator) != null) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ myUsageViewManager.showToolWindow(true);
+ }
+ }, myProject.getDisposed());
+ }
+ Disposer.dispose(findUsagesStartedBalloon);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (findStartedBalloonShown.get()) {
+ Balloon balloon = ToolWindowManager.getInstance(myProject).getToolWindowBalloon(ToolWindowId.FIND);
+ if (balloon != null) {
+ balloon.hide();
+ }
+ }
+ }
+ }, myProject.getDisposed());
+ }
+
+ private void endSearchForUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
+ assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
+ int usageCount = myUsageCountWithoutDefinition.get();
+ if (usageCount == 0 && myProcessPresentation.isShowNotFoundMessage()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
+ final String message = UsageViewBundle.message("dialog.no.usages.found.in",
+ StringUtil.decapitalize(myPresentation.getUsagesString()),
+ myPresentation.getScopeText());
+
+ if (notFoundActions.isEmpty()) {
+ List<String> lines = new ArrayList<String>();
+ lines.add(StringUtil.escapeXml(message));
+ if (myOutOfScopeUsages.get() != 0) {
+ lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
+ }
+ if (myProcessPresentation.isShowFindOptionsPrompt()) {
+ lines.add(createOptionsHtml(mySearchFor));
+ }
+ MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
+ notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
+ type, myProcessPresentation, myProject, lines);
+ findStartedBalloonShown.set(false);
+ }
+ else {
+ List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
+ titles.add(UsageViewBundle.message("dialog.button.ok"));
+ for (Action action : notFoundActions) {
+ Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
+ if (value == null) value = action.getValue(Action.NAME);
+
+ titles.add((String)value);
+ }
+
+ int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
+ ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
+
+ if (option > 0) {
+ notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
+ }
+ }
+ }
+ }, ModalityState.NON_MODAL, myProject.getDisposed());
+ }
+ else if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ Usage usage = myFirstUsage.get();
+ if (usage.canNavigate()) {
+ usage.navigate(true);
+ flashUsageScriptaculously(usage);
+ }
+ List<String> lines = new ArrayList<String>();
+
+ lines.add("Only one usage found.");
+ if (myOutOfScopeUsages.get() != 0) {
+ lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
+ }
+ lines.add(createOptionsHtml(mySearchFor));
+ MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
+ notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
+ type, myProcessPresentation, myProject,
+ lines);
+ }
+ }, ModalityState.NON_MODAL, myProject.getDisposed());
+ }
+ else {
+ final UsageViewImpl usageView = myUsageViewRef.get();
+ if (usageView != null) {
+ usageView.drainQueuedUsageNodes();
+ usageView.setSearchInProgress(false);
+ }
+
+ final List<String> lines;
+ final HyperlinkListener hyperlinkListener;
+ if (myOutOfScopeUsages.get() == 0 || getPsiElement(mySearchFor)==null) {
+ lines = Collections.emptyList();
+ hyperlinkListener = null;
+ }
+ else {
+ lines = Arrays.asList(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope), createSearchInProjectHtml());
+ hyperlinkListener = createSearchInProjectListener();
+ }
+
+ if (!myProcessPresentation.getLargeFiles().isEmpty() || myOutOfScopeUsages.get() != 0) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
+ notifyByFindBalloon(hyperlinkListener, type, myProcessPresentation, myProject, lines);
+ }
+ }, ModalityState.NON_MODAL, myProject.getDisposed());
+ }
+ }
+
+ if (myListener != null) {
+ myListener.findingUsagesFinished(myUsageViewRef.get());
+ }
+ }
+}
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageAdapter.java b/platform/usageView/src/com/intellij/usages/impl/UsageAdapter.java
new file mode 100644
index 000000000000..1cd05c260999
--- /dev/null
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.usages.impl;
+
+import com.intellij.openapi.fileEditor.FileEditorLocation;
+import com.intellij.usages.Usage;
+import com.intellij.usages.UsagePresentation;
+import org.jetbrains.annotations.NotNull;
+
+public class UsageAdapter implements Usage {
+ @Override
+ @NotNull
+ public UsagePresentation getPresentation() {
+ throw new IllegalAccessError();
+ }
+
+ @Override
+ public boolean isValid() {
+ return false;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ @Override
+ public FileEditorLocation getLocation() {
+ return null;
+ }
+
+ @Override
+ public void selectInEditor() {
+
+ }
+
+ @Override
+ public void highlightInEditor() {
+
+ }
+
+ @Override
+ public void navigate(final boolean requestFocus) {
+
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return false;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return false;
+ }
+}
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
index 0e7bae22d452..6d7ce9c07a14 100644
--- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
@@ -15,60 +15,37 @@
*/
package com.intellij.usages.impl;
-import com.intellij.find.FindManager;
import com.intellij.find.SearchInBackgroundOption;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.openapi.actionSystem.DataSink;
+import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.colors.CodeInsightColors;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.util.TooManyUsagesStatus;
-import com.intellij.openapi.progress.util.ProgressWrapper;
import com.intellij.openapi.project.DumbModeAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.popup.Balloon;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.Factory;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.ui.HyperlinkAdapter;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.*;
-import com.intellij.util.Alarm;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.CommonProcessors;
-import com.intellij.util.Processor;
-import com.intellij.util.ui.RangeBlinker;
+import com.intellij.usages.rules.PsiElementUsage;
+import com.intellij.usages.rules.UsageInFile;
import com.intellij.util.ui.UIUtil;
-import com.intellij.xml.util.XmlStringUtil;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -77,8 +54,6 @@ import java.util.concurrent.atomic.AtomicReference;
public class UsageViewManagerImpl extends UsageViewManager {
private final Project myProject;
private static final Key<UsageView> USAGE_VIEW_KEY = Key.create("USAGE_VIEW");
- @NonNls private static final String LARGE_FILES_HREF_TARGET = "LargeFiles";
- @NonNls private static final String FIND_OPTIONS_HREF_TARGET = "FindOptions";
public UsageViewManagerImpl(@NotNull Project project) {
myProject = project;
@@ -114,7 +89,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
return showUsages(searchedFor, foundUsages, presentation, null);
}
- private void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) {
+ void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) {
Content content = com.intellij.usageView.UsageViewManager.getInstance(myProject).addContent(
presentation.getTabText(),
presentation.getTabName(),
@@ -135,19 +110,38 @@ public class UsageViewManagerImpl extends UsageViewManager {
final boolean showNotFoundMessage,
@NotNull final UsageViewPresentation presentation,
@Nullable final UsageViewStateListener listener) {
- final AtomicReference<UsageViewImpl> usageViewRef = new AtomicReference<UsageViewImpl>();
-
final FindUsagesProcessPresentation processPresentation = new FindUsagesProcessPresentation(presentation);
processPresentation.setShowNotFoundMessage(showNotFoundMessage);
processPresentation.setShowPanelIfOnlyOneUsage(showPanelIfOnlyOneUsage);
+ return doSearchAndShow(searchFor, searcherFactory, presentation, processPresentation, listener);
+ }
+
+ private UsageView doSearchAndShow(@NotNull final UsageTarget[] searchFor,
+ @NotNull final Factory<UsageSearcher> searcherFactory,
+ @NotNull final UsageViewPresentation presentation,
+ @NotNull final FindUsagesProcessPresentation processPresentation,
+ @Nullable final UsageViewStateListener listener) {
+ final SearchScope searchScope = getSearchScope(searchFor);
+ return doSearchAndShow(searchFor, searcherFactory, presentation, processPresentation, listener, searchScope);
+ }
+
+ UsageView doSearchAndShow(@NotNull final UsageTarget[] searchFor,
+ @NotNull final Factory<UsageSearcher> searcherFactory,
+ @NotNull final UsageViewPresentation presentation,
+ @NotNull final FindUsagesProcessPresentation processPresentation,
+ @Nullable final UsageViewStateListener listener,
+ @NotNull final SearchScope searchScope) {
+ final AtomicReference<UsageViewImpl> usageViewRef = new AtomicReference<UsageViewImpl>();
+
Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
- new SearchForUsagesRunnable(UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory,
- processPresentation, listener).run();
+ new SearchForUsagesRunnable(UsageViewManagerImpl.this, UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory,
+ processPresentation, searchScope, listener).run();
}
+ @NotNull
@Override
public DumbModeAction getDumbModeAction() {
return DumbModeAction.CANCEL;
@@ -164,38 +158,29 @@ public class UsageViewManagerImpl extends UsageViewManager {
return usageViewRef.get();
}
+ @NotNull
+ private SearchScope getSearchScope(@NotNull UsageTarget[] searchFor) {
+ UsageTarget target = searchFor[0];
+ if (target instanceof TypeSafeDataProvider) {
+ final SearchScope[] scope = new SearchScope[1];
+ ((TypeSafeDataProvider)target).calcData(UsageView.USAGE_SCOPE, new DataSink() {
+ @Override
+ public <T> void put(DataKey<T> key, T data) {
+ scope[0] = (SearchScope)data;
+ }
+ });
+ return scope[0];
+ }
+ return GlobalSearchScope.projectScope(myProject);
+ }
+
@Override
public void searchAndShowUsages(@NotNull UsageTarget[] searchFor,
@NotNull Factory<UsageSearcher> searcherFactory,
@NotNull FindUsagesProcessPresentation processPresentation,
@NotNull UsageViewPresentation presentation,
@Nullable UsageViewStateListener listener) {
- final AtomicReference<UsageViewImpl> usageView = new AtomicReference<UsageViewImpl>();
- final SearchForUsagesRunnable runnable = new SearchForUsagesRunnable(myProject, usageView, presentation, searchFor, searcherFactory, processPresentation, listener);
- final Factory<ProgressIndicator> progressIndicatorFactory = processPresentation.getProgressIndicatorFactory();
-
- final ProgressIndicator progressIndicator = progressIndicatorFactory != null ? progressIndicatorFactory.create() : null;
-
- final AtomicBoolean findUsagesStartedShown = new AtomicBoolean();
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- try {
- ProgressManager.getInstance().runProcess(new Runnable() {
- @Override
- public void run() {
- runnable.searchUsages(findUsagesStartedShown);
- }
- }, progressIndicator);
- }
- catch (ProcessCanceledException e) {
- //ignore
- }
- finally {
- runnable.endSearchForUsages(findUsagesStartedShown);
- }
- }
- });
+ doSearchAndShow(searchFor, searcherFactory, presentation, processPresentation, listener);
}
@Override
@@ -212,13 +197,11 @@ public class UsageViewManagerImpl extends UsageViewManager {
public static String getProgressTitle(@NotNull UsageViewPresentation presentation) {
final String scopeText = presentation.getScopeText();
String usagesString = StringUtil.capitalize(presentation.getUsagesString());
- String result = scopeText == null
- ? UsageViewBundle.message("progress.searching.for", usagesString)
- : UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
+ String result = UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
return StringUtil.escapeXml(result);
}
- private void showToolWindow(boolean activateWindow) {
+ void showToolWindow(boolean activateWindow) {
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND);
toolWindow.show(null);
if (activateWindow && !toolWindow.isActive()) {
@@ -259,305 +242,6 @@ public class UsageViewManagerImpl extends UsageViewManager {
});
}
- private class SearchForUsagesRunnable implements Runnable {
- private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0);
- private final AtomicReference<Usage> myFirstUsage = new AtomicReference<Usage>();
- @NotNull
- private final Project myProject;
- private final AtomicReference<UsageViewImpl> myUsageViewRef;
- private final UsageViewPresentation myPresentation;
- private final UsageTarget[] mySearchFor;
- private final Factory<UsageSearcher> mySearcherFactory;
- private final FindUsagesProcessPresentation myProcessPresentation;
- private final UsageViewStateListener myListener;
-
- private SearchForUsagesRunnable(@NotNull Project project,
- @NotNull AtomicReference<UsageViewImpl> usageViewRef,
- @NotNull UsageViewPresentation presentation,
- @NotNull UsageTarget[] searchFor,
- @NotNull Factory<UsageSearcher> searcherFactory,
- @NotNull FindUsagesProcessPresentation processPresentation,
- @Nullable UsageViewStateListener listener) {
- myProject = project;
- myUsageViewRef = usageViewRef;
- myPresentation = presentation;
- mySearchFor = searchFor;
- mySearcherFactory = searcherFactory;
- myProcessPresentation = processPresentation;
- myListener = listener;
- }
-
- private UsageViewImpl getUsageView(ProgressIndicator indicator) {
- UsageViewImpl usageView = myUsageViewRef.get();
- if (usageView != null) return usageView;
- int usageCount = myUsageCountWithoutDefinition.get();
- if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
- usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
- usageView.associateProgress(indicator);
- if (myUsageViewRef.compareAndSet(null, usageView)) {
- openView(usageView);
- final Usage firstUsage = myFirstUsage.get();
- if (firstUsage != null) {
- final UsageViewImpl finalUsageView = usageView;
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- finalUsageView.appendUsage(firstUsage);
- }
- });
- }
- }
- else {
- Disposer.dispose(usageView);
- }
- return myUsageViewRef.get();
- }
- return null;
- }
-
- private void openView(@NotNull final UsageViewImpl usageView) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if (myProject.isDisposed()) return;
- addContent(usageView, myPresentation);
- if (myListener != null) {
- myListener.usageViewCreated(usageView);
- }
- showToolWindow(false);
- }
- });
- }
-
- @Override
- public void run() {
- AtomicBoolean findUsagesStartedShown = new AtomicBoolean();
- searchUsages(findUsagesStartedShown);
- endSearchForUsages(findUsagesStartedShown);
- }
-
- private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
- ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
- TooManyUsagesStatus.createFor(indicator);
- Alarm findUsagesStartedBalloon = new Alarm();
- findUsagesStartedBalloon.addRequest(new Runnable() {
- @Override
- public void run() {
- String balloon = UsageViewBundle.message("progress.searching.for", StringUtil.escapeXml(myPresentation.getUsagesString()));
- notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, UsageViewManagerImpl.this.myProject,
- balloon);
- findStartedBalloonShown.set(true);
- }
- }, 300, ModalityState.NON_MODAL);
- UsageSearcher usageSearcher = mySearcherFactory.create();
-
- usageSearcher.generate(new Processor<Usage>() {
- @Override
- public boolean process(final Usage usage) {
- ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
- if (indicator != null && indicator.isCanceled()) return false;
- TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator);
- boolean incrementCounter = !isSelfUsage(usage, mySearchFor);
-
- if (incrementCounter) {
- final int usageCount = myUsageCountWithoutDefinition.incrementAndGet();
- if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
- myFirstUsage.compareAndSet(null, usage);
- }
-
- final UsageViewImpl usageView = getUsageView(indicator);
-
- if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsagesStatus.switchTooManyUsagesStatus()) {
- showTooManyUsagesWarning(myProject, tooManyUsagesStatus, indicator, myPresentation, usageCount, usageView);
- }
-
- if (usageView != null) {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- usageView.appendUsage(usage);
- }
- });
- }
- }
- return indicator == null || !indicator.isCanceled();
- }
- });
- if (getUsageView(indicator) != null) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- showToolWindow(true);
- }
- }, myProject.getDisposed());
- }
- Disposer.dispose(findUsagesStartedBalloon);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- if (findStartedBalloonShown.get()) {
- Balloon balloon = ToolWindowManager.getInstance(myProject).getToolWindowBalloon(ToolWindowId.FIND);
- if (balloon != null) {
- balloon.hide();
- }
- }
- }
- }, myProject.getDisposed());
- }
-
- private void endSearchForUsages(@NotNull final AtomicBoolean findStartedBalloonShown) {
- assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
- int usageCount = myUsageCountWithoutDefinition.get();
- if (usageCount == 0 && myProcessPresentation.isShowNotFoundMessage()) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- final List<Action> notFoundActions = myProcessPresentation.getNotFoundActions();
- final String message = UsageViewBundle.message("dialog.no.usages.found.in",
- StringUtil.decapitalize(myPresentation.getUsagesString()),
- myPresentation.getScopeText());
-
- if (notFoundActions.isEmpty()) {
- String[] lines = myProcessPresentation.isShowFindOptionsPrompt() ? new String[] {StringUtil.escapeXml(message), createOptionsHtml(mySearchFor)} : new String[]{StringUtil.escapeXml(message)};
- notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
- MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject, lines);
- findStartedBalloonShown.set(false);
- }
- else {
- List<String> titles = new ArrayList<String>(notFoundActions.size() + 1);
- titles.add(UsageViewBundle.message("dialog.button.ok"));
- for (Action action : notFoundActions) {
- Object value = action.getValue(FindUsagesProcessPresentation.NAME_WITH_MNEMONIC_KEY);
- if (value == null) value = action.getValue(Action.NAME);
-
- titles.add((String)value);
- }
-
- int option = Messages.showDialog(myProject, message, UsageViewBundle.message("dialog.title.information"),
- ArrayUtil.toStringArray(titles), 0, Messages.getInformationIcon());
-
- if (option > 0) {
- notFoundActions.get(option - 1).actionPerformed(new ActionEvent(this, 0, titles.get(option)));
- }
- }
- }
- }, ModalityState.NON_MODAL, myProject.getDisposed());
- }
- else if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- Usage usage = myFirstUsage.get();
- if (usage.canNavigate()) {
- usage.navigate(true);
- flashUsageScriptaculously(usage);
- }
- notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
- MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Only one usage found.", createOptionsHtml(
- mySearchFor));
- }
- }, ModalityState.NON_MODAL, myProject.getDisposed());
- }
- else {
- final UsageViewImpl usageView = myUsageViewRef.get();
- if (usageView != null) {
- usageView.drainQueuedUsageNodes();
- usageView.setSearchInProgress(false);
- }
- if (!myProcessPresentation.getLargeFiles().isEmpty()) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- notifyByFindBalloon(null, MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject);
- }
- }, ModalityState.NON_MODAL, myProject.getDisposed());
- }
- }
-
- if (myListener != null) {
- myListener.findingUsagesFinished(myUsageViewRef.get());
- }
- }
- }
-
- private static void notifyByFindBalloon(final HyperlinkListener listener,
- @NotNull final MessageType info,
- @NotNull FindUsagesProcessPresentation processPresentation,
- @NotNull final Project project,
- @NotNull String... sLines) {
- com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered
-
- final List<String> lines = new ArrayList<String>(Arrays.asList(sLines));
- final Collection<PsiFile> largeFiles = processPresentation.getLargeFiles();
- List<String> resultLines = new ArrayList<String>(lines);
- HyperlinkListener resultListener = listener;
- if (!largeFiles.isEmpty()) {
- String shortMessage = "(<a href='" + LARGE_FILES_HREF_TARGET + "'>"
- + UsageViewBundle.message("large.files.were.ignored", largeFiles.size()) + "</a>)";
-
- resultLines.add(shortMessage);
- resultListener = new HyperlinkAdapter(){
- @Override
- protected void hyperlinkActivated(HyperlinkEvent e) {
- if (e.getDescription().equals(LARGE_FILES_HREF_TARGET)) {
- String detailedMessage = detailedLargeFilesMessage(largeFiles);
- List<String> strings = new ArrayList<String>(lines);
- strings.add(detailedMessage);
- ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
- }
- else if (listener != null) {
- listener.hyperlinkUpdate(e);
- }
- }
- };
- }
-
- ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener);
- }
-
- @NotNull
- private static String wrapInHtml(@NotNull List<String> strings) {
- return XmlStringUtil.wrapInHtml(StringUtil.join(strings, "<br>"));
- }
-
- @NotNull
- private static String detailedLargeFilesMessage(@NotNull Collection<PsiFile> largeFiles) {
- String message = "";
- if (largeFiles.size() == 1) {
- final VirtualFile vFile = largeFiles.iterator().next().getVirtualFile();
- message += "File " + presentableFileInfo(vFile) + " is ";
- }
- else {
- message += "Files<br> ";
-
- int counter = 0;
- for (PsiFile file : largeFiles) {
- final VirtualFile vFile = file.getVirtualFile();
- message += presentableFileInfo(vFile) + "<br> ";
- if (counter++ > 10) break;
- }
-
- message += "are ";
- }
-
- message += "too large and cannot be scanned";
- return message;
- }
-
- @NotNull
- private static String presentableFileInfo(@NotNull VirtualFile vFile) {
- return getPresentablePath(vFile)
- + "&nbsp;("
- + presentableSize(getFileLength(vFile))
- + ")";
- }
-
- @NotNull
- public static String presentableSize(long bytes) {
- long megabytes = bytes / (1024 * 1024);
- return UsageViewBundle.message("find.file.size.megabytes", Long.toString(megabytes));
- }
-
public static long getFileLength(@NotNull final VirtualFile virtualFile) {
final long[] length = {-1L};
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -572,52 +256,22 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
@NotNull
- private static String getPresentablePath(@NotNull final VirtualFile virtualFile) {
- return "'" + ApplicationManager.getApplication().runReadAction(new Computable<String>() {
- @Override
- public String compute() {
- return virtualFile.getPresentableUrl();
- }
- }) + "'";
+ public static String presentableSize(long bytes) {
+ long megabytes = bytes / (1024 * 1024);
+ return UsageViewBundle.message("find.file.size.megabytes", Long.toString(megabytes));
}
- @NotNull
- private HyperlinkListener createGotToOptionsListener(@NotNull final UsageTarget[] targets) {
- return new HyperlinkAdapter() {
- @Override
- protected void hyperlinkActivated(HyperlinkEvent e) {
- if (e.getDescription().equals(FIND_OPTIONS_HREF_TARGET)) {
- FindManager.getInstance(myProject).showSettingsAndFindUsages(targets);
- }
- }
- };
+ public static boolean isInScope(@NotNull Usage usage, @NotNull SearchScope searchScope) {
+ VirtualFile file = usage instanceof UsageInFile ? ((UsageInFile)usage).getFile() : usage instanceof PsiElementUsage ? PsiUtilCore
+ .getVirtualFile(((PsiElementUsage)usage).getElement()) : null;
+ return file != null && (searchScope instanceof LocalSearchScope
+ ? ((LocalSearchScope)searchScope).isInScope(file) : ((GlobalSearchScope)searchScope).contains(file));
}
@NotNull
- private static String createOptionsHtml(@NonNls UsageTarget[] searchFor) {
- KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(searchFor);
- String shortcutText = "";
- if (shortcut != null) {
- shortcutText = "&nbsp;(" + KeymapUtil.getShortcutText(shortcut) + ")";
- }
- return "<a href='" + FIND_OPTIONS_HREF_TARGET + "'>Find Options...</a>" + shortcutText;
+ public static String outOfScopeMessage(int nUsages, @NotNull SearchScope searchScope) {
+ return (nUsages == 1 ? "One usage is" : nUsages + " usages are") +
+ " out of scope '"+ searchScope.getDisplayName()+"'";
}
- private static void flashUsageScriptaculously(@NotNull final Usage usage) {
- if (!(usage instanceof UsageInfo2UsageAdapter)) {
- return;
- }
- UsageInfo2UsageAdapter usageInfo = (UsageInfo2UsageAdapter)usage;
-
- Editor editor = usageInfo.openTextEditor(true);
- if (editor == null) return;
- TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.BLINKING_HIGHLIGHTS_ATTRIBUTES);
-
- RangeBlinker rangeBlinker = new RangeBlinker(editor, attributes, 6);
- List<Segment> segments = new ArrayList<Segment>();
- CommonProcessors.CollectProcessor<Segment> processor = new CommonProcessors.CollectProcessor<Segment>(segments);
- usageInfo.processRangeMarkers(processor);
- rangeBlinker.resetMarkers(segments);
- rangeBlinker.startBlinking();
- }
}
diff --git a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java
index 6c807c2e7276..8b6e353fdbea 100644
--- a/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/text/StringUtilRt.java
@@ -92,6 +92,11 @@ public class StringUtilRt {
}
@NotNull
+ public static CharSequence convertLineSeparators(@NotNull CharSequence text, @NotNull String newSeparator) {
+ return unifyLineSeparators(text, newSeparator, null, false);
+ }
+
+ @NotNull
public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator, @Nullable int[] offsetsToKeep) {
return convertLineSeparators(text, newSeparator, offsetsToKeep, false);
}
diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java
index d69be14f0866..edbf8e2b8496 100644
--- a/platform/util/src/com/intellij/Patches.java
+++ b/platform/util/src/com/intellij/Patches.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -145,4 +145,10 @@ public class Patches {
* which need to be changed when migrated to JDK 7
*/
public static final boolean USE_REFLECTION_TO_ACCESS_JDK7 = true;
+
+ /**
+ * AtomicIntegerFieldUpdater does not work when SecurityManager is installed
+ * fixed in JDK8
+ */
+ public static final boolean JDK_BUG_ID_7103570 = true;
}
diff --git a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java
index 5aa77f814d5b..69c8ce5425f1 100644
--- a/platform/util/src/com/intellij/execution/process/UnixProcessManager.java
+++ b/platform/util/src/com/intellij/execution/process/UnixProcessManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.Processor;
+import com.intellij.util.ReflectionUtil;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
@@ -27,7 +28,6 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.lang.reflect.Field;
import java.util.*;
/**
@@ -60,14 +60,9 @@ public class UnixProcessManager {
public static int getProcessPid(Process process) {
try {
- Field f = process.getClass().getDeclaredField("pid");
- f.setAccessible(true);
- return ((Number)f.get(process)).intValue();
+ return ReflectionUtil.getField(process.getClass(), process, int.class, "pid");
}
- catch (NoSuchFieldException e) {
- throw new IllegalStateException("system is not unix", e);
- }
- catch (IllegalAccessException e) {
+ catch (Exception e) {
throw new IllegalStateException("system is not unix", e);
}
}
diff --git a/platform/util/src/com/intellij/execution/process/WinProcessManager.java b/platform/util/src/com/intellij/execution/process/WinProcessManager.java
index d2df82eab7e8..5b7ef5e100d1 100644
--- a/platform/util/src/com/intellij/execution/process/WinProcessManager.java
+++ b/platform/util/src/com/intellij/execution/process/WinProcessManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,12 +15,11 @@
*/
package com.intellij.execution.process;
+import com.intellij.util.ReflectionUtil;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
-import java.lang.reflect.Field;
-
/**
* @author Alexey.Ushakov
*/
@@ -37,9 +36,7 @@ public class WinProcessManager {
if (process.getClass().getName().equals("java.lang.Win32Process") ||
process.getClass().getName().equals("java.lang.ProcessImpl")) {
try {
- Field f = process.getClass().getDeclaredField("handle");
- f.setAccessible(true);
- long handle = f.getLong(process);
+ long handle = ReflectionUtil.getField(process.getClass(), process, long.class, "handle");
Kernel32 kernel = Kernel32.INSTANCE;
WinNT.HANDLE winHandle = new WinNT.HANDLE();
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index eceeda209295..9d10f4136383 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -177,6 +177,7 @@ public class AllIcons {
public static final Icon Atrule = IconLoader.getIcon("/css/atrule.png"); // 16x16
public static final Icon Import = IconLoader.getIcon("/css/import.png"); // 16x16
public static final Icon Property = IconLoader.getIcon("/css/property.png"); // 16x16
+ public static final Icon Pseudo_class = IconLoader.getIcon("/css/pseudo-class.png"); // 16x16
public static final Icon Pseudo_element = IconLoader.getIcon("/css/pseudo-element.png"); // 16x16
public static final Icon Toolwindow = IconLoader.getIcon("/css/toolwindow.png"); // 13x13
@@ -769,6 +770,7 @@ public class AllIcons {
public static final Icon DataTables = IconLoader.getIcon("/nodes/DataTables.png"); // 16x16
public static final Icon DataView = IconLoader.getIcon("/nodes/dataView.png"); // 16x16
public static final Icon Deploy = IconLoader.getIcon("/nodes/deploy.png"); // 16x16
+ public static final Icon Desktop = IconLoader.getIcon("/nodes/desktop.png"); // 16x16
public static final Icon Ejb = IconLoader.getIcon("/nodes/ejb.png"); // 16x16
public static final Icon EjbBusinessMethod = IconLoader.getIcon("/nodes/ejbBusinessMethod.png"); // 16x16
public static final Icon EjbCmpField = IconLoader.getIcon("/nodes/ejbCmpField.png"); // 16x16
@@ -836,6 +838,7 @@ public class AllIcons {
public static final Icon PinToolWindow = IconLoader.getIcon("/nodes/pinToolWindow.png"); // 13x13
public static final Icon Plugin = IconLoader.getIcon("/nodes/plugin.png"); // 16x16
public static final Icon PluginJB = IconLoader.getIcon("/nodes/pluginJB.png"); // 16x16
+ public static final Icon PluginLogo = IconLoader.getIcon("/nodes/pluginLogo.png"); // 32x32
public static final Icon Pluginnotinstalled = IconLoader.getIcon("/nodes/pluginnotinstalled.png"); // 16x16
public static final Icon Pluginobsolete = IconLoader.getIcon("/nodes/pluginobsolete.png"); // 16x16
public static final Icon PluginRestart = IconLoader.getIcon("/nodes/pluginRestart.png"); // 16x16
@@ -848,6 +851,7 @@ public class AllIcons {
public static final Icon PpLib = IconLoader.getIcon("/nodes/ppLib.png"); // 16x16
public static final Icon PpLibFolder = IconLoader.getIcon("/nodes/ppLibFolder.png"); // 16x16
public static final Icon PpWeb = IconLoader.getIcon("/nodes/ppWeb.png"); // 16x16
+ public static final Icon PpWebLogo = IconLoader.getIcon("/nodes/ppWebLogo.png"); // 32x32
public static final Icon Project = IconLoader.getIcon("/nodes/project.png"); // 16x16
public static final Icon Property = IconLoader.getIcon("/nodes/property.png"); // 16x16
public static final Icon PropertyRead = IconLoader.getIcon("/nodes/propertyRead.png"); // 16x16
diff --git a/platform/util/src/com/intellij/ide/ClassUtilCore.java b/platform/util/src/com/intellij/ide/ClassUtilCore.java
index ac5740927408..3e2d53e05e3f 100644
--- a/platform/util/src/com/intellij/ide/ClassUtilCore.java
+++ b/platform/util/src/com/intellij/ide/ClassUtilCore.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,23 +15,18 @@
*/
package com.intellij.ide;
-import org.jetbrains.annotations.NonNls;
-
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
public class ClassUtilCore {
- @NonNls static final String FILE_CACHE = "fileCache";
- @NonNls static final String URL_CACHE = "urlCache";// See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4167874
-
public static void clearJarURLCache() {
try {
Class jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory");
- clearMap(jarFileFactory.getDeclaredField(FILE_CACHE));
- clearMap(jarFileFactory.getDeclaredField(URL_CACHE));
+ clearMap(jarFileFactory.getDeclaredField("fileCache"));
+ clearMap(jarFileFactory.getDeclaredField("urlCache"));
}
catch (Exception ignore) {
// Do nothing.
diff --git a/platform/util/src/com/intellij/openapi/util/SystemInfo.java b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
index cd85b568b919..ef1acead508d 100644
--- a/platform/util/src/com/intellij/openapi/util/SystemInfo.java
+++ b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
@@ -139,6 +139,7 @@ public class SystemInfo extends SystemInfoRt {
public static final boolean isMacOSLion = isMac && isOsVersionAtLeast("10.7");
public static final boolean isMacOSMountainLion = isMac && isOsVersionAtLeast("10.8");
public static final boolean isMacOSMavericks = isMac && isOsVersionAtLeast("10.9");
+ public static final boolean isMacOSYosemite = isMac && isOsVersionAtLeast("10.10");
@NotNull
public static String getMacOSMajorVersion() {
diff --git a/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java b/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java
index 1f1b0b475a94..8fa7c3ae7544 100644
--- a/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java
+++ b/platform/util/src/com/intellij/openapi/util/UserDataHolderBase.java
@@ -34,7 +34,7 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
protected Object clone() {
try {
UserDataHolderBase clone = (UserDataHolderBase)super.clone();
- clone.myUserMap = KeyFMap.EMPTY_MAP;
+ clone.setUserMap(KeyFMap.EMPTY_MAP);
copyCopyableDataTo(clone);
return clone;
}
@@ -45,32 +45,41 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
@TestOnly
public String getUserDataString() {
- final KeyFMap userMap = myUserMap;
+ final KeyFMap userMap = getUserMap();
final KeyFMap copyableMap = getUserData(COPYABLE_USER_MAP_KEY);
return userMap.toString() + (copyableMap == null ? "" : copyableMap.toString());
}
public void copyUserDataTo(UserDataHolderBase other) {
- other.myUserMap = myUserMap;
+ other.setUserMap(getUserMap());
}
@Override
public <T> T getUserData(@NotNull Key<T> key) {
//noinspection unchecked
- return myUserMap.get(key);
+ return getUserMap().get(key);
+ }
+
+ @NotNull
+ protected KeyFMap getUserMap() {
+ return myUserMap;
}
@Override
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
while (true) {
- KeyFMap map = myUserMap;
+ KeyFMap map = getUserMap();
KeyFMap newMap = value == null ? map.minus(key) : map.plus(key, value);
- if (newMap == map || updater.compareAndSet(this, map, newMap)) {
+ if (newMap == map || changeUserMap(map, newMap)) {
break;
}
}
}
+ protected boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
+ return updater.compareAndSet(this, oldMap, newMap);
+ }
+
public <T> T getCopyableUserData(Key<T> key) {
KeyFMap map = getUserData(COPYABLE_USER_MAP_KEY);
//noinspection unchecked,ConstantConditions
@@ -79,14 +88,14 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
public <T> void putCopyableUserData(Key<T> key, T value) {
while (true) {
- KeyFMap map = myUserMap;
+ KeyFMap map = getUserMap();
KeyFMap copyableMap = map.get(COPYABLE_USER_MAP_KEY);
if (copyableMap == null) {
copyableMap = KeyFMap.EMPTY_MAP;
}
KeyFMap newCopyableMap = value == null ? copyableMap.minus(key) : copyableMap.plus(key, value);
KeyFMap newMap = newCopyableMap.isEmpty() ? map.minus(COPYABLE_USER_MAP_KEY) : map.plus(COPYABLE_USER_MAP_KEY, newCopyableMap);
- if (newMap == map || updater.compareAndSet(this, map, newMap)) {
+ if (newMap == map || changeUserMap(map, newMap)) {
return;
}
}
@@ -95,12 +104,12 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
@Override
public <T> boolean replace(@NotNull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
while (true) {
- KeyFMap map = myUserMap;
+ KeyFMap map = getUserMap();
if (map.get(key) != oldValue) {
return false;
}
KeyFMap newMap = newValue == null ? map.minus(key) : map.plus(key, newValue);
- if (newMap == map || updater.compareAndSet(this, map, newMap)) {
+ if (newMap == map || changeUserMap(map, newMap)) {
return true;
}
}
@@ -110,13 +119,13 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
@NotNull
public <T> T putUserDataIfAbsent(@NotNull final Key<T> key, @NotNull final T value) {
while (true) {
- KeyFMap map = myUserMap;
+ KeyFMap map = getUserMap();
T oldValue = map.get(key);
if (oldValue != null) {
return oldValue;
}
KeyFMap newMap = map.plus(key, value);
- if (newMap == map || updater.compareAndSet(this, map, newMap)) {
+ if (newMap == map || changeUserMap(map, newMap)) {
return value;
}
}
@@ -127,11 +136,15 @@ public class UserDataHolderBase implements UserDataHolderEx, Cloneable {
}
protected void clearUserData() {
- myUserMap = KeyFMap.EMPTY_MAP;
+ setUserMap(KeyFMap.EMPTY_MAP);
+ }
+
+ protected void setUserMap(KeyFMap map) {
+ myUserMap = map;
}
public boolean isUserDataEmpty() {
- return myUserMap.isEmpty();
+ return getUserMap().isEmpty();
}
private static final AtomicFieldUpdater<UserDataHolderBase, KeyFMap> updater = AtomicFieldUpdater.forFieldOfType(UserDataHolderBase.class, KeyFMap.class);
diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
index 76956730cf81..fa67b7462bec 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -773,11 +773,43 @@ public class FileUtil extends FileUtilRt {
*/
@NotNull
public static String normalize(@NotNull String path) {
- final StringBuilder result = new StringBuilder(path.length());
-
int start = 0;
boolean separator = false;
- if (SystemInfo.isWindows && (path.startsWith("//") || path.startsWith("\\\\"))) {
+ if (SystemInfo.isWindows) {
+ if (path.startsWith("//")) {
+ start = 2;
+ separator = true;
+ }
+ else if (path.startsWith("\\\\")) {
+ return normalizeTail(0, path, false);
+ }
+ }
+
+ for (int i = start; i < path.length(); ++i) {
+ final char c = path.charAt(i);
+ if (c == '/') {
+ if (separator) {
+ return normalizeTail(i, path, true);
+ }
+ separator = true;
+ }
+ else if (c == '\\') {
+ return normalizeTail(i, path, separator);
+ }
+ else {
+ separator = false;
+ }
+ }
+
+ return path;
+ }
+
+ @NotNull
+ private static String normalizeTail(int prefixEnd, @NotNull String path, boolean separator) {
+ final StringBuilder result = new StringBuilder(path.length());
+ result.append(path, 0, prefixEnd);
+ int start = prefixEnd;
+ if (start==0 && SystemInfo.isWindows && (path.startsWith("//") || path.startsWith("\\\\"))) {
start = 2;
result.append("//");
separator = true;
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index 859b75ef267b..7ee904c1f344 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -101,12 +101,12 @@ public class StringUtil extends StringUtilRt {
};
@NotNull
- public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @Nullable String newS) {
+ public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
return replace(text, oldS, newS, false);
}
@NotNull
- public static String replaceIgnoreCase(@NotNull String text, @NotNull String oldS, @Nullable String newS) {
+ public static String replaceIgnoreCase(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
return replace(text, oldS, newS, true);
}
@@ -139,23 +139,20 @@ public class StringUtil extends StringUtilRt {
return newBuffer == null ? buffer : newBuffer.toString();
}
- public static String replace(@NotNull final String text, @NotNull final String oldS, @Nullable final String newS, boolean ignoreCase) {
+ public static String replace(@NonNls @NotNull final String text, @NonNls @NotNull final String oldS, @NonNls @NotNull final String newS, final boolean ignoreCase) {
if (text.length() < oldS.length()) return text;
- final String text1 = ignoreCase ? text.toLowerCase() : text;
- final String oldS1 = ignoreCase ? oldS.toLowerCase() : oldS;
StringBuilder newText = null;
int i = 0;
- while (i < text1.length()) {
- int i1 = text1.indexOf(oldS1, i);
+ while (i < text.length()) {
+ final int i1 = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
if (i1 < 0) {
if (i == 0) return text;
newText.append(text, i, text.length());
break;
}
else {
- if (newS == null) return null;
if (newText == null) newText = new StringBuilder(text.length() - i);
newText.append(text, i, i1);
newText.append(newS);
@@ -522,7 +519,7 @@ public class StringUtil extends StringUtilRt {
else if (additionalChars != null && additionalChars.indexOf(ch) > -1 && (escapeSlash || prev != '\\')) {
buffer.append("\\").append(ch);
}
- else if (Character.isISOControl(ch)) {
+ else if (!isPrintableUnicode(ch)) {
String hexCode = StringUtilRt.toUpperCase(Integer.toHexString(ch));
buffer.append("\\u");
int paddingCount = 4 - hexCode.length();
@@ -540,6 +537,12 @@ public class StringUtil extends StringUtilRt {
return buffer;
}
+ private static boolean isPrintableUnicode(char c) {
+ int t = Character.getType(c);
+ return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR &&
+ t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE;
+ }
+
@NotNull
public static String escapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
index 1c490fa8a555..23afc188dfbd 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.codeStyle;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.FList;
@@ -31,6 +32,7 @@ import java.util.Iterator;
* @author peter
*/
public class MinusculeMatcher implements Matcher {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.MinusculeMatcher");
/**
* Lowercase humps don't work for parts separated by these characters
* Need either an explicit uppercase letter or the same separator character in prefix
@@ -137,6 +139,10 @@ public class MinusculeMatcher implements Matcher {
}
public int matchingDegree(@NotNull String name) {
+ return matchingDegree(name, false);
+ }
+
+ public int matchingDegree(@NotNull String name, boolean valueStartCaseMatch) {
FList<TextRange> iterable = matchingFragments(name);
if (iterable == null) return Integer.MIN_VALUE;
if (iterable.isEmpty()) return 0;
@@ -176,7 +182,7 @@ public class MinusculeMatcher implements Matcher {
else if (isHumpStart) matchingCase += 1; // if a lowercase matches lowercase hump start, that also means something
} else if (isHumpStart) {
// disfavor hump starts where pattern letter case doesn't match name case
- matchingCase -= 20;
+ matchingCase -= 1;
}
}
}
@@ -188,8 +194,9 @@ public class MinusculeMatcher implements Matcher {
return (wordStart ? 1000 : 0) +
integral * 10 +
- matchingCase * (startMatch ? 10 : 1) + // in start matches, case is more important; in middle matches - fragment length (integral)
+ matchingCase * (startMatch && valueStartCaseMatch ? 10 : 1) +
(afterSeparator ? 0 : 2) +
+ (startMatch ? 1 : 0) +
(finalMatch ? 1 : 0);
}
@@ -213,7 +220,7 @@ public class MinusculeMatcher implements Matcher {
}
@Nullable
- public FList<TextRange> matchingFragments(@NotNull String name) {
+ private FList<TextRange> calcMatchingFragments(@NotNull String name) {
MatchingState state = myMatchingState.get();
state.initializeState(name);
try {
@@ -224,6 +231,22 @@ public class MinusculeMatcher implements Matcher {
}
}
+ @Nullable
+ public FList<TextRange> matchingFragments(@NotNull String name) {
+ long start = System.currentTimeMillis();
+ FList<TextRange> result = calcMatchingFragments(name);
+ if (System.currentTimeMillis() - start > 1000 &&
+ // if there's little free memory, it might have been the gc affecting the performance
+ Runtime.getRuntime().freeMemory() > Runtime.getRuntime().totalMemory() * 3 / 10) {
+ start = System.currentTimeMillis();
+ calcMatchingFragments(name);
+ if (System.currentTimeMillis() - start > 1000) {
+ LOG.error("Too long name matching: name=" + name + "; prefix=" + new String(myPattern));
+ }
+ }
+ return result;
+ }
+
/**
* After a wildcard (* or space), search for the first non-wildcard pattern character in the name starting from nameIndex
* and try to {@link #matchFragment(String, int, int, com.intellij.psi.codeStyle.MinusculeMatcher.MatchingState)} for it.
diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
index 2ab896e7c1cd..74081d16ed72 100644
--- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
+++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java
@@ -336,36 +336,23 @@ public class NameUtil {
}
int i = start;
- boolean prevIsLetterOrDigit = i > 0 && Character.isLetterOrDigit(text.charAt(i - 1));
- while (i < text.length()) {
- char c = text.charAt(i);
- if (!isWordStart(c)) {
- if (!Character.isLetterOrDigit(c)) {
- break;
- }
- if (prevIsLetterOrDigit) {
- break;
- }
- }
- prevIsLetterOrDigit = true;
- i++;
+ while (i < text.length() && Character.isDigit(text.charAt(i))) i++;
+ if (i > start) {
+ // digits form a separate hump
+ return i;
}
+ while (i < text.length() && Character.isUpperCase(text.charAt(i))) i++;
+
if (i > start + 1) {
- if (i == text.length() || !Character.isLetterOrDigit(text.charAt(i))) {
+ // several consecutive uppercase letter form a hump
+ if (i == text.length() || !Character.isLetter(text.charAt(i))) {
return i;
}
return i - 1;
}
- /*boolean */prevIsLetterOrDigit = i > 0 && Character.isLetterOrDigit(text.charAt(i - 1));
- while (i < text.length()){
- char c = text.charAt(i);
- if (!Character.isLetterOrDigit(c)) break;
- if (isWordStart(c)) break;
- if (!prevIsLetterOrDigit) break;
- prevIsLetterOrDigit = true;
- i++;
- }
+
+ while (i < text.length() && Character.isLetter(text.charAt(i)) && !Character.isUpperCase(text.charAt(i))) i++;
return i;
}
diff --git a/platform/util/src/com/intellij/ui/EngravedLabel.java b/platform/util/src/com/intellij/ui/EngravedLabel.java
index fdf098a52c4b..ec4fc8afef8c 100644
--- a/platform/util/src/com/intellij/ui/EngravedLabel.java
+++ b/platform/util/src/com/intellij/ui/EngravedLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -28,6 +28,8 @@ import java.awt.*;
* @author max
*/
public class EngravedLabel extends JLabel {
+ private Color myShadowColor = EngravedTextGraphics.SHADOW_COLOR;
+
public EngravedLabel(String text) {
super(text);
setOpaque(false);
@@ -38,7 +40,18 @@ public class EngravedLabel extends JLabel {
}
@Override
- protected void paintComponent(Graphics g) {
- super.paintComponent(UIUtil.isUnderDarcula() ? g : new EngravedTextGraphics((Graphics2D)g));
+ protected void paintComponent(Graphics graphics) {
+ if (!UIUtil.isUnderDarcula()) {
+ graphics = new EngravedTextGraphics((Graphics2D)graphics, 0, 1, getShadowColor());
+ }
+ super.paintComponent(graphics);
+ }
+
+ public Color getShadowColor() {
+ return myShadowColor == null ? EngravedTextGraphics.SHADOW_COLOR : myShadowColor;
+ }
+
+ public void setShadowColor(Color shadowColor) {
+ myShadowColor = shadowColor;
}
}
diff --git a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java
index f47072f423a8..916bde842c3b 100644
--- a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java
+++ b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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 @@ import java.awt.*;
import java.text.AttributedCharacterIterator;
public class EngravedTextGraphics extends Graphics2DDelegate {
- private static final Color SHADOW_COLOR = Gray._250.withAlpha(140);
+ public static final Color SHADOW_COLOR = Gray._250.withAlpha(140);
private static final boolean ALLOW_ENGRAVEMENT = SystemInfo.isMac;
private Color myShadowColor;
private int myXOffset;
diff --git a/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java b/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java
index 4e14931a2dcb..e8277dbe0798 100644
--- a/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java
+++ b/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java
@@ -311,6 +311,8 @@ public class Foundation {
public int count() {
return invoke(myDelegate, "count").intValue();
}
+
+ public NSArray keys() { return new NSArray(invoke(myDelegate, "allKeys")); }
}
public static class NSArray {
diff --git a/platform/util/src/com/intellij/util/PathMappingSettings.java b/platform/util/src/com/intellij/util/PathMappingSettings.java
index 9bdd98755337..09c5b490cb4b 100644
--- a/platform/util/src/com/intellij/util/PathMappingSettings.java
+++ b/platform/util/src/com/intellij/util/PathMappingSettings.java
@@ -128,10 +128,20 @@ public class PathMappingSettings implements Cloneable {
public void addMapping(String local, String remote) {
PathMapping mapping = new PathMapping(local, remote);
- if (areBothEmpty(mapping.myLocalRoot, mapping.myRemoteRoot)) {
- return;
+ add(mapping);
+ }
+
+ public void addMappingCheckUnique(String local, String remote) {
+ for (PathMapping mapping: myPathMappings) {
+ if (pathEquals(local, mapping.getLocalRoot()) && pathEquals(remote, mapping.getRemoteRoot())) {
+ return;
+ }
}
- myPathMappings.add(mapping);
+ addMapping(local, remote);
+ }
+
+ private static boolean pathEquals(@NotNull String path1, @NotNull String path2) {
+ return norm(path1).equals(norm(path2));
}
public boolean canReplaceRemote(String remotePath) {
@@ -267,11 +277,11 @@ public class PathMappingSettings implements Cloneable {
return myRemoteRoot;
}
- public int getLocalLen() {
+ private int getLocalLen() {
return myLocalRoot != null ? myLocalRoot.length() : -1;
}
- public int getRemoteLen() {
+ private int getRemoteLen() {
return myRemoteRoot != null ? myRemoteRoot.length() : -1;
}
diff --git a/platform/util/src/com/intellij/util/ReflectionUtil.java b/platform/util/src/com/intellij/util/ReflectionUtil.java
index 1730d6500ba3..a4bf4318a76e 100644
--- a/platform/util/src/com/intellij/util/ReflectionUtil.java
+++ b/platform/util/src/com/intellij/util/ReflectionUtil.java
@@ -160,11 +160,11 @@ public class ReflectionUtil {
}
@NotNull
- public static Field findAssignableField(@NotNull Class<?> clazz, @NotNull final Class<?> fieldType, @NotNull final String fieldName) throws NoSuchFieldException {
+ public static Field findAssignableField(@NotNull Class<?> clazz, @Nullable("null means any type") final Class<?> fieldType, @NotNull final String fieldName) throws NoSuchFieldException {
Field result = processFields(clazz, new Condition<Field>() {
@Override
public boolean value(Field field) {
- return fieldName.equals(field.getName()) && fieldType.isAssignableFrom(field.getType());
+ return fieldName.equals(field.getName()) && (fieldType == null || fieldType.isAssignableFrom(field.getType()));
}
});
if (result != null) return result;
@@ -186,7 +186,10 @@ public class ReflectionUtil {
private static Field processFields(@NotNull Class clazz, @NotNull Condition<Field> checker) {
for (Field field : clazz.getDeclaredFields()) {
- if (checker.value(field)) return field;
+ if (checker.value(field)) {
+ field.setAccessible(true);
+ return field;
+ }
}
final Class superClass = clazz.getSuperclass();
if (superClass != null) {
@@ -201,7 +204,7 @@ public class ReflectionUtil {
return null;
}
- public static void resetField(@NotNull Class clazz, @NotNull Class type, @NotNull String name) {
+ public static void resetField(@NotNull Class clazz, @Nullable("null means of any type") Class type, @NotNull String name) {
try {
resetField(null, findField(clazz, type, name));
}
@@ -209,7 +212,7 @@ public class ReflectionUtil {
LOG.info(e);
}
}
- public static void resetField(@NotNull Object object, @NotNull Class type, @NotNull String name) {
+ public static void resetField(@NotNull Object object, @Nullable("null means any type") Class type, @NotNull String name) {
try {
resetField(object, findField(object.getClass(), type, name));
}
@@ -257,7 +260,10 @@ public class ReflectionUtil {
@Nullable
public static Method findMethod(@NotNull Collection<Method> methods, @NonNls @NotNull String name, @NotNull Class... parameters) {
for (final Method method : methods) {
- if (name.equals(method.getName()) && Arrays.equals(parameters, method.getParameterTypes())) return method;
+ if (name.equals(method.getName()) && Arrays.equals(parameters, method.getParameterTypes())) {
+ method.setAccessible(true);
+ return method;
+ }
}
return null;
}
@@ -272,6 +278,16 @@ public class ReflectionUtil {
return findMethod(getClassDeclaredMethods(aClass, false), name, parameters);
}
+ @Nullable
+ public static Field getDeclaredField(@NotNull Class aClass, @NonNls @NotNull final String name) {
+ return processFields(aClass, new Condition<Field>() {
+ @Override
+ public boolean value(Field field) {
+ return name.equals(field.getName());
+ }
+ });
+ }
+
public static List<Method> getClassPublicMethods(@NotNull Class aClass) {
return getClassPublicMethods(aClass, false);
}
@@ -284,11 +300,17 @@ public class ReflectionUtil {
public static List<Method> getClassDeclaredMethods(@NotNull Class aClass) {
return getClassDeclaredMethods(aClass, false);
}
-
+
+ @NotNull
public static List<Method> getClassDeclaredMethods(@NotNull Class aClass, boolean includeSynthetic) {
Method[] methods = aClass.getDeclaredMethods();
return includeSynthetic ? Arrays.asList(methods) : filterRealMethods(methods);
}
+ @NotNull
+ public static List<Field> getClassDeclaredFields(@NotNull Class aClass) {
+ Field[] fields = aClass.getDeclaredFields();
+ return Arrays.asList(fields);
+ }
private static List<Method> filterRealMethods(Method[] methods) {
List<Method> result = ContainerUtil.newArrayList();
@@ -306,10 +328,9 @@ public class ReflectionUtil {
return method == null ? null : method.getDeclaringClass();
}
- public static <T> T getField(@NotNull Class objectClass, Object object, @NotNull Class<T> fieldType, @NotNull @NonNls String fieldName) {
+ public static <T> T getField(@NotNull Class objectClass, Object object, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName) {
try {
final Field field = findAssignableField(objectClass, fieldType, fieldName);
- field.setAccessible(true);
return (T)field.get(object);
}
catch (NoSuchFieldException e) {
@@ -322,6 +343,22 @@ public class ReflectionUtil {
}
}
+ // returns true if value was set
+ public static <T> boolean setField(@NotNull Class objectClass, Object object, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName, T value) {
+ try {
+ final Field field = findAssignableField(objectClass, fieldType, fieldName);
+ field.set(object, value);
+ return true;
+ }
+ catch (NoSuchFieldException e) {
+ LOG.debug(e);
+ }
+ catch (IllegalAccessException e) {
+ LOG.debug(e);
+ }
+ return false;
+ }
+
public static Type resolveVariableInHierarchy(@NotNull TypeVariable variable, @NotNull Class aClass) {
Type type;
Class current = aClass;
@@ -353,21 +390,8 @@ public class ReflectionUtil {
// method getConstructorAccessorMethod is not necessary since JDK7, use acquireConstructorAccessor return value instead
assert Patches.USE_REFLECTION_TO_ACCESS_JDK7;
}
- private static final Method acquireConstructorAccessorMethod;
- private static final Method getConstructorAccessorMethod;
- static {
- try {
- Method accessor = Constructor.class.getDeclaredMethod("acquireConstructorAccessor");
- accessor.setAccessible(true);
- acquireConstructorAccessorMethod = accessor;
- Method get = Constructor.class.getDeclaredMethod("getConstructorAccessor");
- get.setAccessible(true);
- getConstructorAccessorMethod = get;
- }
- catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
+ private static final Method acquireConstructorAccessorMethod = getDeclaredMethod(Constructor.class, "acquireConstructorAccessor");
+ private static final Method getConstructorAccessorMethod = getDeclaredMethod(Constructor.class, "getConstructorAccessor");
@NotNull
public static ConstructorAccessor getConstructorAccessor(@NotNull Constructor constructor) {
@@ -413,17 +437,11 @@ public class ReflectionUtil {
}
public static void resetThreadLocals() {
- try {
- Field field = Thread.class.getDeclaredField("threadLocals");
- field.setAccessible(true);
- field.set(Thread.currentThread(), null);
- }
- catch (Throwable e) {
- LOG.info(e);
- }
+ resetField(Thread.currentThread(), null, "threadLocals");
}
- public static @Nullable Class getGrandCallerClass() {
+ @Nullable
+ public static Class getGrandCallerClass() {
int stackFrameCount = 3;
Class callerClass = findCallerClass(stackFrameCount);
while (callerClass != null && callerClass.getClassLoader() == null) { // looks like a system class
diff --git a/platform/util/src/com/intellij/util/Restarter.java b/platform/util/src/com/intellij/util/Restarter.java
index 4c3450bca836..7f1584dc73dc 100644
--- a/platform/util/src/com/intellij/util/Restarter.java
+++ b/platform/util/src/com/intellij/util/Restarter.java
@@ -133,7 +133,7 @@ public class Restarter {
}
private static void restartOnMac(@NotNull final String... beforeRestart) throws IOException {
- final String homePath = PathManager.getHomePath();
+ final String homePath = PathManager.getHomePath().substring(0, PathManager.getHomePath().indexOf( ".app" ) + 4);
if (!StringUtil.endsWithIgnoreCase(homePath, ".app")) throw new IOException("Application bundle not found: " + homePath);
doScheduleRestart(new File(PathManager.getBinPath(), "restarter"), new Consumer<List<String>>() {
diff --git a/platform/util/src/com/intellij/util/WaitFor.java b/platform/util/src/com/intellij/util/WaitFor.java
index e1271ac15730..775b25a84c27 100644
--- a/platform/util/src/com/intellij/util/WaitFor.java
+++ b/platform/util/src/com/intellij/util/WaitFor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +23,7 @@ import org.jetbrains.annotations.NonNls;
*/
public abstract class WaitFor {
private static final int DEFAULT_STEP = 10;
- private static final int MAX_TIMEOUT = 600 * 1000;
+ private static final int MAX_TIMEOUT = 60 * 1000;
private long myWaitTime;
private boolean myInterrupted;
diff --git a/platform/util/src/com/intellij/util/cls/BytePointer.java b/platform/util/src/com/intellij/util/cls/BytePointer.java
index d13e4e64eea7..58322ff65713 100644
--- a/platform/util/src/com/intellij/util/cls/BytePointer.java
+++ b/platform/util/src/com/intellij/util/cls/BytePointer.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.cls;
+/** @deprecated to be removed in IDEA 15 */
public class BytePointer {
public final byte[] bytes;
public int offset;
diff --git a/platform/util/src/com/intellij/util/cls/ClsUtil.java b/platform/util/src/com/intellij/util/cls/ClsUtil.java
index 8d1f594d98fe..95e1fcb2d87f 100644
--- a/platform/util/src/com/intellij/util/cls/ClsUtil.java
+++ b/platform/util/src/com/intellij/util/cls/ClsUtil.java
@@ -16,9 +16,9 @@
package com.intellij.util.cls;
import com.intellij.openapi.util.text.StringUtil;
-import org.jetbrains.annotations.NonNls;
-
+/** @deprecated to be removed in IDEA 15 */
+@SuppressWarnings("ALL")
public class ClsUtil {
public static final int MAGIC = 0xCAFEBABE;
@@ -375,56 +375,6 @@ public class ClsUtil {
}
public static String literalToString(CharSequence value, char quote) {
- int length = value.length();
- @NonNls StringBuilder buffer = new StringBuilder(length + 3);
- buffer.append(quote);
-
- for (int i = 0; i < length; i++) {
- char c = value.charAt(i);
- if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9') {
- buffer.append(c);
- continue;
- }
-
- switch (c) {
- case '\b':
- buffer.append("\\b");
- break;
- case '\t':
- buffer.append("\\t");
- break;
- case '\n':
- buffer.append("\\n");
- break;
- case '\f':
- buffer.append("\\f");
- break;
- case '\r':
- buffer.append("\\r");
- break;
- case '\\':
- buffer.append("\\\\");
- break;
- default:
- if (c == quote) {
- buffer.append("\\").append(quote);
- }
- else if (Character.isISOControl(c)) {
- String hexCode = StringUtil.toUpperCase(Integer.toHexString(c));
- buffer.append("\\u");
- int paddingCount = 4 - hexCode.length();
- while (paddingCount-- > 0) {
- buffer.append(0);
- }
- buffer.append(hexCode);
- }
- else {
- buffer.append(c);
- }
- }
- }
-
- buffer.append(quote);
- return buffer.toString();
+ return quote + StringUtil.escapeStringCharacters(value.toString()) + quote;
}
}
diff --git a/platform/util/src/com/intellij/util/cls/package.html b/platform/util/src/com/intellij/util/cls/package.html
deleted file mode 100644
index 06cd41d1ded4..000000000000
--- a/platform/util/src/com/intellij/util/cls/package.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
- ~ Copyright 2000-2007 JetBrains s.r.o.
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html><body bgcolor="white">
-Provides the utilities for parsing compiled Java class files.
-</body></html>
diff --git a/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java b/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java
index 4a885fa5cb5a..fbac0f06cd39 100644
--- a/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java
+++ b/platform/util/src/com/intellij/util/concurrency/AtomicFieldUpdater.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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,34 +22,26 @@
*/
package com.intellij.util.concurrency;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+/**
+ * Utility class similar to {@link java.util.concurrent.atomic.AtomicReferenceFieldUpdater} except:
+ * - removed access check in getAndSet() hot path for performance
+ * - new methods "forFieldXXX" added that search by field type instead of field name, which is useful in scrambled classes
+ */
public class AtomicFieldUpdater<T,V> {
private static final Unsafe unsafe = getUnsafe();
@NotNull
public static Unsafe getUnsafe() {
- Unsafe unsafe = null;
- Class uc = Unsafe.class;
- try {
- Field[] fields = uc.getDeclaredFields();
- for (Field field : fields) {
- if (field.getName().equals("theUnsafe")) {
- field.setAccessible(true);
- unsafe = (Unsafe)field.get(uc);
- break;
- }
- }
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
+ Unsafe unsafe = ReflectionUtil.getField(Unsafe.class, null, Unsafe.class, "theUnsafe");
if (unsafe == null) {
- throw new RuntimeException("Could not find 'theUnsafe' field in the " + uc);
+ throw new RuntimeException("Could not find 'theUnsafe' field in the " + Unsafe.class);
}
return unsafe;
}
@@ -62,11 +54,22 @@ public class AtomicFieldUpdater<T,V> {
}
@NotNull
- public static <T> AtomicFieldUpdater<T, Long> forLongField(@NotNull Class<T> ownerClass) {
+ public static <T> AtomicFieldUpdater<T, Long> forLongFieldIn(@NotNull Class<T> ownerClass) {
return new AtomicFieldUpdater<T, Long>(ownerClass, long.class);
}
+ @NotNull
+ public static <T> AtomicFieldUpdater<T, Integer> forIntFieldIn(@NotNull Class<T> ownerClass) {
+ return new AtomicFieldUpdater<T, Integer>(ownerClass, int.class);
+ }
+
private AtomicFieldUpdater(@NotNull Class<T> ownerClass, @NotNull Class<V> fieldType) {
+ Field found = getTheOnlyVolatileFieldOfClass(ownerClass, fieldType);
+ offset = unsafe.objectFieldOffset(found);
+ }
+
+ @NotNull
+ private static <T,V> Field getTheOnlyVolatileFieldOfClass(@NotNull Class<T> ownerClass, @NotNull Class<V> fieldType) {
Field[] declaredFields = ownerClass.getDeclaredFields();
Field found = null;
for (Field field : declaredFields) {
@@ -89,7 +92,7 @@ public class AtomicFieldUpdater<T,V> {
if ((found.getModifiers() & Modifier.VOLATILE) == 0) {
throw new IllegalArgumentException("Field "+found+" in the "+ownerClass+" must be volatile");
}
- offset = unsafe.objectFieldOffset(found);
+ return found;
}
public boolean compareAndSet(@NotNull T owner, V expected, V newValue) {
@@ -100,6 +103,10 @@ public class AtomicFieldUpdater<T,V> {
return unsafe.compareAndSwapLong(owner, offset, expected, newValue);
}
+ public boolean compareAndSetInt(@NotNull T owner, int expected, int newValue) {
+ return unsafe.compareAndSwapInt(owner, offset, expected, newValue);
+ }
+
public void set(@NotNull T owner, V newValue) {
unsafe.putObjectVolatile(owner, offset, newValue);
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentMultiMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentMultiMap.java
index 9ebd04c4fcdc..8c072cb8d3a7 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentMultiMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentMultiMap.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.Map;
/**
+ * @see MultiMap#createConcurrentSet()
* @author peter
*/
public class ConcurrentMultiMap<K,V> extends MultiMap<K,V> {
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index 7a1b1f89d1b7..4a9c7bde5614 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -2061,8 +2061,8 @@ public class ContainerUtil extends ContainerUtilRt {
}
@Contract("null -> true")
- public static <T> boolean isEmpty(List<T> list) {
- return list == null || list.isEmpty();
+ public static <T> boolean isEmpty(Collection<T> collection) {
+ return collection == null || collection.isEmpty();
}
private interface ConcurrentMapFactory {
diff --git a/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java b/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java
index 5376a92275e4..13a73529a7ac 100644
--- a/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java
+++ b/platform/util/src/com/intellij/util/containers/LockFreeCopyOnWriteArrayList.java
@@ -965,7 +965,7 @@ class LockFreeCopyOnWriteArrayList<E> implements List<E>, RandomAccess, Concurre
if (!hasPrevious()) {
throw new NoSuchElementException();
}
- return (E)snapshot[--cursor];
+ return (E)snapshot[lastRet = --cursor];
}
@Override
@@ -981,7 +981,7 @@ class LockFreeCopyOnWriteArrayList<E> implements List<E>, RandomAccess, Concurre
@Override
public void remove() {
if (lastRet < 0) {
- throw new IllegalStateException();
+ throw new NoSuchElementException();
}
@SuppressWarnings("unchecked")
E e = (E)snapshot[lastRet];
diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java
index bd0906edb78b..cfdf375738d8 100644
--- a/platform/util/src/com/intellij/util/containers/MultiMap.java
+++ b/platform/util/src/com/intellij/util/containers/MultiMap.java
@@ -293,6 +293,29 @@ public class MultiMap<K, V> implements Serializable {
}
@NotNull
+ public static <K, V> MultiMap<K, V> createConcurrentSet() {
+ return new MultiMap<K, V>() {
+ @NotNull
+ @Override
+ protected Collection<V> createCollection() {
+ return new ConcurrentHashSet<V>();
+ }
+
+ @NotNull
+ @Override
+ protected Collection<V> createEmptyCollection() {
+ return Collections.emptySet();
+ }
+
+ @NotNull
+ @Override
+ protected Map<K, Collection<V>> createMap() {
+ return ContainerUtil.newConcurrentMap();
+ }
+ };
+ }
+
+ @NotNull
public static <K, V> MultiMap<K, V> createSet() {
return new MultiMap<K, V>() {
@NotNull
diff --git a/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java b/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java
index eee100e9781f..ab3092c30d02 100644
--- a/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java
+++ b/platform/util/src/com/intellij/util/containers/WeakFactoryMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -51,4 +51,12 @@ public abstract class WeakFactoryMap<T,V> {
public void clear() {
myMap.clear();
}
+
+ private static <K> K getKey(K key) {
+ return key == null ? (K)NULL : key;
+ }
+
+ public void put(T key, V value) {
+ myMap.put(getKey(key), new WeakReference<V>(value == null ? (V)NULL : value));
+ }
}
diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
index 3375e952e434..465a65a9df50 100644
--- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
+++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
@@ -61,7 +61,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
private int myCollisions;
private int myExistingKeysEnumerated;
- private IntToIntBtree btree;
+ private IntToIntBtree myBTree;
private final boolean myInlineKeysNoMapping;
private boolean myExternalKeysNoMapping;
@@ -98,13 +98,30 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
myInlineKeysNoMapping = myDataDescriptor instanceof InlineKeyDescriptor && !wantKeyMapping();
myExternalKeysNoMapping = !(myDataDescriptor instanceof InlineKeyDescriptor) && !wantKeyMapping();
- if (btree == null) {
+ if (myBTree == null) {
try {
lockStorage();
storeVars(false);
initBtree(false);
storeBTreeVars(false);
}
+ catch (IOException e) {
+ try {
+ close(); // cleanup already initialized state
+ }
+ catch (Throwable ignored) {
+ }
+ throw e;
+ }
+ catch (Throwable e) {
+ LOG.info(e);
+ try {
+ close(); // cleanup already initialized state
+ }
+ catch (Throwable ignored) {
+ }
+ throw new CorruptedException(file);
+ }
finally {
unlockStorage();
}
@@ -121,7 +138,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
}
private void initBtree(boolean initial) throws IOException {
- btree = new IntToIntBtree(PAGE_SIZE, indexFile(myFile), myStorage.getPagedFileStorage().getStorageLockContext(), initial);
+ myBTree = new IntToIntBtree(PAGE_SIZE, indexFile(myFile), myStorage.getPagedFileStorage().getStorageLockContext(), initial);
}
private void storeVars(boolean toDisk) {
@@ -138,9 +155,10 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
}
private void storeBTreeVars(boolean toDisk) {
- if (btree != null) {
+ final IntToIntBtree tree = myBTree;
+ if (tree != null) {
final int BTREE_DATA_START = DATA_START + 36;
- btree.persistVars(new IntToIntBtree.BtreeDataStorage() {
+ tree.persistVars(new IntToIntBtree.BtreeDataStorage() {
@Override
public int persistInt(int offset, int value, boolean toDisk) {
return store(BTREE_DATA_START + offset, value, toDisk);
@@ -176,7 +194,10 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
super.doClose();
}
finally {
- btree.doClose();
+ final IntToIntBtree tree = myBTree;
+ if (tree != null) {
+ tree.doClose();
+ }
}
}
@@ -207,7 +228,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
public boolean traverseAllRecords(@NotNull final RecordsProcessor p) throws IOException {
try {
lockStorage();
- return btree.processMappings(new IntToIntBtree.KeyValueProcessor() {
+ return myBTree.processMappings(new IntToIntBtree.KeyValueProcessor() {
@Override
public boolean process(int key, int value) throws IOException {
p.setCurrentKey(key);
@@ -289,7 +310,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
assert myInlineKeysNoMapping;
try {
lockStorage();
- final boolean hasMapping = btree.get(((InlineKeyDescriptor<Data>)myDataDescriptor).toInt(key), myResultBuf);
+ final boolean hasMapping = myBTree.get(((InlineKeyDescriptor<Data>)myDataDescriptor).toInt(key), myResultBuf);
if (!hasMapping) {
return NULL_ID;
}
@@ -318,11 +339,11 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
markDirty(true);
int intKey = ((InlineKeyDescriptor<Data>)myDataDescriptor).toInt(key);
if (value < Integer.MAX_VALUE) {
- btree.put(intKey, (int) value);
+ myBTree.put(intKey, (int) value);
} else {
int pos = nextLongValueRecord();
myStorage.putLong(pos, value);
- btree.put(intKey, -pos);
+ myBTree.put(intKey, -pos);
}
} catch (IllegalStateException e) {
CorruptedException exception = new CorruptedException(myFile);
@@ -336,7 +357,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
private int nextLongValueRecord() {
assert myInlineKeysNoMapping;
- if (myDuplicatedValuesPageStart == -1 || myDuplicatedValuesPageOffset == btree.pageSize) {
+ if (myDuplicatedValuesPageStart == -1 || myDuplicatedValuesPageOffset == myBTree.pageSize) {
myDuplicatedValuesPageStart = allocPage();
myDuplicatedValuesPageOffset = 0;
}
@@ -353,7 +374,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
if (IntToIntBtree.doDump) System.out.println(value);
final int valueHC = myDataDescriptor.getHashCode(value);
- final boolean hasMapping = btree.get(valueHC, myResultBuf);
+ final boolean hasMapping = myBTree.get(valueHC, myResultBuf);
if (!hasMapping && onlyCheckForExisting) {
return NULL_ID;
}
@@ -412,13 +433,13 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
", existing keys enumerated:"+ myExistingKeysEnumerated +
", storage size:" +
myStorage.length());
- btree.dumpStatistics();
+ myBTree.dumpStatistics();
}
if (collisionAddress != NULL_ID) {
if (hasExistingData) {
if (indexNodeValueAddress > 0) {
- btree.put(valueHC, newValueId);
+ myBTree.put(valueHC, newValueId);
} else {
myStorage.putInt(collisionAddress, newValueId);
}
@@ -426,7 +447,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
if (indexNodeValueAddress > 0) {
// organize collision type reference
int duplicatedValueOff = nextDuplicatedValueRecord();
- btree.put(valueHC, -duplicatedValueOff);
+ myBTree.put(valueHC, -duplicatedValueOff);
myStorage.putInt(duplicatedValueOff, indexNodeValueAddress); // we will set collision offset in next if
collisionAddress = duplicatedValueOff;
@@ -440,7 +461,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
myStorage.putInt(duplicatedValueOff + COLLISION_OFFSET, 0);
}
} else {
- btree.put(valueHC, newValueId);
+ myBTree.put(valueHC, newValueId);
}
if (IntToIntBtree.doSanityCheck) {
@@ -475,7 +496,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
private int nextDuplicatedValueRecord() {
assert !myInlineKeysNoMapping;
- if (myDuplicatedValuesPageStart == -1 || myDuplicatedValuesPageOffset == btree.pageSize) {
+ if (myDuplicatedValuesPageStart == -1 || myDuplicatedValuesPageOffset == myBTree.pageSize) {
myDuplicatedValuesPageStart = allocPage();
myDuplicatedValuesPageOffset = 0;
}
@@ -487,7 +508,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
@Override
protected void doFlush() throws IOException {
- btree.doFlush();
+ myBTree.doFlush();
storeVars(true);
super.doFlush();
}
@@ -500,16 +521,16 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
if (enumerator.myFirstPageStart == -1) {
enumerator.myFirstPageStart = enumerator.myDataPageStart = enumerator.allocPage();
}
- if (enumerator.myDataPageOffset + buf.length + 4 > enumerator.btree.pageSize) {
- assert enumerator.myDataPageOffset + 4 <= enumerator.btree.pageSize;
- int prevDataPageStart = enumerator.myDataPageStart + enumerator.btree.pageSize - 4;
+ if (enumerator.myDataPageOffset + buf.length + 4 > enumerator.myBTree.pageSize) {
+ assert enumerator.myDataPageOffset + 4 <= enumerator.myBTree.pageSize;
+ int prevDataPageStart = enumerator.myDataPageStart + enumerator.myBTree.pageSize - 4;
enumerator.myDataPageStart = enumerator.allocPage();
enumerator.myStorage.putInt(prevDataPageStart, enumerator.myDataPageStart);
enumerator.myDataPageOffset = 0;
}
int recordWriteOffset = enumerator.myDataPageOffset;
- assert recordWriteOffset + buf.length + 4 <= enumerator.btree.pageSize;
+ assert recordWriteOffset + buf.length + 4 <= enumerator.myBTree.pageSize;
enumerator.myDataPageOffset += buf.length;
return recordWriteOffset + enumerator.myDataPageStart;
}
diff --git a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
index a91c7e0dabf7..9f879f67d99d 100644
--- a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
+++ b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java
@@ -227,7 +227,18 @@ public abstract class PersistentEnumeratorBase<Data> implements Forceable, Close
myKeyStorage = null;
}
else {
- myKeyStorage = new AppendableStorageBackedByResizableMappedFile(keystreamFile(), initialSize, myStorage.getPagedFileStorage().getStorageLockContext(), PagedFileStorage.MB, false);
+ try {
+ myKeyStorage = new AppendableStorageBackedByResizableMappedFile(keystreamFile(), initialSize, myStorage.getPagedFileStorage().getStorageLockContext(), PagedFileStorage.MB, false);
+ }
+ catch (IOException e) {
+ myStorage.close();
+ throw e;
+ }
+ catch (Throwable e) {
+ LOG.info(e);
+ myStorage.close();
+ throw new CorruptedException(file);
+ }
}
myAssumeDifferentSerializedBytesMeansObjectsInequality = myDataDescriptor instanceof DifferentSerializableBytesImplyNonEqualityPolicy;
}
diff --git a/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java b/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java
index 0f408fa8dd8a..0e3ef835b21b 100644
--- a/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java
+++ b/platform/util/src/com/intellij/util/keyFMap/ArrayBackedFMap.java
@@ -78,7 +78,7 @@ class ArrayBackedFMap implements KeyFMap {
if (oldSize == 3) {
int i1 = (2-i)/2;
int i2 = 3 - (i+2)/2;
- return new PairElementsFMap(keys[i1], values[i1], keys[i2], values[i2]);
+ return new PairElementsFMap(Key.getKeyByIndex(keys[i1]), values[i1], Key.getKeyByIndex(keys[i2]), values[i2]);
}
int newSize = oldSize - 1;
int[] newKeys = new int[newSize];
diff --git a/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java b/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java
index d682bcb4dd46..a51068c18abd 100644
--- a/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java
+++ b/platform/util/src/com/intellij/util/keyFMap/EmptyFMap.java
@@ -25,7 +25,7 @@ class EmptyFMap implements KeyFMap {
@NotNull
@Override
public <V> KeyFMap plus(@NotNull Key<V> key, @NotNull V value) {
- return new OneElementFMap<V>(key.hashCode(), value);
+ return new OneElementFMap<V>(key, value);
}
@NotNull
diff --git a/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java b/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java
index 76488c68c979..8bd2f343cb92 100644
--- a/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java
+++ b/platform/util/src/com/intellij/util/keyFMap/OneElementFMap.java
@@ -18,45 +18,69 @@ package com.intellij.util.keyFMap;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
-class OneElementFMap<V> implements KeyFMap {
- private final int myKeyCode;
+public class OneElementFMap<V> implements KeyFMap {
+ private final Key myKey;
private final V myValue;
- OneElementFMap(int keyCode, @NotNull V value) {
- myKeyCode = keyCode;
+ public OneElementFMap(@NotNull Key key, @NotNull V value) {
+ myKey = key;
myValue = value;
}
@NotNull
@Override
public <V> KeyFMap plus(@NotNull Key<V> key, @NotNull V value) {
- int keyCode = key.hashCode();
- if (myKeyCode == keyCode) return new OneElementFMap<V>(keyCode, value);
- return new PairElementsFMap(myKeyCode, myValue, keyCode, value);
+ if (myKey == key) return new OneElementFMap<V>(key, value);
+ return new PairElementsFMap(myKey, myValue, key, value);
}
@NotNull
@Override
public KeyFMap minus(@NotNull Key<?> key) {
- if (key.hashCode() == myKeyCode) {
- return KeyFMap.EMPTY_MAP;
- }
- return this;
+ return key == myKey ? KeyFMap.EMPTY_MAP : this;
}
@Override
public <V> V get(@NotNull Key<V> key) {
//noinspection unchecked
- return myKeyCode == key.hashCode() ? (V)myValue : null;
+ return myKey == key ? (V)myValue : null;
}
@Override
public String toString() {
- return "<"+Key.getKeyByIndex(myKeyCode) + " -> " + myValue+">";
+ return "<" + myKey + " -> " + myValue+">";
}
@Override
public boolean isEmpty() {
return false;
}
+
+ public Key getKey() {
+ return myKey;
+ }
+
+ public V getValue() {
+ return myValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof OneElementFMap)) return false;
+
+ OneElementFMap map = (OneElementFMap)o;
+
+ if (myKey != map.myKey) return false;
+ if (!myValue.equals(map.myValue)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myKey.hashCode();
+ result = 31 * result + myValue.hashCode();
+ return result;
+ }
}
diff --git a/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java b/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java
index 35ea8b957e36..bb8b8d0ace15 100644
--- a/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java
+++ b/platform/util/src/com/intellij/util/keyFMap/PairElementsFMap.java
@@ -19,12 +19,12 @@ import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
class PairElementsFMap implements KeyFMap {
- private final int key1;
- private final int key2;
+ private final Key key1;
+ private final Key key2;
private final Object value1;
private final Object value2;
- PairElementsFMap(int key1, @NotNull Object value1, int key2, @NotNull Object value2) {
+ PairElementsFMap(@NotNull Key key1, @NotNull Object value1, @NotNull Key key2, @NotNull Object value2) {
this.key1 = key1;
this.value1 = value1;
this.key2 = key2;
@@ -35,31 +35,28 @@ class PairElementsFMap implements KeyFMap {
@NotNull
@Override
public <V> KeyFMap plus(@NotNull Key<V> key, @NotNull V value) {
- int keyCode = key.hashCode();
- if (keyCode == key1) return new PairElementsFMap(keyCode, value, key2, value2);
- if (keyCode == key2) return new PairElementsFMap(keyCode, value, key1, value1);
- return new ArrayBackedFMap(new int[]{key1, key2, keyCode}, new Object[]{value1, value2, value});
+ if (key == key1) return new PairElementsFMap(key, value, key2, value2);
+ if (key == key2) return new PairElementsFMap(key, value, key1, value1);
+ return new ArrayBackedFMap(new int[]{key1.hashCode(), key2.hashCode(), key.hashCode()}, new Object[]{value1, value2, value});
}
@NotNull
@Override
public KeyFMap minus(@NotNull Key<?> key) {
- int keyCode = key.hashCode();
- if (keyCode == key1) return new OneElementFMap<Object>(key2, value2);
- if (keyCode == key2) return new OneElementFMap<Object>(key1, value1);
+ if (key == key1) return new OneElementFMap<Object>(key2, value2);
+ if (key == key2) return new OneElementFMap<Object>(key1, value1);
return this;
}
@Override
public <V> V get(@NotNull Key<V> key) {
- int keyCode = key.hashCode();
//noinspection unchecked
- return keyCode == key1 ? (V)value1 : keyCode == key2 ? (V)value2 : null;
+ return key == key1 ? (V)value1 : key == key2 ? (V)value2 : null;
}
@Override
public String toString() {
- return "Pair: ("+ Key.getKeyByIndex(key1) + " -> " + value1+"; "+Key.getKeyByIndex(key2) + " -> " + value2 + ")";
+ return "Pair: (" + key1 + " -> " + value1 + "; " + key2 + " -> " + value2 + ")";
}
@Override
diff --git a/platform/util/src/com/intellij/util/lang/JarLoader.java b/platform/util/src/com/intellij/util/lang/JarLoader.java
index a088275a7913..15556a8d0a52 100644
--- a/platform/util/src/com/intellij/util/lang/JarLoader.java
+++ b/platform/util/src/com/intellij/util/lang/JarLoader.java
@@ -58,8 +58,17 @@ class JarLoader extends Loader {
}
void preloadClasses() {
+ ZipFile zipFile;
+
+ try {
+ zipFile = acquireZipFile();
+ }
+ catch (Exception e) {
+ LOG.debug("url: " + myURL, e);
+ return;
+ }
+
try {
- ZipFile zipFile = acquireZipFile();
try {
JarMemoryLoader loader = JarMemoryLoader.load(zipFile, getBaseURL());
if (loader != null) {
diff --git a/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java b/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java
index e29a37127159..03b41cd0d493 100644
--- a/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java
+++ b/platform/util/src/com/intellij/util/lang/JarMemoryLoader.java
@@ -67,7 +67,7 @@ public class JarMemoryLoader {
int size = ZipShort.getValue(bytes);
JarMemoryLoader loader = new JarMemoryLoader();
- for (int i = 0; i < size; i++) {
+ for (int i = 0; i < size && entries.hasMoreElements(); i++) {
ZipEntry entry = entries.nextElement();
MemoryResource resource = MemoryResource.load(baseUrl, zipFile, entry);
loader.myResources.put(entry.getName(), resource);
diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java b/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java
index ba7b35024eb9..a8ce8f1cb73b 100644
--- a/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java
+++ b/platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * @author max
- */
package com.intellij.util.messages.impl;
import com.intellij.openapi.Disposable;
@@ -39,6 +35,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
+/**
+ * @author max
+ */
public class MessageBusImpl implements MessageBus {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.messages.impl.MessageBusImpl");
private static final Comparator<MessageBusImpl> MESSAGE_BUS_COMPARATOR = new Comparator<MessageBusImpl>() {
@@ -76,7 +75,6 @@ public class MessageBusImpl implements MessageBus {
private MessageBusImpl myParentBus;
//is used for debugging purposes
- @SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
private final Object myOwner;
private boolean myDisposed;
@@ -103,7 +101,10 @@ public class MessageBusImpl implements MessageBus {
}
private RootBus asRoot() {
- return (RootBus)this;
+ if ((this instanceof RootBus)) {
+ return (RootBus)this;
+ }
+ throw new AssertionError("Accessing disposed message bus; " + myOwner);
}
private List<Integer> notifyChildBusCreated(final MessageBusImpl childBus) {
@@ -222,7 +223,7 @@ public class MessageBusImpl implements MessageBus {
}
private void checkNotDisposed() {
- LOG.assertTrue(!myDisposed, "Already disposed");
+ if (myDisposed) LOG.error("Already disposed: " + myOwner);
}
private void calcSubscribers(Topic topic, List<MessageBusConnectionImpl> result) {
diff --git a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java
index 0b92057074ac..c51b950b67a7 100644
--- a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java
+++ b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java
@@ -165,9 +165,20 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
@Override
public ComponentAdapter unregisterComponent(Object componentKey) {
ComponentAdapter adapter = componentKeyToAdapterCache.remove(componentKey);
-
componentAdapters.remove(adapter);
-
+ if (adapter instanceof AssignableToComponentAdapter) {
+ classNameToAdapter.remove(((AssignableToComponentAdapter)adapter).getAssignableToClassName());
+ }
+ else {
+ do {
+ FList<ComponentAdapter> oldList = nonAssignableComponentAdapters.get();
+ FList<ComponentAdapter> newList = oldList.without(adapter);
+ if (nonAssignableComponentAdapters.compareAndSet(oldList, newList)) {
+ break;
+ }
+ }
+ while (true);
+ }
return adapter;
}
diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java
index d57c32138bd1..cc6d5a305bf5 100644
--- a/platform/util/src/com/intellij/util/ui/UIUtil.java
+++ b/platform/util/src/com/intellij/util/ui/UIUtil.java
@@ -273,14 +273,10 @@ public class UIUtil {
try {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
final GraphicsDevice device = env.getDefaultScreenDevice();
- Field field = device.getClass().getDeclaredField("scale");
- if (field != null) {
- field.setAccessible(true);
- Object scale = field.get(device);
- if (scale instanceof Integer && ((Integer)scale).intValue() == 2) {
- ourRetina.set(true);
- return true;
- }
+ Integer scale = ReflectionUtil.getField(device.getClass(), device, int.class, "scale");
+ if (scale != null && scale.intValue() == 2) {
+ ourRetina.set(true);
+ return true;
}
}
catch (AWTError ignore) {}
@@ -925,20 +921,24 @@ public class UIUtil {
return UIManager.getBorder("Button.border");
}
+ @NotNull
public static Icon getErrorIcon() {
- return UIManager.getIcon("OptionPane.errorIcon");
+ return ObjectUtils.notNull(UIManager.getIcon("OptionPane.errorIcon"), AllIcons.General.ErrorDialog);
}
+ @NotNull
public static Icon getInformationIcon() {
- return UIManager.getIcon("OptionPane.informationIcon");
+ return ObjectUtils.notNull(UIManager.getIcon("OptionPane.informationIcon"), AllIcons.General.InformationDialog);
}
+ @NotNull
public static Icon getQuestionIcon() {
- return UIManager.getIcon("OptionPane.questionIcon");
+ return ObjectUtils.notNull(UIManager.getIcon("OptionPane.questionIcon"), AllIcons.General.QuestionDialog);
}
+ @NotNull
public static Icon getWarningIcon() {
- return UIManager.getIcon("OptionPane.warningIcon");
+ return ObjectUtils.notNull(UIManager.getIcon("OptionPane.warningIcon"), AllIcons.General.WarningDialog);
}
public static Icon getBalloonInformationIcon() {
@@ -2096,6 +2096,17 @@ public class UIUtil {
}
}
+ public static <T> T invokeAndWaitIfNeeded(@NotNull final Computable<T> computable) {
+ final Ref<T> result = Ref.create();
+ invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ result.set(computable.compute());
+ }
+ });
+ return result.get();
+ }
+
public static void invokeAndWaitIfNeeded(@NotNull final ThrowableRunnable runnable) throws Throwable {
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
@@ -2225,20 +2236,10 @@ public class UIUtil {
}
@Nullable
- public static ComboPopup getComboBoxPopup(JComboBox comboBox) {
+ public static ComboPopup getComboBoxPopup(@NotNull JComboBox comboBox) {
final ComboBoxUI ui = comboBox.getUI();
if (ui instanceof BasicComboBoxUI) {
- try {
- final Field popup = BasicComboBoxUI.class.getDeclaredField("popup");
- popup.setAccessible(true);
- return (ComboPopup)popup.get(ui);
- }
- catch (NoSuchFieldException e) {
- return null;
- }
- catch (IllegalAccessException e) {
- return null;
- }
+ return ReflectionUtil.getField(BasicComboBoxUI.class, ui, ComboPopup.class, "popup");
}
return null;
@@ -2904,17 +2905,12 @@ public class UIUtil {
public static String getCurrentKeyboardLayout() {
InputContext instance = InputContext.getInstance();
Class<? extends InputContext> instanceClass = instance.getClass();
- if (instanceClass.getSuperclass().getName().equals("sun.awt.im.InputContext")) {
+ Class<?> superclass = instanceClass.getSuperclass();
+ if (superclass.getName().equals("sun.awt.im.InputContext")) {
try {
- Field f = instanceClass.getSuperclass().getDeclaredField("inputMethodLocator");
- f.setAccessible(true);
- Object o = f.get(instance);
- f = o.getClass().getDeclaredField("locale");
- f.setAccessible(true);
- o = f.get(o);
- if (o instanceof Locale) {
- return ((Locale)o).getLanguage().toUpperCase(Locale.getDefault());
- }
+ Object inputMethodLocator = ReflectionUtil.getField(superclass, instance, null, "inputMethodLocator");
+ Locale locale = ReflectionUtil.getField(inputMethodLocator.getClass(), inputMethodLocator, Locale.class, "locale");
+ return locale.getLanguage().toUpperCase(Locale.getDefault());
}
catch (Exception ignored) {
}
diff --git a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
index 579a42529359..ba0eb265655e 100644
--- a/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
+++ b/platform/util/src/com/intellij/util/ui/tree/WideSelectionTreeUI.java
@@ -17,7 +17,6 @@ package com.intellij.util.ui.tree;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.containers.ComparatorUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -49,7 +48,6 @@ public class WideSelectionTreeUI extends BasicTreeUI {
@NotNull private final Condition<Integer> myWideSelectionCondition;
private boolean myWideSelection;
private boolean myOldRepaintAllRowValue;
- private boolean invertLineColor;
private boolean myForceDontPaintLines = false;
private boolean mySkinny = false;
@@ -281,17 +279,15 @@ public class WideSelectionTreeUI extends BasicTreeUI {
final boolean isExpanded,
final boolean hasBeenExpanded,
final boolean isLeaf) {
- if (!shouldPaintLines()) return;
- if (!UIUtil.isUnderAquaBasedLookAndFeel() && !UIUtil.isUnderDarcula() && !UIUtil.isUnderIntelliJLaF()) {
- if (UIUtil.isUnderAlloyIDEALookAndFeel()) {
- invertLineColor = tree.getSelectionModel().isRowSelected(row) && tree.hasFocus();
- }
+ if (shouldPaintLines()) {
super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
- invertLineColor = false;
}
}
private boolean shouldPaintLines() {
+ if (UIUtil.isUnderAquaBasedLookAndFeel() || UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF()) {
+ return false;
+ }
return myForceDontPaintLines || !"None".equals(tree.getClientProperty("JTree.lineStyle"));
}
@@ -302,41 +298,26 @@ public class WideSelectionTreeUI extends BasicTreeUI {
@Override
protected void paintVerticalPartOfLeg(final Graphics g, final Rectangle clipBounds, final Insets insets, final TreePath path) {
- if (!UIUtil.isUnderAquaBasedLookAndFeel() && !UIUtil.isUnderDarcula() && !UIUtil.isUnderIntelliJLaF() && shouldPaintLines()) {
- invertLineColor = UIUtil.isUnderAlloyIDEALookAndFeel() && tree.hasFocus() && tree.getSelectionModel().isPathSelected(path);
+ if (shouldPaintLines()) {
super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
- invertLineColor = false;
}
}
@Override
protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, int bottom) {
- if (!shouldPaintLines()) return;
- if (tree.hasFocus() && UIUtil.isUnderAlloyIDEALookAndFeel()) {
- int y0, y1 = top;
- while (y1 < bottom) {
- y0 = y1;
- final int row = tree.getRowForPath(tree.getClosestPathForLocation(x, y0 + 1));
- invertLineColor = tree.isRowSelected(row);
- g.setColor(getHashColor());
- final Rectangle bounds = tree.getRowBounds(row);
- y1 = bounds.y + bounds.height;
- super.paintVerticalLine(g, c, x, y0, Math.min(bottom, y1));
- }
- invertLineColor = false;
- } else {
+ if (shouldPaintLines()) {
super.paintVerticalLine(g, c, x, top, bottom);
}
}
@Override
protected Color getHashColor() {
- if (invertLineColor && !ComparatorUtil.equalsNullable(UIUtil.getTreeSelectionForeground(), UIUtil.getTreeForeground())) {
- final Color c = UIUtil.getTreeSelectionForeground();
- if (c != null) {
- return c.darker();
- }
- }
+ //if (invertLineColor && !ComparatorUtil.equalsNullable(UIUtil.getTreeSelectionForeground(), UIUtil.getTreeForeground())) {
+ // final Color c = UIUtil.getTreeSelectionForeground();
+ // if (c != null) {
+ // return c.darker();
+ // }
+ //}
return super.getHashColor();
}
diff --git a/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java b/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java
index bedc0da0f80a..943f34e129d0 100644
--- a/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java
+++ b/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java
@@ -34,6 +34,23 @@ import java.util.regex.Pattern;
public class JDOMXIncluder {
private static final Logger LOG = Logger.getInstance(JDOMXIncluder.class);
+ public static final PathResolver DEFAULT_PATH_RESOLVER = new PathResolver() {
+ @NotNull
+ @Override
+ public URL resolvePath(@NotNull String relativePath, @Nullable String base) {
+ try {
+ if (base != null) {
+ return new URL(new URL(base), relativePath);
+ }
+ else {
+ return new URL(relativePath);
+ }
+ }
+ catch (MalformedURLException ex) {
+ throw new XIncludeException(ex);
+ }
+ }
+ };
@NonNls private static final String HTTP_WWW_W3_ORG_2001_XINCLUDE = "http://www.w3.org/2001/XInclude";
@NonNls private static final String XI = "xi";
@@ -47,8 +64,12 @@ public class JDOMXIncluder {
@NonNls private static final String XPOINTER = "xpointer";
public static final Namespace XINCLUDE_NAMESPACE = Namespace.getNamespace(XI, HTTP_WWW_W3_ORG_2001_XINCLUDE);
+ private final boolean myIgnoreMissing;
+ private final PathResolver myPathResolver;
- private JDOMXIncluder() {
+ private JDOMXIncluder(boolean ignoreMissing, PathResolver pathResolver) {
+ myIgnoreMissing = ignoreMissing;
+ myPathResolver = pathResolver;
}
public static Document resolve(Document original, String base) throws XIncludeException {
@@ -56,6 +77,18 @@ public class JDOMXIncluder {
}
public static Document resolve(Document original, String base, boolean ignoreMissing) throws XIncludeException {
+ return resolve(original, base, ignoreMissing, DEFAULT_PATH_RESOLVER);
+ }
+
+ public static Document resolve(Document original, String base, boolean ignoreMissing, PathResolver pathResolver) throws XIncludeException {
+ return new JDOMXIncluder(ignoreMissing, pathResolver).doResolve(original, base);
+ }
+
+ public static List<Content> resolve(@NotNull Element original, String base) throws XIncludeException {
+ return new JDOMXIncluder(false, DEFAULT_PATH_RESOLVER).doResolve(original, base);
+ }
+
+ private Document doResolve(Document original, String base) {
if (original == null) {
throw new NullPointerException("Document must not be null");
}
@@ -63,7 +96,7 @@ public class JDOMXIncluder {
Document result = original.clone();
Element root = result.getRootElement();
- List<Content> resolved = resolve(root, base, ignoreMissing);
+ List<Content> resolved = doResolve(root, base);
// check that the list returned contains
// exactly one root element
@@ -137,43 +170,33 @@ public class JDOMXIncluder {
return result;
}
- public static List<Content> resolve(@NotNull Element original, String base) throws XIncludeException {
- return resolve(original, base, false);
- }
-
- private static List<Content> resolve(@NotNull Element original, String base, boolean ignoreMissing) throws XIncludeException {
+ private List<Content> doResolve(@NotNull Element original, String base) throws XIncludeException {
Stack<String> bases = new Stack<String>();
if (base != null) bases.push(base);
- List<Content> result = resolve(original, bases, ignoreMissing);
+ List<Content> result = resolve(original, bases);
bases.pop();
return result;
}
private static boolean isIncludeElement(Element element) {
- if (element.getName().equals(INCLUDE) && element.getNamespace().equals(XINCLUDE_NAMESPACE)) {
- return true;
- }
- return false;
-
+ return element.getName().equals(INCLUDE) && element.getNamespace().equals(XINCLUDE_NAMESPACE);
}
- private static List<Content> resolve(Element original, Stack<String> bases, boolean ignoreMissing) throws XIncludeException {
- if (!bases.isEmpty()) bases.peek();
-
+ private List<Content> resolve(Element original, Stack<String> bases) throws XIncludeException {
if (isIncludeElement(original)) {
- return resolveXIncludeElement(original, bases, ignoreMissing);
+ return resolveXIncludeElement(original, bases);
}
else {
- Element resolvedElement = resolveNonXIncludeElement(original, bases, ignoreMissing);
+ Element resolvedElement = resolveNonXIncludeElement(original, bases);
List<Content> resultList = new ArrayList<Content>(1);
resultList.add(resolvedElement);
return resultList;
}
}
- private static List<Content> resolveXIncludeElement(Element element, Stack<String> bases, boolean ignoreMissing) throws XIncludeException {
+ private List<Content> resolveXIncludeElement(Element element, Stack<String> bases) throws XIncludeException {
String base = "";
if (!bases.isEmpty()) base = bases.peek();
@@ -188,24 +211,7 @@ public class JDOMXIncluder {
base = baseAttribute.getValue();
}
- URL remote;
- if (base != null) {
- try {
- URL context = new URL(base);
- remote = new URL(context, href);
- }
- catch (MalformedURLException ex) {
- throw new XIncludeException(ex);
- }
- }
- else { // base == null
- try {
- remote = new URL(href);
- }
- catch (MalformedURLException ex) {
- throw new XIncludeException(ex);
- }
- }
+ URL remote = myPathResolver.resolvePath(href, base);
boolean parse = true;
final String parseAttribute = element.getAttributeValue(PARSE);
@@ -222,7 +228,7 @@ public class JDOMXIncluder {
assert !bases.contains(remote.toExternalForm()) : "Circular XInclude Reference to " + remote.toExternalForm();
final Element fallbackElement = element.getChild("fallback", element.getNamespace());
- List<Content> remoteParsed = parseRemote(bases, remote, fallbackElement, ignoreMissing);
+ List<Content> remoteParsed = parseRemote(bases, remote, fallbackElement);
if (!remoteParsed.isEmpty()) {
remoteParsed = extractNeededChildren(element, remoteParsed);
}
@@ -232,7 +238,7 @@ public class JDOMXIncluder {
if (o instanceof Element) {
Element e = (Element)o;
- List<? extends Content> nodes = resolve(e, bases, ignoreMissing);
+ List<? extends Content> nodes = resolve(e, bases);
remoteParsed.addAll(i, nodes);
i += nodes.size();
remoteParsed.remove(i);
@@ -309,17 +315,16 @@ public class JDOMXIncluder {
}
@NotNull
- private static List<Content> parseRemote(Stack<String> bases,
- URL remote,
- @Nullable Element fallbackElement,
- boolean ignoreMissing) {
+ private List<Content> parseRemote(Stack<String> bases,
+ URL remote,
+ @Nullable Element fallbackElement) {
try {
Document doc = JDOMUtil.loadResourceDocument(remote);
bases.push(remote.toExternalForm());
Element root = doc.getRootElement();
- List<Content> list = resolve(root, bases, ignoreMissing);
+ List<Content> list = resolve(root, bases);
bases.pop();
return list;
@@ -332,7 +337,7 @@ public class JDOMXIncluder {
// TODO[yole] return contents of fallback element (we don't have fallback elements with content ATM)
return Collections.emptyList();
}
- if (ignoreMissing) {
+ if (myIgnoreMissing) {
LOG.info(remote.toExternalForm() + " include ignored: " + e.getMessage());
return Collections.emptyList();
}
@@ -340,9 +345,7 @@ public class JDOMXIncluder {
}
}
- private static Element resolveNonXIncludeElement(Element original, Stack<String> bases, boolean ignoreMissing) throws XIncludeException {
- if (!bases.isEmpty()) bases.peek();
-
+ private Element resolveNonXIncludeElement(Element original, Stack<String> bases) throws XIncludeException {
Element result = new Element(original.getName(), original.getNamespace());
for (Attribute a : original.getAttributes()) {
result.setAttribute(a.clone());
@@ -352,18 +355,22 @@ public class JDOMXIncluder {
if (o instanceof Element) {
Element element = (Element)o;
if (isIncludeElement(element)) {
- result.addContent(resolveXIncludeElement(element, bases, ignoreMissing));
+ result.addContent(resolveXIncludeElement(element, bases));
}
else {
- result.addContent(resolveNonXIncludeElement(element, bases, ignoreMissing));
+ result.addContent(resolveNonXIncludeElement(element, bases));
}
}
else {
result.addContent(o.clone());
}
- } // end while
+ }
return result;
+ }
+ public interface PathResolver {
+ @NotNull
+ URL resolvePath(@NotNull String relativePath, @Nullable String base);
}
} \ No newline at end of file
diff --git a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
index 31a4127080eb..2972091e78a5 100644
--- a/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
+++ b/platform/util/testSrc/com/intellij/util/containers/ConcurrentMapsTest.java
@@ -17,15 +17,18 @@ package com.intellij.util.containers;
import com.intellij.openapi.util.text.StringUtil;
import gnu.trove.TObjectHashingStrategy;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.lang.ref.SoftReference;
import java.util.List;
import java.util.Map;
import java.util.Set;
-public class ConcurrentMapsTest extends TestCase {
- public static final TObjectHashingStrategy<String> CUSTOM_STRATEGY = new TObjectHashingStrategy<String>() {
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ConcurrentMapsTest {
+ private static final TObjectHashingStrategy<String> CUSTOM_STRATEGY = new TObjectHashingStrategy<String>() {
@Override
public int computeHashCode(String object) {
return Character.toLowerCase(object.charAt(object.length() - 1));
@@ -37,8 +40,9 @@ public class ConcurrentMapsTest extends TestCase {
}
};
+ @Test
public void testKeysRemovedWhenIdentityStrategyIsUsed() {
- ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
+ @SuppressWarnings("unchecked") ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>(TObjectHashingStrategy.IDENTITY);
map.put(new Object(), new Object());
tryGcSoftlyReachableObjects(); // sometimes weak references are not collected under linux, try to stress gc to force them
@@ -50,6 +54,7 @@ public class ConcurrentMapsTest extends TestCase {
assertEquals(1, map.underlyingMapSize());
}
+ @Test
public void testRemoveFromSoftEntrySet() {
ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
map.put(this, this);
@@ -61,6 +66,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testRemoveFromWeakEntrySet() {
ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
map.put(this, this);
@@ -72,6 +78,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testTossedWeakKeysAreRemoved() {
ConcurrentWeakHashMap<Object, Object> map = new ConcurrentWeakHashMap<Object, Object>();
map.put(new Object(), new Object());
@@ -87,13 +94,15 @@ public class ConcurrentMapsTest extends TestCase {
}
public static void tryGcSoftlyReachableObjects() {
- SoftReference reference = new SoftReference(new Object());
+ SoftReference<?> reference = new SoftReference<Object>(new Object());
List<Object> list = ContainerUtil.newArrayList();
while (reference.get() != null) {
- list.add(new SoftReference<byte[]>(new byte[(int)Runtime.getRuntime().freeMemory() / 2]));
+ int chunk = (int)Math.min(Runtime.getRuntime().freeMemory() / 2, Integer.MAX_VALUE);
+ list.add(new SoftReference<byte[]>(new byte[chunk / 2]));
}
}
+ @Test
public void testTossedSoftKeysAreRemoved() {
ConcurrentSoftHashMap<Object, Object> map = new ConcurrentSoftHashMap<Object, Object>();
map.put(new Object(), new Object());
@@ -108,6 +117,7 @@ public class ConcurrentMapsTest extends TestCase {
assertEquals(1, map.underlyingMapSize());
}
+ @Test
public void testTossedWeakValueIsRemoved() {
ConcurrentWeakValueHashMap<Object, Object> map = new ConcurrentWeakValueHashMap<Object, Object>();
map.put(new Object(), new Object());
@@ -121,6 +131,7 @@ public class ConcurrentMapsTest extends TestCase {
map.put(this, this);
assertEquals(1, map.underlyingMapSize());
}
+ @Test
public void testTossedSoftValueIsRemoved() {
ConcurrentSoftValueHashMap<Object, Object> map = new ConcurrentSoftValueHashMap<Object, Object>();
map.put(new Object(), new Object());
@@ -135,6 +146,7 @@ public class ConcurrentMapsTest extends TestCase {
assertEquals(1, map.underlyingMapSize());
}
+ @Test
public void testCustomStrategy() {
SoftHashMap<String, String> map = new SoftHashMap<String, String>(CUSTOM_STRATEGY);
@@ -145,6 +157,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testCustomStrategyForConcurrentSoft() {
ConcurrentSoftHashMap<String, String> map = new ConcurrentSoftHashMap<String, String>(CUSTOM_STRATEGY);
@@ -156,6 +169,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testCustomStrategyForConcurrentWeakSoft() {
ConcurrentWeakKeySoftValueHashMap<String, String> map = new ConcurrentWeakKeySoftValueHashMap<String, String>(1,1,1,CUSTOM_STRATEGY);
@@ -167,6 +181,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testTossedSoftKeyAndValue() {
SoftKeySoftValueHashMap<Object, Object> map = new SoftKeySoftValueHashMap<Object, Object>();
map.put(new Object(), new Object());
@@ -179,6 +194,7 @@ public class ConcurrentMapsTest extends TestCase {
assertTrue(map.isEmpty());
}
+ @Test
public void testTossedWeakKeyAndValue() {
WeakKeyWeakValueHashMap<Object, Object> map = new WeakKeyWeakValueHashMap<Object, Object>();
map.put(new Object(), new Object());
diff --git a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java
index a52bdbca47dc..4d78ad14f6a4 100644
--- a/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java
+++ b/platform/util/testSrc/com/intellij/util/containers/ContainerUtilTest.java
@@ -244,7 +244,7 @@ public class ContainerUtilTest extends TestCase {
iterator.remove();
fail("must not be able to remove before next() call");
}
- catch (IllegalStateException ignored) {
+ catch (NoSuchElementException ignored) {
}
}
int size = my.size();
@@ -268,7 +268,7 @@ public class ContainerUtilTest extends TestCase {
iterator.remove();
fail("must not be able to double remove()");
}
- catch (IllegalStateException ignored) {
+ catch (NoSuchElementException ignored) {
}
}
diff --git a/platform/util/testSrc/com/intellij/util/pico/IdeaPicoContainerTest.java b/platform/util/testSrc/com/intellij/util/pico/IdeaPicoContainerTest.java
new file mode 100644
index 000000000000..55dd486b9045
--- /dev/null
+++ b/platform/util/testSrc/com/intellij/util/pico/IdeaPicoContainerTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.pico;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.picocontainer.MutablePicoContainer;
+
+public class IdeaPicoContainerTest {
+ private MutablePicoContainer myContainer;
+
+ @Before
+ public void setUp() throws Exception {
+ myContainer = new IdeaPicoContainer();
+ }
+
+ @Test
+ public void testUnregister() throws Exception {
+ String key = "myObject";
+ MyComponentClass instance = new MyComponentClass();
+ myContainer.registerComponentInstance(key, instance);
+ Assert.assertEquals(1, myContainer.getComponentAdaptersOfType(MyComponentClass.class).size());
+ myContainer.unregisterComponent(key);
+ Assert.assertTrue(myContainer.getComponentAdaptersOfType(MyComponentClass.class).isEmpty());
+ }
+
+ private static class MyComponentClass {}
+} \ No newline at end of file
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java
index b7f4a66d38c7..9b5e7c7cde4e 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.util.PlatformUtils;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
@@ -32,7 +33,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* author: lesya
@@ -138,6 +141,8 @@ public final class VcsConfiguration implements PersistentStateComponent<VcsConfi
public boolean REARRANGE_BEFORE_PROJECT_COMMIT = false;
+ public Map<String, ChangeBrowserSettings> CHANGE_BROWSER_SETTINGS = new HashMap<String, ChangeBrowserSettings>();
+
public float FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION = 0.8f;
public float FILE_HISTORY_DIALOG_SPLITTER_PROPORTION = 0.5f;
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/ShowAllAffectedGenericAction.java b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/ShowAllAffectedGenericAction.java
index 680341da4a59..4759b915aea4 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/ShowAllAffectedGenericAction.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/annotate/ShowAllAffectedGenericAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
@@ -42,7 +43,7 @@ import java.util.List;
* Date: 3/16/11
* Time: 2:41 PM
*/
-public class ShowAllAffectedGenericAction extends AnAction {
+public class ShowAllAffectedGenericAction extends AnAction implements DumbAware {
private static final String ACTION_ID = "VcsHistory.ShowAllAffected";
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutorBase.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutorBase.java
new file mode 100644
index 000000000000..6d8ef0f0518b
--- /dev/null
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/CommitExecutorBase.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vcs.changes;
+
+public abstract class CommitExecutorBase implements CommitExecutor {
+
+ public boolean areChangesRequired() {
+ return true;
+ }
+}
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/versionBrowser/ChangeBrowserSettings.java b/platform/vcs-api/src/com/intellij/openapi/vcs/versionBrowser/ChangeBrowserSettings.java
index a747cea04c33..cd2806d15eda 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/versionBrowser/ChangeBrowserSettings.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/versionBrowser/ChangeBrowserSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,43 +15,45 @@
*/
package com.intellij.openapi.vcs.versionBrowser;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.*;
import com.intellij.util.text.SyncDateFormat;
import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.text.SimpleDateFormat;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
public class ChangeBrowserSettings implements JDOMExternalizable {
- @NonNls public static final String HEAD = "HEAD";
public interface Filter {
boolean accepts(CommittedChangeList change);
}
+ public static final String HEAD = "HEAD";
+ public static final SyncDateFormat DATE_FORMAT = new SyncDateFormat(DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG));
+
+ private static final Logger LOG = Logger.getInstance(ChangeBrowserSettings.class);
+
public boolean USE_DATE_BEFORE_FILTER = false;
public boolean USE_DATE_AFTER_FILTER = false;
public boolean USE_CHANGE_BEFORE_FILTER = false;
public boolean USE_CHANGE_AFTER_FILTER = false;
-
public String DATE_BEFORE = "";
public String DATE_AFTER = "";
- @NonNls public String CHANGE_BEFORE = "";
+ public String CHANGE_BEFORE = "";
public String CHANGE_AFTER = "";
public boolean USE_USER_FILTER = false;
public String USER = "";
public boolean STOP_ON_COPY = false;
- public static final SyncDateFormat DATE_FORMAT = new SyncDateFormat(SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG,
- SimpleDateFormat.LONG));
-
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
@@ -60,38 +62,33 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
DefaultJDOMExternalizer.writeExternal(this, element);
}
- private static Date parseDate(final String dateStr) {
- if (dateStr == null) return null;
+ @Nullable
+ private static Date parseDate(@Nullable String dateStr) {
+ if (dateStr == null || dateStr.isEmpty()) return null;
try {
return DATE_FORMAT.parse(dateStr);
}
catch (Exception e) {
+ LOG.warn(e);
return null;
}
}
- public void setDateBefore(final Date value) {
- if (value == null) {
- DATE_BEFORE = null;
- }
- else {
- DATE_BEFORE = DATE_FORMAT.format(value);
- }
+ public void setDateBefore(@Nullable Date value) {
+ DATE_BEFORE = value == null ? null : DATE_FORMAT.format(value);
}
+ @Nullable
public Date getDateBefore() {
return parseDate(DATE_BEFORE);
}
+ @Nullable
public Date getDateAfter() {
- if (USE_DATE_AFTER_FILTER) {
- return parseDate(DATE_AFTER);
- }
- else {
- return null;
- }
+ return parseDate(DATE_AFTER);
}
+ @Nullable
public Long getChangeBeforeFilter() {
if (USE_CHANGE_BEFORE_FILTER && CHANGE_BEFORE.length() > 0) {
if (HEAD.equals(CHANGE_BEFORE)) return null;
@@ -100,15 +97,12 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
return null;
}
+ @Nullable
public Date getDateBeforeFilter() {
- if (USE_DATE_BEFORE_FILTER) {
- return parseDate(DATE_BEFORE);
- }
- else {
- return null;
- }
+ return USE_DATE_BEFORE_FILTER ? parseDate(DATE_BEFORE) : null;
}
+ @Nullable
public Long getChangeAfterFilter() {
if (USE_CHANGE_AFTER_FILTER && CHANGE_AFTER.length() > 0) {
return Long.parseLong(CHANGE_AFTER);
@@ -116,20 +110,16 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
return null;
}
+ @Nullable
public Date getDateAfterFilter() {
- return parseDate(DATE_AFTER);
+ return USE_DATE_AFTER_FILTER ? parseDate(DATE_AFTER) : null;
}
- public void setDateAfter(final Date value) {
- if (value == null) {
- DATE_AFTER = null;
-
- }
- else {
- DATE_AFTER = DATE_FORMAT.format(value);
- }
+ public void setDateAfter(@Nullable Date value) {
+ DATE_AFTER = value == null ? null : DATE_FORMAT.format(value);
}
+ @NotNull
protected List<Filter> createFilters() {
final ArrayList<Filter> result = new ArrayList<Filter>();
addDateFilter(USE_DATE_BEFORE_FILTER, getDateBefore(), result, true);
@@ -146,6 +136,7 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
}
catch (NumberFormatException e) {
//ignore
+ LOG.info(e);
}
}
@@ -160,6 +151,7 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
}
catch (NumberFormatException e) {
//ignore
+ LOG.info(e);
}
}
@@ -174,10 +166,7 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
return result;
}
- private static void addDateFilter(final boolean useFilter,
- final Date date,
- final ArrayList<Filter> result,
- final boolean before) {
+ private static void addDateFilter(final boolean useFilter, final Date date, final ArrayList<Filter> result, final boolean before) {
if (useFilter) {
assert date != null;
result.add(new Filter() {
@@ -191,6 +180,7 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
}
}
+ @NotNull
public Filter createFilter() {
final List<Filter> filters = createFilters();
return new Filter() {
@@ -203,7 +193,7 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
};
}
- public void filterChanges(final List<? extends CommittedChangeList> changeListInfos) {
+ public void filterChanges(@NotNull List<? extends CommittedChangeList> changeListInfos) {
Filter filter = createFilter();
for (Iterator<? extends CommittedChangeList> iterator = changeListInfos.iterator(); iterator.hasNext();) {
CommittedChangeList changeListInfo = iterator.next();
@@ -213,13 +203,9 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
}
}
+ @Nullable
public String getUserFilter() {
- if (USE_USER_FILTER) {
- return USER;
- }
- else {
- return null;
- }
+ return USE_USER_FILTER ? USER : null;
}
public boolean isAnyFilterSpecified() {
diff --git a/platform/vcs-api/src/com/intellij/util/ui/ConfirmationDialog.java b/platform/vcs-api/src/com/intellij/util/ui/ConfirmationDialog.java
index d8b2adc8d0ad..3141d5dfd8f5 100644
--- a/platform/vcs-api/src/com/intellij/util/ui/ConfirmationDialog.java
+++ b/platform/vcs-api/src/com/intellij/util/ui/ConfirmationDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +73,7 @@ public class ConfirmationDialog extends OptionsMessageDialog {
myCheckBoxDoNotShowDialog.setText(doNotShowAgainMessage);
}
+ @NotNull
@Override
protected String getDoNotShowMessage() {
return myDoNotShowAgainMessage == null ? super.getDoNotShowMessage() : myDoNotShowAgainMessage;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
index dfce14728906..7db646c94b5b 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -43,6 +43,7 @@ import com.intellij.ui.components.JBLoadingPanel;
import com.intellij.ui.table.JBTable;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.StatusText;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -826,6 +827,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
return true;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return "Do not ask me again";
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
index 5bcb5fbf165d..0b09f753168f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/CommitCompletionContributor.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.vcs.ui.CommitMessage;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
+import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -36,7 +37,7 @@ import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
public class CommitCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document != null) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
index 97f5277ab6e5..025795eb08ed 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
@@ -171,7 +171,8 @@ public class ChangesFragmentedDiffPanel implements Disposable {
descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
} else {
if (((DiffPanelImpl) panel).getEditor1().getDocument().getTextLength() == 0) {
- FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0), true);
+ FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0),
+ true);
return;
}
@@ -281,11 +282,13 @@ public class ChangesFragmentedDiffPanel implements Disposable {
FragmentedEditorHighlighter bh = fragmentedContent.getBeforeHighlighter();
if (bh != null) {
- ((EditorEx) ((DiffPanelImpl) currentPanel).getEditor1()).setHighlighter(bh);
+ ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor1()).setHighlighter(bh);
+ ((EditorEx) ((DiffPanelImpl) myVertical).getEditor1()).setHighlighter(bh);
}
FragmentedEditorHighlighter ah = fragmentedContent.getAfterHighlighter();
if (ah != null) {
- ((EditorEx) ((DiffPanelImpl) currentPanel).getEditor2()).setHighlighter(ah);
+ ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor2()).setHighlighter(ah);
+ ((EditorEx) ((DiffPanelImpl) myVertical).getEditor2()).setHighlighter(ah);
}
if (((DiffPanelImpl) currentPanel).getEditor1() != null) {
highlightTodo(true, fragmentedContent.getBeforeTodoRanges());
@@ -335,7 +338,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
final DiffPanel diffPanel = new DiffPanelImpl(null, myProject, false, horizontal, SHORT_DIFF_DIVIDER_POLYGONS_OFFSET, null) {
@Override
protected DiffPanelState createDiffPanelState(@NotNull Disposable parentDisposable) {
- return new FragmentedDiffPanelState(this, myProject, ! horizontal, parentDisposable);
+ return new FragmentedDiffPanelState(this, myProject, getDiffDividerPolygonsOffset(), ! horizontal, parentDisposable);
}
};
diffPanel.enableToolbar(false);
@@ -403,7 +406,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
}
private static final Icon ourIcon = PlatformIcons.CHECK_ICON;
-
+
private class PopupAction extends DumbAwareAction {
private final AnAction myUsual;
private final AnAction myNumbered;
@@ -680,7 +683,7 @@ public class ChangesFragmentedDiffPanel implements Disposable {
private class MyNextDiffAction extends DumbAwareAction {
private boolean myEnabled;
-
+
private MyNextDiffAction() {
super("Next Change", "Next Change", AllIcons.Actions.NextOccurence);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
index 5b3860523a91..00c9c6c1a0c5 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +36,7 @@ public class VcsConfirmationDialog extends OptionsDialog {
private final String myMessage;
private final String myDoNotShowMessage;
- protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, String doNotShowMessage) {
+ protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, @NotNull String doNotShowMessage) {
super(project);
myOption = option;
myMessage = message;
@@ -68,6 +68,7 @@ public class VcsConfirmationDialog extends OptionsDialog {
return panel;
}
+ @NotNull
@Override
protected String getDoNotShowMessage() {
return myDoNotShowMessage;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
index 87bb5a338ca7..521071b0faf4 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/BrowseChangesAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -41,7 +41,12 @@ public class BrowseChangesAction extends AnAction implements DumbAware {
assert vcs != null;
final CommittedChangesProvider provider = vcs.getCommittedChangesProvider();
assert provider != null;
- ChangeBrowserSettings settings = provider.createDefaultSettings();
+ final VcsConfiguration vcsConfiguration = VcsConfiguration.getInstance(project);
+ ChangeBrowserSettings settings = vcsConfiguration.CHANGE_BROWSER_SETTINGS.get(vcs.getName());
+ if (settings == null) {
+ settings = provider.createDefaultSettings();
+ vcsConfiguration.CHANGE_BROWSER_SETTINGS.put(vcs.getName(), settings);
+ }
CommittedChangesFilterDialog dlg = new CommittedChangesFilterDialog(project, provider.createFilterUI(true), settings);
dlg.show();
if (!dlg.isOK()) return;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
index 99c8d796c38b..60750b1cdbad 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotifications;
+import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -34,11 +35,14 @@ public class ChangelistConflictNotificationProvider extends EditorNotifications.
myConflictTracker = changeListManager.getConflictTracker();
}
+ @Override
+ @NotNull
public Key<ChangelistConflictNotificationPanel> getKey() {
return KEY;
}
- public ChangelistConflictNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ @Override
+ public ChangelistConflictNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
return myConflictTracker.hasConflict(file) ? ChangelistConflictNotificationPanel.create(myConflictTracker, file) : null;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
index c213feb38c40..e76ba194672e 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
@@ -294,7 +294,9 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
}
private void notifyStateChanged() {
- myBus.syncPublisher(SHELF_TOPIC).stateChanged(new ChangeEvent(this));
+ if (!myProject.isDisposed()) {
+ myBus.syncPublisher(SHELF_TOPIC).stateChanged(new ChangeEvent(this));
+ }
}
private File getPatchPath(@NonNls final String commitMessage) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
index ffa8b2a97fc5..497db3da7d9f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java
@@ -85,7 +85,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private String myLastKnownComment = "";
private final boolean myAllOfDefaultChangeListChangesIncluded;
@NonNls private static final String SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.SPLITTER_PROPORTION_" + LAYOUT_VERSION;
- private final Action[] myExecutorActions;
+ private final CommitExecutorAction[] myExecutorActions;
private final boolean myShowVcsCommit;
private final Map<AbstractVcs, JPanel> myPerVcsOptionsPanels = new HashMap<AbstractVcs, JPanel>();
@@ -103,7 +103,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private final PseudoMap<Object, Object> myAdditionalData;
private String myHelpId;
-
+
private SplitterWithSecondHideable myDetailsSplitter;
private static final String DETAILS_SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_" + LAYOUT_VERSION;
private static final String DETAILS_SHOW_OPTION = "CommitChangeListDialog.DETAILS_SHOW_OPTION_";
@@ -142,9 +142,15 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private final MyUpdateButtonsRunnable myUpdateButtonsRunnable = new MyUpdateButtonsRunnable(this);
- private static boolean commit(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
- final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
- @Nullable CommitResultHandler customResultHandler) {
+ public static boolean commitChanges(final Project project, final List<Change> changes, final LocalChangeList initialSelection,
+ final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
+ @Nullable CommitResultHandler customResultHandler, boolean cancelIfNoChanges) {
+ if (cancelIfNoChanges && changes.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
+ Messages.showInfoMessage(project, VcsBundle.message("commit.dialog.no.changes.detected.text"),
+ VcsBundle.message("commit.dialog.no.changes.detected.title"));
+ return false;
+ }
+
for (BaseCheckinHandlerFactory factory : getCheckInFactories(project)) {
BeforeCheckinDialogHandler handler = factory.createSystemReadyHandler(project);
if (handler != null && !handler.beforeCommitDialogShown(project, changes, executors, showVcsCommit)) {
@@ -208,13 +214,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
public static boolean commitChanges(final Project project, final Collection<Change> changes, final LocalChangeList initialSelection,
final List<CommitExecutor> executors, final boolean showVcsCommit, final String comment,
@Nullable CommitResultHandler customResultHandler) {
- if (changes.isEmpty() && !ApplicationManager.getApplication().isUnitTestMode()) {
- Messages.showInfoMessage(project, VcsBundle.message("commit.dialog.no.changes.detected.text") ,
- VcsBundle.message("commit.dialog.no.changes.detected.title"));
- return false;
- }
-
- return commit(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment, customResultHandler);
+ return commitChanges(project, new ArrayList<Change>(changes), initialSelection, executors, showVcsCommit, comment,
+ customResultHandler, true);
}
public static void commitAlienChanges(final Project project, final List<Change> changes, final AbstractVcs vcs,
@@ -317,7 +318,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myZipperUpdater.queue(myRefreshDetails);
}
});
-
+
myBrowserExtender.addToolbarActions(this);
myBrowserExtender.addSelectedListChangeListener(new SelectedListChangeListener() {
@@ -447,7 +448,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
restoreState();
if (myExecutors != null) {
- myExecutorActions = new Action[myExecutors.size()];
+ myExecutorActions = new CommitExecutorAction[myExecutors.size()];
for (int i = 0; i < myExecutors.size(); i++) {
final CommitExecutor commitExecutor = myExecutors.get(i);
@@ -466,10 +467,10 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
init();
updateButtons();
updateVcsOptionsVisibility();
-
+
updateOnListSelection();
myCommitMessageArea.requestFocusInMessage();
-
+
for (EditChangelistSupport support : Extensions.getExtensions(EditChangelistSupport.EP_NAME, project)) {
support.installSearch(myCommitMessageArea.getEditorField(), myCommitMessageArea.getEditorField());
}
@@ -829,7 +830,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
if (configuration != null) {
configuration.CHECK_COMMIT_MESSAGE_SPELLING = checkSpelling;
}
- myCommitMessageArea.setCheckSpelling(checkSpelling);
+ myCommitMessageArea.setCheckSpelling(checkSpelling);
}
private boolean checkComment() {
@@ -853,7 +854,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myDisposed = false;
myUpdateButtonsRunnable.restart(this);
}
-
+
private CheckinHandler.ReturnResult runBeforeCommitHandlers(final Runnable okAction, final CommitExecutor executor) {
final Computable<CheckinHandler.ReturnResult> proceedRunnable = new Computable<CheckinHandler.ReturnResult>() {
@Override
@@ -1244,8 +1245,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myCommitAction.setEnabled(enabled);
}
if (myExecutorActions != null) {
- for (Action executorAction : myExecutorActions) {
- executorAction.setEnabled(enabled);
+ for (CommitExecutorAction executorAction : myExecutorActions) {
+ executorAction.updateEnabled(enabled);
}
}
myOKButtonUpdateAlarm.cancelAllRequests();
@@ -1268,7 +1269,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
protected String getDimensionServiceKey() {
return "CommitChangelistDialog" + LAYOUT_VERSION;
}
-
+
@Override
public JComponent getPreferredFocusedComponent() {
return myCommitMessageArea.getEditorField();
@@ -1323,6 +1324,11 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
callExecutor.run();
}
}
+
+ public void updateEnabled(boolean hasDiffs) {
+ setEnabled(hasDiffs
+ || (myCommitExecutor instanceof CommitExecutorBase) && !((CommitExecutorBase)myCommitExecutor).areChangesRequired());
+ }
}
private static class DiffCommitMessageEditor extends CommitMessage implements Disposable {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
index 2e34d7819e77..19b1420ddda9 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
@@ -41,6 +41,7 @@ import com.intellij.openapi.vcs.checkin.CheckinHandler;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.update.RefreshVFsSynchronously;
import com.intellij.util.Consumer;
+import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.concurrency.Semaphore;
@@ -581,7 +582,7 @@ public class CommitHelper {
}
else {
if (myCustomResultHandler == null) {
- showErrorDialogAndMoveToAnotherList(processor, errorsSize, warningsSize);
+ showErrorDialogAndMoveToAnotherList(processor, errorsSize, warningsSize, errors);
}
else {
myCustomResultHandler.onFailure();
@@ -589,19 +590,26 @@ public class CommitHelper {
}
}
- private void showErrorDialogAndMoveToAnotherList(final GeneralCommitProcessor processor, final int errorsSize, final int warningsSize) {
+ private void showErrorDialogAndMoveToAnotherList(final GeneralCommitProcessor processor, final int errorsSize, final int warningsSize,
+ @NotNull final List<VcsException> errors) {
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
public void run() {
- final String message;
+ String message;
if (errorsSize > 0 && warningsSize > 0) {
message = VcsBundle.message("message.text.commit.failed.with.errors.and.warnings");
}
else if (errorsSize > 0) {
- message = VcsBundle.message("message.text.commit.failed.with.errors");
+ message = StringUtil.pluralize(VcsBundle.message("message.text.commit.failed.with.error"), errorsSize);
}
else {
- message = VcsBundle.message("message.text.commit.finished.with.warnings");
+ message = StringUtil.pluralize(VcsBundle.message("message.text.commit.finished.with.warning"), warningsSize);
}
+ message += ":\n" + StringUtil.join(errors, new Function<VcsException, String>() {
+ @Override
+ public String fun(VcsException e) {
+ return e.getMessage();
+ }
+ }, "\n");
//new VcsBalloonProblemNotifier(myProject, message, MessageType.ERROR).run();
Messages.showErrorDialog(message, VcsBundle.message("message.title.commit"));
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
new file mode 100644
index 000000000000..fe9c12036596
--- /dev/null
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vcs.changes.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.FilePath;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.tree.DefaultTreeModel;
+import java.util.List;
+
+public class FilePathChangesTreeList extends ChangesTreeList<FilePath> {
+ private final Project myProject;
+
+ public FilePathChangesTreeList(@NotNull Project project, @NotNull List<FilePath> originalFiles,
+ boolean showCheckboxes, boolean highlightProblems,
+ @Nullable Runnable inclusionListener, @Nullable ChangeNodeDecorator nodeDecorator) {
+ super(project, originalFiles, showCheckboxes, highlightProblems, inclusionListener, nodeDecorator);
+ myProject = project;
+ }
+
+ protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
+ return new TreeModelBuilder(myProject, false).buildModelFromFilePaths(changes);
+ }
+
+ protected List<FilePath> getSelectedObjects(final ChangesBrowserNode<FilePath> node) {
+ return node.getAllFilePathsUnder();
+ }
+
+ @Nullable
+ protected FilePath getLeadSelectedObject(final ChangesBrowserNode node) {
+ final Object userObject = node.getUserObject();
+ if (userObject instanceof FilePath) {
+ return (FilePath) userObject;
+ }
+ return null;
+ }
+}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
index b27dc2e64d63..61bcd6ea2ae6 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilePathsDialog.java
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.tree.DefaultTreeModel;
import java.util.Collection;
import java.util.List;
@@ -38,24 +37,7 @@ public class SelectFilePathsDialog extends AbstractSelectFilesDialog<FilePath> {
final VcsShowConfirmationOption confirmationOption,
@Nullable String okActionName, @Nullable String cancelActionName, boolean showDoNotAskOption) {
super(project, false, confirmationOption, prompt, showDoNotAskOption);
- myFileList = new ChangesTreeList<FilePath>(project, originalFiles, true, true, null, null) {
- protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
- return new TreeModelBuilder(project, false).buildModelFromFilePaths(changes);
- }
-
- protected List<FilePath> getSelectedObjects(final ChangesBrowserNode node) {
- return node.getAllFilePathsUnder();
- }
-
- @Nullable
- protected FilePath getLeadSelectedObject(final ChangesBrowserNode node) {
- final Object userObject = node.getUserObject();
- if (userObject instanceof FilePath) {
- return (FilePath) userObject;
- }
- return null;
- }
- };
+ myFileList = new FilePathChangesTreeList(project, originalFiles, true, true, null, null);
if (okActionName != null) {
getOKAction().putValue(Action.NAME, okActionName);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
index 6c139f9d069f..8806e4544a9c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/SelectFilesDialog.java
@@ -93,7 +93,7 @@ public class SelectFilesDialog extends AbstractSelectFilesDialog<VirtualFile> {
return defaultGroup;
}
- private static class VirtualFileList extends ChangesTreeList<VirtualFile> {
+ public static class VirtualFileList extends ChangesTreeList<VirtualFile> {
private final Project myProject;
@Nullable private final DeleteProvider myDeleteProvider;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
index 587628a27c0b..304275d732d7 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurable.java
@@ -78,6 +78,11 @@ public class VcsManagerConfigurable extends SearchableConfigurable.Parent.Abstra
}
@Override
+ public boolean isVisible() {
+ return ProjectLevelVcsManager.getInstance(myProject).getAllVcss().length > 0;
+ }
+
+ @Override
public void disposeUIResources() {
super.disposeUIResources();
if (myMappings != null) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
index e43a499f9a33..3ddfe8d9b188 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
@@ -31,6 +32,7 @@ import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,28 +44,25 @@ import java.awt.*;
* @author Kirill Likhodedov
*/
class VcsUpdateInfoScopeFilterConfigurable implements Configurable, NamedScopesHolder.ScopeListener {
-
private final JCheckBox myCheckbox;
private final JComboBox myComboBox;
- private final Project myProject;
private final VcsConfiguration myVcsConfiguration;
private final NamedScopesHolder[] myNamedScopeHolders;
VcsUpdateInfoScopeFilterConfigurable(Project project, VcsConfiguration vcsConfiguration) {
- myProject = project;
myVcsConfiguration = vcsConfiguration;
myCheckbox = new JCheckBox(VcsBundle.getString("settings.filter.update.project.info.by.scope"));
- myComboBox = new JComboBox();
+ myComboBox = new ComboBox();
myComboBox.setEnabled(myCheckbox.isSelected());
myCheckbox.addChangeListener(new ChangeListener() {
@Override
- public void stateChanged(ChangeEvent e) {
+ public void stateChanged(@NotNull ChangeEvent e) {
myComboBox.setEnabled(myCheckbox.isSelected());
}
});
- myNamedScopeHolders = NamedScopesHolder.getAllNamedScopeHolders(myProject);
+ myNamedScopeHolders = NamedScopesHolder.getAllNamedScopeHolders(project);
for (NamedScopesHolder holder : myNamedScopeHolders) {
holder.addScopeListener(this);
}
@@ -93,12 +92,12 @@ class VcsUpdateInfoScopeFilterConfigurable implements Configurable, NamedScopesH
panel.add(myCheckbox);
panel.add(myComboBox);
panel.add(Box.createHorizontalStrut(UIUtil.DEFAULT_HGAP));
- panel.add(new LinkLabel("Edit scopes", null, new LinkListener() {
+ panel.add(new LinkLabel("Manage Scopes", null, new LinkListener() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
- final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext(panel));
+ OptionsEditor optionsEditor = OptionsEditor.KEY.getData(DataManager.getInstance().getDataContext(panel));
if (optionsEditor != null) {
- SearchableConfigurable configurable = optionsEditor.findConfigurableById(new ScopeChooserConfigurable(myProject).getId());
+ SearchableConfigurable configurable = optionsEditor.findConfigurableById(ScopeChooserConfigurable.PROJECT_SCOPES);
if (configurable != null) {
optionsEditor.select(configurable);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
index bf71a2ffee7c..d6362ffe19c9 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/DocumentWrapper.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.vcs.ex;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -27,7 +28,7 @@ import java.util.List;
public class DocumentWrapper {
private final Document myDocument;
- public DocumentWrapper(Document document) {
+ public DocumentWrapper(@NotNull Document document) {
myDocument = document;
}
@@ -35,10 +36,12 @@ public class DocumentWrapper {
return myDocument.getLineNumber(offset);
}
+ @NotNull
public List<String> getLines() {
return getLines(0, myDocument.getLineCount() - 1);
}
+ @NotNull
public List<String> getLines(int from, int to) {
ArrayList<String> result = new ArrayList<String>();
for (int i = from; i <= to; i++) {
@@ -54,6 +57,7 @@ public class DocumentWrapper {
return result;
}
+ @NotNull
private String getLine(final int i) {
TextRange range = new TextRange(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i));
if (range.getLength() < 0) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
index 548cc514b300..ac0bc8608368 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
@@ -38,26 +38,26 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* @author irengrig
- * author: lesya
+ * author: lesya
*/
public class LineStatusTracker {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.ex.LineStatusTracker");
- private static final Key<CanNotCalculateDiffPanel> PANEL_KEY = new Key<CanNotCalculateDiffPanel>("LineStatusTracker.CanNotCalculateDiffPanel");
+ private static final Key<CanNotCalculateDiffPanel> PANEL_KEY =
+ new Key<CanNotCalculateDiffPanel>("LineStatusTracker.CanNotCalculateDiffPanel");
private final Object myLock = new Object();
- // true -> have contents
private BaseLoadState myBaseLoaded;
private final Document myDocument;
@@ -71,15 +71,17 @@ public class LineStatusTracker {
private boolean myBulkUpdate;
private final Application myApplication;
- @Nullable
- private RevisionPack myBaseRevisionNumber;
+ @Nullable private RevisionPack myBaseRevisionNumber;
private String myPreviousBaseRevision;
private boolean myAnathemaThrown;
private FileEditorManager myFileEditorManager;
private final VirtualFile myVirtualFile;
private boolean myReleased = false;
- private LineStatusTracker(final Document document, final Document upToDateDocument, final Project project, final VirtualFile virtualFile) {
+ private LineStatusTracker(@NotNull final Document document,
+ @NotNull final Document upToDateDocument,
+ final Project project,
+ @Nullable final VirtualFile virtualFile) {
myVirtualFile = virtualFile;
myApplication = ApplicationManager.getApplication();
myDocument = document;
@@ -156,7 +158,7 @@ public class LineStatusTracker {
}
private void removeAnathema() {
- if (! myAnathemaThrown) return;
+ if (!myAnathemaThrown) return;
myAnathemaThrown = false;
final FileEditor[] editors = myFileEditorManager.getEditors(myVirtualFile);
for (FileEditor editor : editors) {
@@ -171,6 +173,7 @@ public class LineStatusTracker {
@SuppressWarnings({"AutoBoxing"})
private RangeHighlighter createHighlighter(final Range range) {
LOG.assertTrue(!myReleased, "Already released");
+
int first =
range.getOffset1() >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getOffset1());
@@ -179,6 +182,7 @@ public class LineStatusTracker {
final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true)
.addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, null, HighlighterTargetArea.LINES_IN_RANGE);
+
final TextAttributes attr = LineStatusTrackerDrawing.getAttributesFor(range);
highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor());
highlighter.setThinErrorStripeMark(true);
@@ -186,14 +190,21 @@ public class LineStatusTracker {
highlighter.setGreedyToRight(true);
highlighter.setLineMarkerRenderer(LineStatusTrackerDrawing.createRenderer(range, this));
highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter());
- final int line1 = myDocument.getLineNumber(first);
- final int line2 = myDocument.getLineNumber(second);
+
final String tooltip;
- if (line1 == line2) {
- tooltip = VcsBundle.message("tooltip.text.line.changed", line1);
+ if (range.getOffset1() == range.getOffset2()) {
+ if (range.getUOffset1() + 1 == range.getUOffset2()) {
+ tooltip = VcsBundle.message("tooltip.text.line.before.deleted", range.getOffset1() + 1);
+ }
+ else {
+ tooltip = VcsBundle.message("tooltip.text.lines.before.deleted", range.getOffset1() + 1, range.getUOffset2() - range.getUOffset1());
+ }
+ }
+ else if (range.getOffset1() + 1 == range.getOffset2()) {
+ tooltip = VcsBundle.message("tooltip.text.line.changed", range.getOffset1() + 1);
}
else {
- tooltip = VcsBundle.message("tooltip.text.lines.changed", line1, line2);
+ tooltip = VcsBundle.message("tooltip.text.lines.changed", range.getOffset1() + 1, range.getOffset2());
}
highlighter.setErrorStripeTooltip(tooltip);
@@ -285,11 +296,15 @@ public class LineStatusTracker {
}
private class MyDocumentListener extends DocumentAdapter {
+ // We have 3 document versions:
+ // * VCS version - upToDate*
+ // * before change - my*
+ // * after change - current*
+
private int myFirstChangedLine;
- private int myUpToDateFirstLine;
- private int myUpToDateLastLine;
private int myLastChangedLine;
- private int myLinesBeforeChange;
+ private int myChangedLines;
+ private int myTotalLines;
private final VcsDirtyScopeManager myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
@Override
@@ -302,50 +317,15 @@ public class LineStatusTracker {
try {
myFirstChangedLine = myDocument.getLineNumber(e.getOffset());
myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength());
+ myChangedLines = myLastChangedLine - myFirstChangedLine;
if (StringUtil.endsWithChar(e.getOldFragment(), '\n')) myLastChangedLine++;
-
- myLinesBeforeChange = myDocument.getLineNumber(e.getOffset() + e.getOldLength()) - myDocument.getLineNumber(e.getOffset());
-
- Range firstChangedRange = getLastRangeBeforeLine(myFirstChangedLine);
-
- if (firstChangedRange == null) {
- myUpToDateFirstLine = myFirstChangedLine;
- }
- else if (firstChangedRange.containsLine(myFirstChangedLine)) {
- myFirstChangedLine = firstChangedRange.getOffset1();
- myUpToDateFirstLine = firstChangedRange.getUOffset1();
- }
- else {
- myUpToDateFirstLine = firstChangedRange.getUOffset2() + myFirstChangedLine - firstChangedRange.getOffset2();
- }
-
- Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine);
-
- if (myLastChangedRange == null) {
- myUpToDateLastLine = myLastChangedLine;
- }
- else if (myLastChangedRange.containsLine(myLastChangedLine)) {
- myUpToDateLastLine = myLastChangedRange.getUOffset2();
- myLastChangedLine = myLastChangedRange.getOffset2();
- }
- else {
- myUpToDateLastLine = myLastChangedRange.getUOffset2() + myLastChangedLine - myLastChangedRange.getOffset2();
- }
- } catch (ProcessCanceledException ignore) {
+ myTotalLines = e.getDocument().getLineCount();
+ }
+ catch (ProcessCanceledException ignore) {
}
}
}
- @Nullable
- private Range getLastRangeBeforeLine(int line) {
- Range result = null;
- for (Range range : myRanges) {
- if (range.isAfter(line)) return result;
- result = range;
- }
- return result;
- }
-
@Override
public void documentChanged(final DocumentEvent e) {
myApplication.assertWriteAccessAllowed();
@@ -354,41 +334,46 @@ public class LineStatusTracker {
if (myReleased) return;
if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return;
try {
+ int currentChangedLines = myDocument.getLineNumber(e.getOffset() + e.getNewLength()) - myDocument.getLineNumber(e.getOffset());
+ int linesShift = currentChangedLines - myChangedLines;
+ int upToDateTotalLine = myUpToDateDocument.getLineCount();
- int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength());
- int linesAfterChange = line - myDocument.getLineNumber(e.getOffset());
- int linesShift = linesAfterChange - myLinesBeforeChange;
-
- List<Range> rangesAfterChange = getRangesAfter(myRanges, myLastChangedLine);
- List<Range> rangesBeforeChange = getRangesBefore(myRanges, myFirstChangedLine);
+ List<Range> rangesBeforeChange = new ArrayList<Range>();
+ List<Range> rangesAfterChange = new ArrayList<Range>();
+ List<Range> changedRanges = new ArrayList<Range>();
+ sortRanges(myRanges, myFirstChangedLine, myLastChangedLine, rangesBeforeChange, changedRanges, rangesAfterChange);
- List<Range> changedRanges = getChangedRanges(myFirstChangedLine, myLastChangedLine);
+ Range firstChangedRange = ContainerUtil.getFirstItem(changedRanges);
+ Range lastChangedRange = ContainerUtil.getLastItem(changedRanges);
+ Range lastRangeBefore = ContainerUtil.getLastItem(rangesBeforeChange);
+ Range firstRangeAfter = ContainerUtil.getFirstItem(rangesAfterChange);
- int newSize = rangesBeforeChange.size() + changedRanges.size() + rangesAfterChange.size();
- if (myRanges.size() != newSize) {
- LOG.info("Ranges: " + myRanges + "; first changed line: " + myFirstChangedLine + "; last changed line: " + myLastChangedLine);
- LOG.assertTrue(false);
+ if (firstChangedRange != null && firstChangedRange.getOffset1() < myFirstChangedLine) {
+ myFirstChangedLine = firstChangedRange.getOffset1();
+ }
+ if (lastChangedRange != null && lastChangedRange.getOffset2() > myLastChangedLine) {
+ myLastChangedLine = lastChangedRange.getOffset2() - 1;
}
+ int currentFirstLine = myFirstChangedLine;
+ int currentLastLine = myLastChangedLine + linesShift;
- myLastChangedLine += linesShift;
-
+ int upToDateFirstLine = getUpToDateLine1(lastRangeBefore, myFirstChangedLine);
+ int upToDateLastLine = getUpToDateLine2(firstRangeAfter, myLastChangedLine, myTotalLines, upToDateTotalLine);
- List<Range> newChangedRanges = getNewChangedRanges();
+ List<Range> newChangedRanges = getNewChangedRanges(currentFirstLine, currentLastLine, upToDateFirstLine, upToDateLastLine);
shiftRanges(rangesAfterChange, linesShift);
if (!changedRanges.equals(newChangedRanges)) {
replaceRanges(changedRanges, newChangedRanges);
- myRanges = new ArrayList<Range>();
+ myRanges = new ArrayList<Range>(rangesBeforeChange.size() + newChangedRanges.size() + rangesAfterChange.size());
myRanges.addAll(rangesBeforeChange);
myRanges.addAll(newChangedRanges);
myRanges.addAll(rangesAfterChange);
- myRanges = mergeRanges(myRanges);
-
for (Range range : myRanges) {
if (!range.hasHighlighter()) range.setHighlighter(createHighlighter(range));
}
@@ -410,49 +395,36 @@ public class LineStatusTracker {
});
}
}
- } catch (ProcessCanceledException ignore) {
- } catch (FilesTooBigForDiffException e1) {
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ catch (FilesTooBigForDiffException e1) {
installAnathema();
removeHighlightersFromMarkupModel();
}
}
}
- private List<Range> getNewChangedRanges() throws FilesTooBigForDiffException {
- List<String> lines = new DocumentWrapper(myDocument).getLines(myFirstChangedLine, myLastChangedLine);
- List<String> uLines = new DocumentWrapper(myUpToDateDocument)
- .getLines(myUpToDateFirstLine, myUpToDateLastLine);
- return new RangesBuilder(lines, uLines, myFirstChangedLine, myUpToDateFirstLine).getRanges();
+ private int getUpToDateLine1(@Nullable Range range, int line) {
+ return range == null ? line : line + range.getUOffset2() - range.getOffset2();
}
- private List<Range> mergeRanges(List<Range> ranges) {
- ArrayList<Range> result = new ArrayList<Range>();
- Iterator<Range> iterator = ranges.iterator();
- if (!iterator.hasNext()) return result;
- Range prev = iterator.next();
- while (iterator.hasNext()) {
- Range range = iterator.next();
- if (prev.canBeMergedWith(range)) {
- if (range.getHighlighter() != null) {
- range.getHighlighter().dispose();
- }
- if (prev.getHighlighter() != null) {
- prev.getHighlighter().dispose();
- }
- prev = prev.mergeWith(range);
- }
- else {
- result.add(prev);
- prev = range;
- }
- }
- result.add(prev);
- return result;
+ private int getUpToDateLine2(@Nullable Range range, int line, int totalLinesBefore, int totalLinesAfter) {
+ return range == null ? totalLinesAfter - totalLinesBefore + line : line + range.getUOffset1() - range.getOffset1();
+ }
+
+ private List<Range> getNewChangedRanges(int firstChangedLine, int lastChangedLine, int upToDateFirstLine, int upToDateLastLine)
+ throws FilesTooBigForDiffException {
+ List<String> lines = new DocumentWrapper(myDocument).getLines(firstChangedLine, lastChangedLine);
+ List<String> uLines = new DocumentWrapper(myUpToDateDocument).getLines(upToDateFirstLine, upToDateLastLine);
+ return new RangesBuilder(lines, uLines, firstChangedLine, upToDateFirstLine).getRanges();
}
- private void replaceRanges(List<Range> rangesInChange, List<Range> newRangesInChange) {
+ private void replaceRanges(@NotNull List<Range> rangesInChange, @NotNull List<Range> newRangesInChange) {
for (Range range : rangesInChange) {
- range.getHighlighter().dispose();
+ if (range.getHighlighter() != null) {
+ range.getHighlighter().dispose();
+ }
range.setHighlighter(null);
}
for (Range range : newRangesInChange) {
@@ -460,25 +432,33 @@ public class LineStatusTracker {
}
}
- private void shiftRanges(List<Range> rangesAfterChange, int shift) {
+ private void shiftRanges(@NotNull List<Range> rangesAfterChange, int shift) {
for (final Range aRangesAfterChange : rangesAfterChange) {
aRangesAfterChange.shift(shift);
}
}
-
- }
-
- private List<Range> getChangedRanges(int from, int to) {
- return getChangedRanges(myRanges, from, to);
}
- public static List<Range> getChangedRanges(List<Range> ranges, int from, int to) {
- ArrayList<Range> result = new ArrayList<Range>();
+ public static void sortRanges(@NotNull List<Range> ranges,
+ int firstChangedLine,
+ int lastChangedLine,
+ @NotNull List<Range> rangesBeforeChange,
+ @NotNull List<Range> changedRanges,
+ @NotNull List<Range> rangesAfterChange) {
for (Range range : ranges) {
- if (range.getOffset1() <= to && range.getOffset2() >= from) result.add(range);
-// if (range.getOffset1() > to) break;
+ int offset1 = range.getOffset1() - 1;
+ int offset2 = range.getOffset2();
+
+ if (offset2 < firstChangedLine) {
+ rangesBeforeChange.add(range);
+ }
+ else if (offset1 > lastChangedLine) {
+ rangesAfterChange.add(range);
+ }
+ else {
+ changedRanges.add(range);
+ }
}
- return result;
}
@Nullable
@@ -525,7 +505,7 @@ public class LineStatusTracker {
return getPrevRange(currentRange);
}
- for (ListIterator<Range> iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious();) {
+ for (ListIterator<Range> iterator = myRanges.listIterator(myRanges.size()); iterator.hasPrevious(); ) {
final Range range = iterator.previous();
if (range.getOffset1() > line) {
continue;
@@ -536,24 +516,6 @@ public class LineStatusTracker {
}
}
- public static List<Range> getRangesBefore(List<Range> ranges, int line) {
- ArrayList<Range> result = new ArrayList<Range>();
-
- for (Range range : ranges) {
- if (range.getOffset2() < line) result.add(range);
- //if (range.getOffset2() > line) break;
- }
- return result;
- }
-
- public static List<Range> getRangesAfter(List<Range> ranges, int line) {
- ArrayList<Range> result = new ArrayList<Range>();
- for (Range range : ranges) {
- if (range.getOffset1() > line) result.add(range);
- }
- return result;
- }
-
@Nullable
public Range getRangeForLine(final int line) {
synchronized (myLock) {
@@ -573,25 +535,33 @@ public class LineStatusTracker {
myApplication.assertWriteAccessAllowed();
synchronized (myLock) {
- TextRange currentTextRange = getCurrentTextRange(range);
+ TextRange currentTextRange = getCurrentTextRangeWithMagic(range);
+ int offset1 = currentTextRange.getStartOffset();
+ int offset2 = Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength());
if (range.getType() == Range.INSERTED) {
- myDocument
- .replaceString(currentTextRange.getStartOffset(), Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()), "");
+ myDocument.replaceString(offset1, offset2, "");
}
else if (range.getType() == Range.DELETED) {
- String upToDateContent = getUpToDateContent(range);
- myDocument.insertString(currentTextRange.getStartOffset(), upToDateContent);
+ String upToDateContent = getUpToDateContentWithMagic(range);
+ myDocument.insertString(offset1, upToDateContent);
}
else {
-
- String upToDateContent = getUpToDateContent(range);
- myDocument.replaceString(currentTextRange.getStartOffset(), Math.min(currentTextRange.getEndOffset() + 1, myDocument.getTextLength()),
- upToDateContent);
+ String upToDateContent = getUpToDateContentWithMagic(range);
+ myDocument.replaceString(offset1, offset2, upToDateContent);
}
}
}
+ public String getUpToDateContentWithMagic(Range range) {
+ synchronized (myLock) {
+ TextRange textRange = getUpToDateRangeWithMagic(range);
+ final int startOffset = textRange.getStartOffset();
+ final int endOffset = Math.min(textRange.getEndOffset() + 1, myUpToDateDocument.getTextLength());
+ return myUpToDateDocument.getCharsSequence().subSequence(startOffset, endOffset).toString();
+ }
+ }
+
public String getUpToDateContent(Range range) {
synchronized (myLock) {
TextRange textRange = getUpToDateRange(range);
@@ -605,25 +575,28 @@ public class LineStatusTracker {
return myProject;
}
- TextRange getCurrentTextRange(Range range) {
- return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument, false);
+ @NotNull
+ TextRange getCurrentTextRangeWithMagic(@NotNull Range range) {
+ return getRangeWithMagic(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument);
}
- TextRange getUpToDateRange(Range range) {
- return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument, false);
+ @NotNull
+ TextRange getUpToDateRangeWithMagic(@NotNull Range range) {
+ return getRangeWithMagic(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument);
}
- TextRange getCurrentTextRangeWithEndSymbol(Range range) {
- return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument, true);
+ @NotNull
+ TextRange getCurrentTextRange(@NotNull Range range) {
+ return getRange(range.getType(), range.getOffset1(), range.getOffset2(), Range.DELETED, myDocument);
}
- // a hack
- TextRange getUpToDateRangeWithEndSymbol(Range range) {
- return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument, true);
+ @NotNull
+ TextRange getUpToDateRange(@NotNull Range range) {
+ return getRange(range.getType(), range.getUOffset1(), range.getUOffset2(), Range.INSERTED, myUpToDateDocument);
}
- private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document,
- final boolean keepEnd) {
+ @NotNull
+ private static TextRange getRangeWithMagic(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) {
if (rangeType == emptyRangeCondition) {
int lineStartOffset;
if (offset1 == 0) {
@@ -634,23 +607,33 @@ public class LineStatusTracker {
}
//if (lineStartOffset > 0) lineStartOffset--;
return new TextRange(lineStartOffset, lineStartOffset);
-
}
else {
int startOffset = document.getLineStartOffset(offset1);
int endOffset = document.getLineEndOffset(offset2 - 1);
if (startOffset > 0) {
- -- startOffset;
- if (! keepEnd) {
- -- endOffset;
- }
+ --startOffset;
+ --endOffset;
}
return new TextRange(startOffset, endOffset);
}
}
- public static LineStatusTracker createOn(@Nullable VirtualFile virtualFile, final Document doc, final Project project) {
- final Document document = new DocumentImpl("",true);
+ @NotNull
+ private static TextRange getRange(byte rangeType, int offset1, int offset2, byte emptyRangeCondition, Document document) {
+ if (rangeType == emptyRangeCondition) {
+ int lineStartOffset = offset1 < document.getLineCount() ? document.getLineStartOffset(offset1) : document.getTextLength();
+ return new TextRange(lineStartOffset, lineStartOffset);
+ }
+ else {
+ int startOffset = document.getLineStartOffset(offset1);
+ int endOffset = document.getLineEndOffset(offset2 - 1);
+ return new TextRange(startOffset, endOffset);
+ }
+ }
+
+ public static LineStatusTracker createOn(@Nullable VirtualFile virtualFile, @NotNull final Document doc, final Project project) {
+ final Document document = new DocumentImpl("", true);
return new LineStatusTracker(doc, document, project, virtualFile);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
index 6900d46c9f10..5727c62f4d14 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java
@@ -31,6 +31,10 @@ public class Range {
public static final byte INSERTED = 2;
public static final byte DELETED = 3;
+ // offset1/offset2 - line numbers
+ // (2,3) - modified 2nd line
+ // (2,2) - empty range between 1 and 2 lines
+ // index of first line is 0
private int myOffset1;
private int myOffset2;
private final int myUpToDateOffset1;
@@ -154,22 +158,4 @@ public class Range {
public RangeHighlighter getHighlighter() {
return myRangeHighlighter;
}
-
- public boolean contains(int offset1, int offset2) {
- return getOffset1() <= offset1 && getOffset2() >= offset2;
- }
-
- public boolean containsLine(int line) {
- if (myType == DELETED) return (myOffset1 - 1) <= line
- && (myOffset2) >= line;
- return myOffset1 <= line && myOffset2 >= line;
- }
-
- public boolean isAfter(int line) {
- if (myType == DELETED)
- return (getOffset1() - 1) > line;
- else
- return getOffset1() > line;
- }
-
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
index e17f868ffad4..74f9e43d08ad 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.util.ArrayUtil;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
+import org.jetbrains.annotations.NotNull;
import java.util.LinkedList;
import java.util.List;
@@ -30,22 +31,20 @@ import java.util.List;
public class RangesBuilder {
private List<Range> myRanges;
- public RangesBuilder(Document current, Document upToDate) throws FilesTooBigForDiffException {
+ public RangesBuilder(@NotNull Document current, @NotNull Document upToDate) throws FilesTooBigForDiffException {
this(new DocumentWrapper(current).getLines(), new DocumentWrapper(upToDate).getLines(), 0, 0);
}
- public RangesBuilder(List<String> current, List<String> upToDate, int shift, int uShift) throws FilesTooBigForDiffException {
+ public RangesBuilder(@NotNull List<String> current, @NotNull List<String> upToDate, int shift, int uShift) throws FilesTooBigForDiffException {
myRanges = new LinkedList<Range>();
Diff.Change ch = Diff.buildChanges(ArrayUtil.toStringArray(upToDate), ArrayUtil.toStringArray(current));
-
while (ch != null) {
Range range = Range.createOn(ch, shift, uShift);
myRanges.add(range);
ch = ch.link;
}
-
}
public List<Range> getRanges() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
index 50622b27d0ce..c5dba0cab29c 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/ShowLineStatusRangeDiffAction.java
@@ -56,10 +56,10 @@ public class ShowLineStatusRangeDiffAction extends BaseLineStatusRangeAction {
public DiffContent[] getContents() {
return new DiffContent[]{
createDiffContent(myLineStatusTracker.getUpToDateDocument(),
- myLineStatusTracker.getUpToDateRangeWithEndSymbol(myRange),
+ myLineStatusTracker.getUpToDateRange(myRange),
null),
createDiffContent(myLineStatusTracker.getDocument(),
- myLineStatusTracker.getCurrentTextRangeWithEndSymbol(myRange),
+ myLineStatusTracker.getCurrentTextRange(myRange),
myLineStatusTracker.getVirtualFile())};
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
index f8daa55b0e8f..a1fa2baeb1d2 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java
@@ -794,18 +794,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
result.add(new RefreshFileHistoryAction());
if (! myIsStaticAndEmbedded) {
- result.add(new ToggleAction("Show Details", "Display details panel", AllIcons.Actions.Preview) {
- @Override
- public boolean isSelected(AnActionEvent e) {
- return getConfiguration().SHOW_FILE_HISTORY_DETAILS;
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- getConfiguration().SHOW_FILE_HISTORY_DETAILS = state;
- setupDetails();
- }
- });
+ result.add(new MyToggleAction());
}
if (!popup && supportsTree()) {
@@ -1119,7 +1108,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
- private class MyAnnotateAction extends AnAction {
+ private class MyAnnotateAction extends AnAction implements DumbAware {
public MyAnnotateAction() {
super(VcsBundle.message("annotate.action.name"), VcsBundle.message("annotate.action.description"),
AllIcons.Actions.Annotate);
@@ -1825,4 +1814,21 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}
}
+ private class MyToggleAction extends ToggleAction implements DumbAware {
+
+ public MyToggleAction() {
+ super("Show Details", "Display details panel", AllIcons.Actions.Preview);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return getConfiguration().SHOW_FILE_HISTORY_DETAILS;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ getConfiguration().SHOW_FILE_HISTORY_DETAILS = state;
+ setupDetails();
+ }
+ }
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
index 7eda8accaa93..8be62f10953d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsEP.java
@@ -25,6 +25,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsActiveEnvironmentsProxy;
import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -47,29 +49,43 @@ public class VcsEP extends AbstractExtensionPointBean {
public boolean crawlUpToCheckUnderVcs;
private AbstractVcs myVcs;
+ private final Object LOCK = new Object();
- public AbstractVcs getVcs(Project project) {
- if (myVcs == null) {
- try {
- final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
- final Class<?>[] interfaces = foundClass.getInterfaces();
- for (Class<?> anInterface : interfaces) {
- if (BaseComponent.class.isAssignableFrom(anInterface)) {
- myVcs = PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
- myVcs = VcsActiveEnvironmentsProxy.proxyVcs(myVcs);
- return myVcs;
- }
- }
- myVcs = VcsActiveEnvironmentsProxy.proxyVcs((AbstractVcs)instantiate(vcsClass, project.getPicoContainer()));
+ @Nullable
+ public AbstractVcs getVcs(@NotNull Project project) {
+ synchronized (LOCK) {
+ if (myVcs != null) {
+ return myVcs;
+ }
+ }
+ AbstractVcs vcs = getInstance(project, vcsClass);
+ synchronized (LOCK) {
+ if (myVcs == null) {
+ myVcs = VcsActiveEnvironmentsProxy.proxyVcs(vcs);
}
- catch(Exception e) {
- LOG.error(e);
- return null;
+ return myVcs;
+ }
+ }
+
+ @Nullable
+ private AbstractVcs getInstance(@NotNull Project project, @NotNull String vcsClass) {
+ try {
+ final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
+ final Class<?>[] interfaces = foundClass.getInterfaces();
+ for (Class<?> anInterface : interfaces) {
+ if (BaseComponent.class.isAssignableFrom(anInterface)) {
+ return PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
+ }
}
+ return instantiate(vcsClass, project.getPicoContainer());
+ }
+ catch(Exception e) {
+ LOG.error(e);
+ return null;
}
- return myVcs;
}
+ @NotNull
public VcsDescriptor createDescriptor() {
return new VcsDescriptor(administrativeAreaName, displayName, name, crawlUpToCheckUnderVcs);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
index f357321d9a00..0a47656491df 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/AllVcses.java
@@ -91,14 +91,23 @@ public class AllVcses implements AllVcsesI, Disposable {
if (vcs != null) {
return vcs;
}
- final VcsEP ep = myExtensions.get(name);
- if (ep != null) {
- final AbstractVcs vcs1 = ep.getVcs(myProject);
- LOG.assertTrue(vcs1 != null, name);
+ }
+
+ // unmodifiable map => no sync needed
+ final VcsEP ep = myExtensions.get(name);
+ if (ep == null) {
+ return null;
+ }
+
+ // VcsEP guarantees to always return the same vcs value
+ final AbstractVcs vcs1 = ep.getVcs(myProject);
+ LOG.assertTrue(vcs1 != null, name);
+
+ synchronized (myLock) {
+ if (!myVcses.containsKey(name)) {
addVcs(vcs1);
- return vcs1;
}
- return null;
+ return vcs1;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java b/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
index e61b229302f1..d3ed9a84de2c 100644
--- a/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
+++ b/platform/vcs-impl/src/com/intellij/vcsUtil/AuthDialog.java
@@ -35,16 +35,17 @@ public class AuthDialog extends DialogWrapper {
public AuthDialog(@NotNull Project project, @NotNull String title, @Nullable String description, @Nullable String login, @Nullable String password, boolean rememberByDefault) {
super(project, false);
setTitle(title);
- boolean rememberPassword = decideOnShowRememberPasswordOption(password, rememberByDefault);
+ Boolean rememberPassword = decideOnShowRememberPasswordOption(password, rememberByDefault);
authPanel = new AuthenticationPanel(description, login, password, rememberPassword);
init();
}
- private static boolean decideOnShowRememberPasswordOption(@Nullable String password, boolean rememberByDefault) {
+ @Nullable
+ private static Boolean decideOnShowRememberPasswordOption(@Nullable String password, boolean rememberByDefault) {
final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
// if password saving is disabled, don't show the checkbox.
if (passwordSafe.getSettings().getProviderType().equals(PasswordSafeSettings.ProviderType.DO_NOT_STORE)) {
- return false;
+ return null;
}
// if password is prefilled, it is expected to continue remembering it.
if (!StringUtil.isEmptyOrSpaces(password)) {
diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java
index 63f54a8c15b5..c7da2ad49a04 100644
--- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java
+++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/VcsTestUtil.java
@@ -19,7 +19,6 @@ import com.intellij.notification.Notification;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
@@ -39,26 +38,18 @@ import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.*;
public class VcsTestUtil {
-
public static VirtualFile createFile(@NotNull Project project, @NotNull final VirtualFile parent, @NotNull final String name,
@Nullable final String content) {
- final Ref<VirtualFile> result = new Ref<VirtualFile>();
- new WriteCommandAction.Simple(project) {
+ return new WriteCommandAction<VirtualFile>(project) {
@Override
- protected void run() throws Throwable {
- try {
- VirtualFile file = parent.createChildData(this, name);
- if (content != null) {
- file.setBinaryContent(CharsetToolkit.getUtf8Bytes(content));
- }
- result.set(file);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
+ protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
+ VirtualFile file = parent.createChildData(this, name);
+ if (content != null) {
+ file.setBinaryContent(CharsetToolkit.getUtf8Bytes(content));
}
+ result.setResult(file);
}
- }.execute();
- return result.get();
+ }.execute().throwException().getResultObject();
}
/**
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUserRegistry.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUserRegistry.java
new file mode 100644
index 000000000000..90971a4f172e
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsUserRegistry.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ *
+ */
+public interface VcsUserRegistry {
+
+ @NotNull
+ Set<VcsUser> getUsers();
+
+}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java
index 4650cd1a1146..d2a3ecff0801 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/bek/BekSorter.java
@@ -29,6 +29,9 @@ import java.util.List;
public class BekSorter {
public static boolean isBekEnabled() { // todo drop later
+ if (Registry.is("vcs.log.bek.sort.disabled")) {
+ return false;
+ }
boolean isInternal = Boolean.valueOf(System.getProperty("idea.is.internal"));
boolean isBekEnabled = Registry.is("vcs.log.bek.sort");
return isBekEnabled || isInternal;
diff --git a/platform/vcs-log/impl/src/META-INF/vcs-log.xml b/platform/vcs-log/impl/src/META-INF/vcs-log.xml
index 5e014d560553..9a3c9da03cb0 100644
--- a/platform/vcs-log/impl/src/META-INF/vcs-log.xml
+++ b/platform/vcs-log/impl/src/META-INF/vcs-log.xml
@@ -12,6 +12,7 @@
<projectService serviceInterface="com.intellij.vcs.log.impl.VcsLogManager" serviceImplementation="com.intellij.vcs.log.impl.VcsLogManager"/>
<projectService serviceInterface="com.intellij.vcs.log.VcsLogSettings" serviceImplementation="com.intellij.vcs.log.impl.VcsLogSettingsImpl"/>
<projectService serviceInterface="com.intellij.vcs.log.data.VcsLogUiProperties" serviceImplementation="com.intellij.vcs.log.data.VcsLogUiProperties"/>
+ <projectService serviceInterface="com.intellij.vcs.log.VcsUserRegistry" serviceImplementation="com.intellij.vcs.log.data.VcsUserRegistryImpl"/>
</extensions>
<actions>
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
index d682624c6863..91385926cd93 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
@@ -16,6 +16,7 @@
package com.intellij.vcs.log.data;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.BackgroundTaskQueue;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -75,7 +76,7 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
*/
@NotNull private final Map<Hash, VcsCommitMetadata> myTopCommitsDetailsCache = ContainerUtil.newConcurrentMap();
- private final VcsUserRegistry myUserRegistry;
+ private final VcsUserRegistryImpl myUserRegistry;
private final VcsLogHashMap myHashMap;
private final ContainingBranchesGetter myContainingBranchesGetter;
@@ -94,7 +95,7 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
myDetailsGetter = new CommitDetailsGetter(this, logProviders);
mySettings = settings;
myDataPackUpdateHandler = dataPackUpdateHandler;
- myUserRegistry = new VcsUserRegistry();
+ myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(project, VcsUserRegistry.class);
try {
myHashMap = new VcsLogHashMap(myProject);
@@ -325,7 +326,7 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
}
@NotNull
- public VcsUserRegistry getUserRegistry() {
+ public VcsUserRegistryImpl getUserRegistry() {
return myUserRegistry;
}
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java
index 4195be79579e..e67f8f91e22a 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogHashMap.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.util.CommonProcessors;
@@ -50,6 +51,7 @@ public class VcsLogHashMap implements Disposable {
VcsLogHashMap(@NotNull Project project) throws IOException {
final File myMapFile = new File(LOG_CACHE_APP_DIR, project.getName() + "." + project.getLocationHash());
+ Disposer.register(project, this);
myPersistentEnumerator = IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentEnumerator<Hash>, IOException>() {
@Override
public PersistentEnumerator<Hash> compute() throws IOException {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
index cdb9f80fe1a9..0c25d7f5709d 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
@@ -45,7 +45,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
@NotNull private final Project myProject;
@NotNull private final VcsLogHashMap myHashMap;
@NotNull private final Map<VirtualFile, VcsLogProvider> myProviders;
- @NotNull private final VcsUserRegistry myUserRegistry;
+ @NotNull private final VcsUserRegistryImpl myUserRegistry;
@NotNull private final Map<Hash, VcsCommitMetadata> myTopCommitsDetailsCache;
@NotNull private final Consumer<Exception> myExceptionHandler;
private final int myRecentCommitCount;
@@ -57,7 +57,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
public VcsLogRefresherImpl(@NotNull final Project project,
@NotNull VcsLogHashMap hashMap,
@NotNull Map<VirtualFile, VcsLogProvider> providers,
- @NotNull final VcsUserRegistry userRegistry,
+ @NotNull final VcsUserRegistryImpl userRegistry,
@NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache,
@NotNull final Consumer<DataPack> dataPackUpdateHandler,
@NotNull Consumer<Exception> exceptionHandler, int recentCommitsCount) {
@@ -154,7 +154,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
@NotNull
private static Map<VirtualFile, List<? extends TimedVcsCommit>> loadRecentCommitsFromVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers,
@NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
- @NotNull final VcsUserRegistry userRegistry,
+ @NotNull final VcsUserRegistryImpl userRegistry,
@NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache)
throws VcsException {
final StopWatch sw = StopWatch.start("loading commits");
@@ -168,6 +168,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
sw.rootCompleted(root);
}
}.iterate(providers);
+ userRegistry.flush();
sw.report();
return commits;
}
@@ -200,7 +201,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return map;
}
- private static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistry userRegistry,
+ private static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistryImpl userRegistry,
@NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache) {
for (VcsCommitMetadata detail : metadatas) {
userRegistry.addUser(detail.getAuthor());
@@ -400,6 +401,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
sw.rootCompleted(root);
}
}.iterate(myProviders);
+ myUserRegistry.flush();
sw.report();
return commits;
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistry.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistry.java
deleted file mode 100644
index b9088e7d6e29..000000000000
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistry.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.vcs.log.data;
-
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.Interner;
-import com.intellij.vcs.log.VcsUser;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- *
- */
-public class VcsUserRegistry {
-
- private final Interner<VcsUser> myUserMap = new Interner<VcsUser>();
- private final ReadWriteLock myLock = new ReentrantReadWriteLock();
-
- @NotNull
- public VcsUser addUser(@NotNull VcsUser user) {
- myLock.writeLock().lock();
- try {
- return myUserMap.intern(user);
- }
- finally {
- myLock.writeLock().unlock();
- }
-
- }
-
- @NotNull
- public Set<VcsUser> getUsers() {
- myLock.readLock().lock();
- try {
- return ContainerUtil.newHashSet(myUserMap.getValues());
- }
- finally {
- myLock.readLock().unlock();
- }
- }
-}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java
new file mode 100644
index 000000000000..a5447d20f115
--- /dev/null
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.data;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.io.*;
+import com.intellij.vcs.log.VcsUser;
+import com.intellij.vcs.log.VcsUserRegistry;
+import com.intellij.vcs.log.impl.VcsUserImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ *
+ */
+public class VcsUserRegistryImpl implements Disposable, VcsUserRegistry {
+
+ private static final File USER_CACHE_APP_DIR = new File(PathManager.getSystemPath(), "vcs-users");
+ private static final Logger LOG = Logger.getInstance(VcsUserRegistryImpl.class);
+ private static final PersistentEnumeratorBase.DataFilter ACCEPT_ALL_DATA_FILTER = new PersistentEnumeratorBase.DataFilter() {
+ @Override
+ public boolean accept(int id) {
+ return true;
+ }
+ };
+
+ @Nullable private final PersistentEnumerator<VcsUser> myPersistentEnumerator;
+
+ VcsUserRegistryImpl(@NotNull Project project) {
+ final File mapFile = new File(USER_CACHE_APP_DIR, project.getName() + "." + project.getLocationHash());
+ Disposer.register(project, this);
+ myPersistentEnumerator = initEnumerator(mapFile);
+ }
+
+ @Nullable
+ private static PersistentEnumerator<VcsUser> initEnumerator(@NotNull final File mapFile) {
+ try {
+ return IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentEnumerator<VcsUser>, IOException>() {
+ @Override
+ public PersistentEnumerator<VcsUser> compute() throws IOException {
+ return new PersistentEnumerator<VcsUser>(mapFile, new MyDescriptor(), Page.PAGE_SIZE);
+ }
+ }, mapFile);
+ }
+ catch (IOException e) {
+ LOG.warn(e);
+ return null;
+ }
+ }
+
+ public void addUser(@NotNull VcsUser user) {
+ try {
+ if (myPersistentEnumerator != null) {
+ myPersistentEnumerator.enumerate(user);
+ }
+ }
+ catch (IOException e) {
+ LOG.warn(e);
+ }
+ }
+
+ @Override
+ @NotNull
+ public Set<VcsUser> getUsers() {
+ try {
+ Collection<VcsUser> users = myPersistentEnumerator != null ?
+ myPersistentEnumerator.getAllDataObjects(ACCEPT_ALL_DATA_FILTER) :
+ Collections.<VcsUser>emptySet();
+ return ContainerUtil.newHashSet(users);
+ }
+ catch (IOException e) {
+ LOG.warn(e);
+ return Collections.emptySet();
+ }
+ }
+
+ public void flush() {
+ if (myPersistentEnumerator != null) {
+ myPersistentEnumerator.force();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ try {
+ if (myPersistentEnumerator != null) {
+ myPersistentEnumerator.close();
+ }
+ }
+ catch (IOException e) {
+ LOG.warn(e);
+ }
+ }
+
+ private static class MyDescriptor implements KeyDescriptor<VcsUser> {
+ @Override
+ public void save(@NotNull DataOutput out, VcsUser value) throws IOException {
+ IOUtil.writeUTF(out, value.getName());
+ IOUtil.writeUTF(out, value.getEmail());
+ }
+
+ @Override
+ public VcsUser read(@NotNull DataInput in) throws IOException {
+ String name = IOUtil.readUTF(in);
+ String email = IOUtil.readUTF(in);
+ return new VcsUserImpl(name, email);
+ }
+
+ @Override
+ public int getHashCode(VcsUser value) {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean isEqual(VcsUser val1, VcsUser val2) {
+ return val1.equals(val2);
+ }
+ }
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
index 3c295b8c4337..77401fdb32f5 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogManager.java
@@ -25,10 +25,7 @@ import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsLogProvider;
import com.intellij.vcs.log.VcsLogRefresher;
import com.intellij.vcs.log.VcsLogSettings;
-import com.intellij.vcs.log.data.DataPack;
-import com.intellij.vcs.log.data.EmptyDataPack;
-import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
+import com.intellij.vcs.log.data.*;
import com.intellij.vcs.log.ui.VcsLogColorManagerImpl;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import com.intellij.vcs.log.ui.frame.VcsLogGraphTable;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
index 5d4685aba489..d18c99c4e24c 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
@@ -35,7 +35,9 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
/**
*/
@@ -89,11 +91,17 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi {
* Returns filter components which will be added to the Log toolbar.
*/
@NotNull
- public ActionGroup getFilterActionComponents() {
+ public ActionGroup getActionGroup() {
return myActionGroup;
}
@NotNull
+ public List<JComponent> getComponents() {
+ return Arrays.<JComponent>asList(myTextFilter.getTextEditor(), myBranchFilterComponent, myUserFilterComponent,
+ myDateFilterComponent, myStructureFilterComponent);
+ }
+
+ @NotNull
@Override
public VcsLogFilterCollection getFilters() {
VcsLogTextFilter textFilter = !myTextFilter.getText().isEmpty() ? new VcsLogTextFilterImpl(myTextFilter.getText().trim()) : null;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
index b551b887c921..6765c7c394c7 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
@@ -16,6 +16,8 @@ import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLoadingPanel;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.table.ComponentsListFocusTraversalPolicy;
import com.intellij.vcs.log.VcsLog;
import com.intellij.vcs.log.VcsLogDataKeys;
import com.intellij.vcs.log.VcsLogFilterUi;
@@ -35,6 +37,7 @@ import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -52,7 +55,8 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
@NotNull private final BranchesPanel myBranchesPanel;
@NotNull private final DetailsPanel myDetailsPanel;
@NotNull private final Splitter myDetailsSplitter;
- private final JComponent myToolbar;
+ @NotNull private final JComponent myToolbar;
+ @NotNull private final RepositoryChangesBrowser myChangesBrowser;
public MainFrame(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUiImpl vcsLogUI, @NotNull Project project,
@NotNull VcsLogSettings settings, @NotNull VcsLogUiProperties uiProperties, @NotNull VcsLog log,
@@ -71,14 +75,14 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
myBranchesPanel.setVisible(settings.isShowBranchesPanel());
myDetailsPanel = new DetailsPanel(logDataHolder, myGraphTable, vcsLogUI.getColorManager(), initialDataPack);
- final RepositoryChangesBrowser changesBrowser = new RepositoryChangesBrowser(project, null, Collections.<Change>emptyList(), null);
- changesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), getGraphTable());
- changesBrowser.getEditSourceAction().registerCustomShortcutSet(CommonShortcuts.getEditSource(), getGraphTable());
- setDefaultEmptyText(changesBrowser);
+ myChangesBrowser = new RepositoryChangesBrowser(project, null, Collections.<Change>emptyList(), null);
+ myChangesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), getGraphTable());
+ myChangesBrowser.getEditSourceAction().registerCustomShortcutSet(CommonShortcuts.getEditSource(), getGraphTable());
+ setDefaultEmptyText(myChangesBrowser);
myChangesLoadingPane = new JBLoadingPanel(new BorderLayout(), project);
- myChangesLoadingPane.add(changesBrowser);
+ myChangesLoadingPane.add(myChangesBrowser);
- final CommitSelectionListener selectionChangeListener = new CommitSelectionListener(changesBrowser);
+ final CommitSelectionListener selectionChangeListener = new CommitSelectionListener(myChangesBrowser);
myGraphTable.getSelectionModel().addListSelectionListener(selectionChangeListener);
myGraphTable.getSelectionModel().addListSelectionListener(myDetailsPanel);
updateWhenDetailsAreLoaded(selectionChangeListener);
@@ -110,6 +114,9 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
changesBrowserSplitter.dispose();
}
});
+ myGraphTable.resetDefaultFocusTraversalKeys();
+ setFocusTraversalPolicyProvider(true);
+ setFocusTraversalPolicy(new MyFocusPolicy());
}
/**
@@ -202,7 +209,7 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
toolbarGroup.add(ActionManager.getInstance().getAction(VcsLogUiImpl.TOOLBAR_ACTION_GROUP));
DefaultActionGroup mainGroup = new DefaultActionGroup();
- mainGroup.add(myFilterUi.getFilterActionComponents());
+ mainGroup.add(myFilterUi.getActionGroup());
mainGroup.addSeparator();
mainGroup.add(toolbarGroup);
ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, mainGroup, true);
@@ -355,4 +362,14 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
e.getPresentation().setEnabled(areGraphActionsEnabled());
}
}
+
+ private class MyFocusPolicy extends ComponentsListFocusTraversalPolicy {
+ @NotNull
+ @Override
+ protected List<Component> getOrderedComponents() {
+ return ContainerUtil.concat(Arrays.<Component>asList(myGraphTable, myChangesBrowser.getPreferredFocusedComponent()),
+ myFilterUi.getComponents());
+ }
+ }
+
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
index 240fc672be53..11e9c843fc60 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
@@ -95,7 +95,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
addMouseListener(mouseAdapter);
PopupHandler.installPopupHandler(this, VcsLogUiImpl.POPUP_ACTION_GROUP, VcsLogUiImpl.VCS_LOG_TABLE_PLACE);
- TableScrollingUtil.installActions(this);
+ TableScrollingUtil.installActions(this, false);
}
@Override
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java
index 84000c188da5..08a30664f7dc 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +22,7 @@ import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.project.Project;
+import com.intellij.util.messages.Topic;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,6 +34,8 @@ import java.util.List;
* @author nik
*/
public abstract class XDebuggerManager {
+ public static final Topic<XDebuggerManagerListener> TOPIC =
+ new Topic<XDebuggerManagerListener>("XDebuggerManager events", XDebuggerManagerListener.class);
public static XDebuggerManager getInstance(@NotNull Project project) {
return project.getComponent(XDebuggerManager.class);
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManagerListener.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManagerListener.java
new file mode 100644
index 000000000000..c12dff0a5475
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerManagerListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface XDebuggerManagerListener {
+ void processStarted(@NotNull XDebugProcess debugProcess);
+
+ void processStopped(@NotNull XDebugProcess debugProcess);
+} \ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XSuspendContext.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XSuspendContext.java
index 4406ea69276a..3bab97ebe14f 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XSuspendContext.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XSuspendContext.java
@@ -15,8 +15,12 @@
*/
package com.intellij.xdebugger.frame;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Represents a suspended state of a debug process
*
@@ -38,4 +42,11 @@ public abstract class XSuspendContext {
return executionStack != null ? new XExecutionStack[]{executionStack} : XExecutionStack.EMPTY_ARRAY;
}
+ public void computeExecutionStacks(XExecutionStackContainer container) {
+ container.addExecutionStack(Arrays.asList(getExecutionStacks()), true);
+ }
+
+ public interface XExecutionStackContainer extends XValueCallback {
+ void addExecutionStack(@NotNull List<? extends XExecutionStack> executionStacks, final boolean last);
+ }
}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/presentation/XValuePresentation.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/presentation/XValuePresentation.java
index 5467033f4e32..8269585f08fc 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/presentation/XValuePresentation.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/presentation/XValuePresentation.java
@@ -91,5 +91,10 @@ public abstract class XValuePresentation {
* Appends {@code symbol} which is not part of the value
*/
void renderSpecialSymbol(@NotNull String symbol);
+
+ /**
+ * Appends red colored {@code error}
+ */
+ void renderError(@NotNull String error);
}
} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 95931e561f58..bdedcc29091a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -16,6 +16,7 @@
package com.intellij.xdebugger.impl;
import com.intellij.execution.ExecutionManager;
+import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.filters.HyperlinkInfo;
@@ -41,9 +42,11 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
@@ -365,7 +368,12 @@ public class XDebugSessionImpl implements XDebugSession {
private <B extends XBreakpoint<?>> void processBreakpoints(final XBreakpointHandler<B> handler,
boolean register,
final boolean temporary) {
- Collection<? extends B> breakpoints = myDebuggerManager.getBreakpointManager().getBreakpoints(handler.getBreakpointTypeClass());
+ Collection<? extends B> breakpoints = ApplicationManager.getApplication().runReadAction(new Computable<Collection<? extends B>>() {
+ @Override
+ public Collection<? extends B> compute() {
+ return myDebuggerManager.getBreakpointManager().getBreakpoints(handler.getBreakpointTypeClass());
+ }
+ });
for (B b : breakpoints) {
handleBreakpoint(handler, b, register, temporary);
}
@@ -650,49 +658,69 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public boolean breakpointReached(@NotNull final XBreakpoint<?> breakpoint, @Nullable String evaluatedLogExpression,
@NotNull XSuspendContext suspendContext) {
- XDebuggerEvaluator evaluator = XDebuggerUtilImpl.getEvaluator(suspendContext);
- String condition = breakpoint.getCondition();
- if (condition != null && evaluator != null) {
- LOG.debug("evaluating condition: " + condition);
- boolean result = evaluator.evaluateCondition(condition);
- LOG.debug("condition evaluates to " + result);
- if (!result) {
- return false;
+ return breakpointReached(breakpoint, evaluatedLogExpression, suspendContext, true);
+ }
+
+ public void breakpointReachedNoProcessing(@NotNull final XBreakpoint<?> breakpoint, @NotNull XSuspendContext suspendContext) {
+ breakpointReached(breakpoint, null, suspendContext, false);
+ }
+
+ private boolean breakpointReached(@NotNull final XBreakpoint<?> breakpoint, @Nullable String evaluatedLogExpression,
+ @NotNull XSuspendContext suspendContext, boolean doProcessing) {
+ if (doProcessing) {
+ XDebuggerEvaluator evaluator = XDebuggerUtilImpl.getEvaluator(suspendContext);
+ String condition = breakpoint.getCondition();
+ if (condition != null && evaluator != null) {
+ LOG.debug("evaluating condition: " + condition);
+ boolean result = evaluator.evaluateCondition(condition);
+ LOG.debug("condition evaluates to " + result);
+ if (!result) {
+ return false;
+ }
}
- }
- if (breakpoint.isLogMessage()) {
- String text = StringUtil.decapitalize(XBreakpointUtil.getDisplayText(breakpoint));
- final XSourcePosition position = breakpoint.getSourcePosition();
- final OpenFileHyperlinkInfo hyperlinkInfo =
- position != null ? new OpenFileHyperlinkInfo(myProject, position.getFile(), position.getLine()) : null;
- printMessage(XDebuggerBundle.message("xbreakpoint.reached.text") + " ", text, hyperlinkInfo);
- }
+ if (breakpoint.isLogMessage()) {
+ String text = StringUtil.decapitalize(XBreakpointUtil.getDisplayText(breakpoint));
+ final XSourcePosition position = breakpoint.getSourcePosition();
+ final OpenFileHyperlinkInfo hyperlinkInfo =
+ position != null ? new OpenFileHyperlinkInfo(myProject, position.getFile(), position.getLine()) : null;
+ printMessage(XDebuggerBundle.message("xbreakpoint.reached.text") + " ", text, hyperlinkInfo);
+ }
- if (evaluatedLogExpression != null) {
- printMessage(evaluatedLogExpression, null, null);
- }
- else {
- String expression = breakpoint.getLogExpression();
- if (expression != null && evaluator != null) {
- LOG.debug("evaluating log expression: " + expression);
- final String message = evaluator.evaluateMessage(expression);
- if (message != null) {
- printMessage(message, null, null);
+ if (evaluatedLogExpression != null) {
+ printMessage(evaluatedLogExpression, null, null);
+ }
+ else {
+ String expression = breakpoint.getLogExpression();
+ if (expression != null && evaluator != null) {
+ LOG.debug("evaluating log expression: " + expression);
+ final String message = evaluator.evaluateMessage(expression);
+ if (message != null) {
+ printMessage(message, null, null);
+ }
}
}
- }
- processDependencies(breakpoint);
+ processDependencies(breakpoint);
- if (breakpoint.getSuspendPolicy() == SuspendPolicy.NONE) {
- return false;
+ if (breakpoint.getSuspendPolicy() == SuspendPolicy.NONE) {
+ return false;
+ }
}
myActiveNonLineBreakpoint = !(breakpoint instanceof XLineBreakpoint<?>) ? breakpoint : null;
positionReached(suspendContext);
- if (breakpoint instanceof XLineBreakpoint<?> && ((XLineBreakpoint)breakpoint).isTemporary()) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ mySessionTab.toFront();
+ mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
+ }
+ });
+
+
+ if (doProcessing && breakpoint instanceof XLineBreakpoint<?> && ((XLineBreakpoint)breakpoint).isTemporary()) {
handleTemporaryBreakpointHit(breakpoint);
}
return true;
@@ -717,7 +745,7 @@ public class XDebugSessionImpl implements XDebugSession {
});
}
- private void processDependencies(final XBreakpoint<?> breakpoint) {
+ public void processDependencies(final XBreakpoint<?> breakpoint) {
XDependentBreakpointManager dependentBreakpointManager = myDebuggerManager.getBreakpointManager().getDependentBreakpointManager();
if (!dependentBreakpointManager.isMasterOrSlave(breakpoint)) return;
@@ -773,8 +801,6 @@ public class XDebugSessionImpl implements XDebugSession {
initSessionTab();
showSessionTab();
}
- mySessionTab.toFront();
- mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
if (myCurrentPosition != null) {
adjustMouseTrackingCounter(myCurrentPosition, 1);
}
@@ -786,7 +812,7 @@ public class XDebugSessionImpl implements XDebugSession {
private void adjustMouseTrackingCounter(@NotNull XSourcePosition position, int increment) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
- Editor editor = XDebuggerUtilImpl.createEditor(XSourcePositionImpl.createOpenFileDescriptor(myProject, position));
+ Editor editor = XDebuggerUtilImpl.createEditor(new OpenFileDescriptor(myProject, position.getFile()));
if (editor != null) {
JComponent component = editor.getComponent();
Object o = component.getClientProperty(EditorImpl.IGNORE_MOUSE_TRACKING);
@@ -821,6 +847,7 @@ public class XDebugSessionImpl implements XDebugSession {
if (myStopped) return;
myDebugProcess.stop();
+ myProject.getMessageBus().syncPublisher(XDebuggerManager.TOPIC).processStopped(myDebugProcess);
myCurrentPosition = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
@@ -922,8 +949,22 @@ public class XDebugSessionImpl implements XDebugSession {
}
}
+ private String getWatchesKey() {
+ if (myEnvironment != null) {
+ RunProfile profile = myEnvironment.getRunProfile();
+ if (profile instanceof RunConfiguration) {
+ return ((RunConfiguration)profile).getType().getId();
+ }
+ }
+ return getSessionName();
+ }
+
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
mySessionData.setWatchExpressions(watchExpressions);
- myDebuggerManager.getWatchesManager().setWatches(getSessionName(), watchExpressions);
+ myDebuggerManager.getWatchesManager().setWatches(getWatchesKey(), watchExpressions);
+ }
+
+ XExpression[] getWatchExpressions() {
+ return myDebuggerManager.getWatchesManager().getWatches(getWatchesKey());
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java
index 69c1166eda5f..eee1f28ad451 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerManagerImpl.java
@@ -206,10 +206,11 @@ public class XDebuggerManagerImpl extends XDebuggerManager
private XDebugSessionImpl startSession(final RunContentDescriptor contentToReuse, final XDebugProcessStarter processStarter,
final XDebugSessionImpl session) throws ExecutionException {
XDebugProcess process = processStarter.start(session);
+ myProject.getMessageBus().syncPublisher(TOPIC).processStarted(process);
XDebugSessionData oldSessionData = contentToReuse != null ? mySessionData.get(contentToReuse) : null;
if (oldSessionData == null) {
- oldSessionData = new XDebugSessionData(myWatchesManager.getWatches(session.getSessionName()));
+ oldSessionData = new XDebugSessionData(session.getWatchExpressions());
}
// Perform custom configuration of session data for XDebugProcessConfiguratorStarter classes
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/FocusOnBreakpointAction.java
index 91b223c613c9..8eb8d8ee99c3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/FocusOnBreakpointAction.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.debugger.ui.breakpoints.actions;
+package com.intellij.xdebugger.impl.actions;
import com.intellij.execution.ui.actions.AbstractFocusOnAction;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ToggleBreakpointEnabledAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ToggleBreakpointEnabledAction.java
new file mode 100644
index 000000000000..45f0df1645ad
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ToggleBreakpointEnabledAction.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.impl.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.Range;
+import com.intellij.util.containers.HashSet;
+import com.intellij.xdebugger.XDebuggerManager;
+import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
+import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
+import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
+import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointManager;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author egor
+ */
+public class ToggleBreakpointEnabledAction extends DumbAwareAction {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Collection<XLineBreakpoint> breakpoints = findLineBreakpoints(e);
+ for (XLineBreakpoint breakpoint : breakpoints) {
+ breakpoint.setEnabled(!breakpoint.isEnabled());
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(!findLineBreakpoints(e).isEmpty());
+ }
+
+ @NotNull
+ private static Set<XLineBreakpoint> findLineBreakpoints(AnActionEvent e) {
+ Project project = e.getProject();
+ Editor editor = e.getData(CommonDataKeys.EDITOR);
+ if (project == null || editor == null) return Collections.emptySet();
+ XBreakpointManagerImpl breakpointManager = (XBreakpointManagerImpl)XDebuggerManager.getInstance(project).getBreakpointManager();
+ XLineBreakpointManager lineBreakpointManager = breakpointManager.getLineBreakpointManager();
+ Document document = editor.getDocument();
+ Collection<Range<Integer>> lineRanges = new ArrayList<Range<Integer>>();
+ for (Caret caret : editor.getCaretModel().getAllCarets()) {
+ lineRanges.add(new Range<Integer>(document.getLineNumber(caret.getSelectionStart()), document.getLineNumber(caret.getSelectionEnd())));
+ }
+
+ Collection<XLineBreakpointImpl> breakpoints = lineBreakpointManager.getDocumentBreakpoints(document);
+ HashSet<XLineBreakpoint> res = new HashSet<XLineBreakpoint>();
+ for (XLineBreakpointImpl breakpoint : breakpoints) {
+ int line = breakpoint.getLine();
+ for (Range<Integer> range : lineRanges) {
+ if (range.isWithin(line)) {
+ res.add(breakpoint);
+ }
+ }
+ }
+ return res;
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java
index 7a00d6c156b7..557a1104acda 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java
@@ -68,4 +68,6 @@ public interface XDebuggerActions {
@NonNls String AUTO_TOOLTIP = "XDebugger.AutoTooltip";
@NonNls String MARK_OBJECT = "Debugger.MarkObject";
+
+ @NonNls String FOCUS_ON_BREAKPOINT = "Debugger.FocusOnBreakpoint";
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
index 9723c9ca68d6..6184ad9857b3 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
@@ -167,7 +167,10 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
}
public void setConditionEnabled(boolean conditionEnabled) {
- myConditionEnabled = conditionEnabled;
+ if (myConditionEnabled != conditionEnabled) {
+ myConditionEnabled = conditionEnabled;
+ fireBreakpointChanged();
+ }
}
public boolean isLogExpressionEnabled() {
@@ -175,7 +178,10 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
}
public void setLogExpressionEnabled(boolean logExpressionEnabled) {
- myLogExpressionEnabled = logExpressionEnabled;
+ if (myLogExpressionEnabled != logExpressionEnabled) {
+ myLogExpressionEnabled = logExpressionEnabled;
+ fireBreakpointChanged();
+ }
}
@Override
@@ -204,7 +210,7 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setLogExpressionObject(@Nullable XExpression expression) {
- if (!Comparing.equal(getLogExpressionObject(), expression)) {
+ if (!Comparing.equal(myLogExpression, expression)) {
myLogExpression = expression;
fireBreakpointChanged();
}
@@ -236,7 +242,7 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setConditionExpression(@Nullable XExpression condition) {
- if (!Comparing.equal(condition, getConditionExpression())) {
+ if (!Comparing.equal(condition, myCondition)) {
myCondition = condition;
fireBreakpointChanged();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionState.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionState.java
index 8fc46ba6477a..205cc2d9498d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionState.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionState.java
@@ -66,6 +66,7 @@ public class XExpressionState {
}
public XExpression toXExpression() {
+ checkConverted();
return new XExpressionImpl(myExpression, Language.findLanguageByID(myLanguage), myCustomInfo);
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
index f7465d74f15b..e2252ea642a9 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.breakpoints;
import com.intellij.execution.impl.ConsoleViewUtil;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -58,6 +59,7 @@ import org.jetbrains.annotations.NotNull;
import java.awt.event.MouseEvent;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -164,6 +166,15 @@ public class XLineBreakpointManager {
}
}
+ @NotNull
+ public Collection<XLineBreakpointImpl> getDocumentBreakpoints(Document document) {
+ Collection<XLineBreakpointImpl> breakpoints = myBreakpoints.getKeysByValue(document);
+ if (breakpoints == null) {
+ breakpoints = Collections.emptyList();
+ }
+ return breakpoints;
+ }
+
private void updateBreakpoints(@NotNull Document document) {
Collection<XLineBreakpointImpl> breakpoints = myBreakpoints.getKeysByValue(document);
if (breakpoints == null) {
@@ -250,7 +261,7 @@ public class XLineBreakpointManager {
private class MyEditorMouseListener extends EditorMouseAdapter {
@Override
- public void mouseClicked(EditorMouseEvent e) {
+ public void mouseClicked(final EditorMouseEvent e) {
final Editor editor = e.getEditor();
final MouseEvent mouseEvent = e.getMouseEvent();
if (mouseEvent.isPopupTrigger()
@@ -274,6 +285,8 @@ public class XLineBreakpointManager {
@Override
public void run() {
if (!myProject.isDisposed() && myProject.isInitialized() && file.isValid()) {
+ ActionManagerEx.getInstanceEx().fireBeforeActionPerformed("ToggleLineBreakpoint", e.getMouseEvent());
+
XLineBreakpoint breakpoint =
XBreakpointUtil.toggleLineBreakpoint(myProject, file, editor, line, mouseEvent.isAltDown(), false);
if (!mouseEvent.isAltDown() && mouseEvent.isShiftDown() && breakpoint != null) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XDebuggerTreeCreator.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XDebuggerTreeCreator.java
index 0be9cefb43ff..8f53dba017f9 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XDebuggerTreeCreator.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XDebuggerTreeCreator.java
@@ -26,9 +26,15 @@ import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.evaluate.quick.common.DebuggerTreeCreator;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeListener;
+import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
+
public class XDebuggerTreeCreator implements DebuggerTreeCreator<Pair<XValue,String>> {
@NotNull private final Project myProject;
private final XDebuggerEditorsProvider myProvider;
@@ -46,8 +52,25 @@ public class XDebuggerTreeCreator implements DebuggerTreeCreator<Pair<XValue,Str
@NotNull
@Override
public Tree createTree(@NotNull Pair<XValue, String> descriptor) {
- XDebuggerTree tree = new XDebuggerTree(myProject, myProvider, myPosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP, myMarkers);
- tree.setRoot(new XValueNodeImpl(tree, null, descriptor.getSecond(), descriptor.getFirst()), true);
+ final XDebuggerTree tree = new XDebuggerTree(myProject, myProvider, myPosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP, myMarkers);
+ final XValueNodeImpl root = new XValueNodeImpl(tree, null, descriptor.getSecond(), descriptor.getFirst());
+ tree.setRoot(root, true);
+ // expand root on load
+ tree.addTreeListener(new XDebuggerTreeListener() {
+ @Override
+ public void nodeLoaded(@NotNull RestorableStateNode node, String name) {
+ if (node == root && !node.isLeaf()) {
+ node.getChildCount();
+ }
+ }
+
+ @Override
+ public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, boolean last) {
+ if (node == root) {
+ tree.expandPath(node.getPath());
+ }
+ }
+ });
return tree;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java
index e7694a833789..5a956450952a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/AbstractValueHint.java
@@ -18,13 +18,23 @@ package com.intellij.xdebugger.impl.evaluate.quick.common;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.codeInsight.hint.HintUtil;
+import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.event.EditorMouseEvent;
-import com.intellij.openapi.editor.markup.*;
+import com.intellij.openapi.editor.markup.HighlighterLayer;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
-import com.intellij.ui.*;
+import com.intellij.ui.ClickListener;
+import com.intellij.ui.HintListener;
+import com.intellij.ui.LightweightHint;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.IconUtil;
import org.intellij.lang.annotations.JdkConstants;
@@ -41,14 +51,6 @@ import java.util.EventObject;
public abstract class AbstractValueHint {
private static final Logger LOG = Logger.getInstance(AbstractValueHint.class);
- private static final TextAttributes ourReferenceAttributes = new TextAttributes();
-
- static {
- ourReferenceAttributes.setForegroundColor(JBColor.BLUE);
- ourReferenceAttributes.setEffectColor(JBColor.BLUE);
- ourReferenceAttributes.setEffectType(EffectType.LINE_UNDERSCORE);
- }
-
private final KeyListener myEditorKeyListener = new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
@@ -139,8 +141,12 @@ public abstract class AbstractValueHint {
}
if (myType == ValueHintType.MOUSE_ALT_OVER_HINT) {
+ EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
+ TextAttributes attributes = scheme.getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR);
+ attributes = NavigationUtil.patchAttributesColor(attributes, myCurrentRange, myEditor);
+
myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(myCurrentRange.getStartOffset(), myCurrentRange.getEndOffset(),
- HighlighterLayer.SELECTION + 1, ourReferenceAttributes,
+ HighlighterLayer.SELECTION + 1, attributes,
HighlighterTargetArea.EXACT_RANGE);
Component internalComponent = myEditor.getContentComponent();
myStoredCursor = internalComponent.getCursor();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/ThreadComboBoxRenderer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/ThreadComboBoxRenderer.java
index 7e4849bc740e..c827bcd0d74f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/ThreadComboBoxRenderer.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/ThreadComboBoxRenderer.java
@@ -34,5 +34,8 @@ public class ThreadComboBoxRenderer extends ListCellRendererWrapper<XExecutionSt
setText(value.getDisplayName());
setIcon(value.getIcon());
}
+ else if (index >= 0) {
+ setText("Loading...");
+ }
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index b07bd62383f2..b7c5f4bf9746 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -16,13 +16,15 @@
package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.CommonActionsManager;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.CaptionPanel;
-import com.intellij.ui.PopupHandler;
-import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.*;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.containers.ContainerUtil;
@@ -38,6 +40,8 @@ import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.plaf.basic.ComboPopup;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
@@ -52,7 +56,7 @@ import java.util.List;
public class XFramesView implements XDebugView {
private final JPanel myMainPanel;
private final XDebuggerFramesList myFramesList;
- private final JComboBox myThreadComboBox;
+ private final ComboBox myThreadComboBox;
private final Set<XExecutionStack> myExecutionStacks = ContainerUtil.newHashSet();
@NotNull private final XDebugSession mySession;
private XExecutionStack mySelectedStack;
@@ -60,6 +64,7 @@ public class XFramesView implements XDebugView {
private final Map<XExecutionStack, StackFramesListBuilder> myBuilders = new HashMap<XExecutionStack, StackFramesListBuilder>();
private final ActionToolbarImpl myToolbar;
private final Wrapper myThreadsPanel;
+ private boolean myThreadsCalculated = false;
public XFramesView(@NotNull final XDebugSession session) {
mySession = session;
@@ -95,10 +100,49 @@ public class XFramesView implements XDebugView {
myMainPanel.add(ScrollPaneFactory.createScrollPane(myFramesList), BorderLayout.CENTER);
- myThreadComboBox = new JComboBox();
+ myThreadComboBox = new ComboBox();
//noinspection unchecked
myThreadComboBox.setRenderer(new ThreadComboBoxRenderer(myThreadComboBox));
myThreadComboBox.addItemListener(new MyItemListener());
+ myThreadComboBox.addPopupMenuListener(new PopupMenuListenerAdapter() {
+ @Override
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ XSuspendContext context = mySession.getSuspendContext();
+ if (context != null && !myThreadsCalculated) {
+ myThreadsCalculated = true;
+ myThreadComboBox.addItem(null); // rendered as "Loading..."
+ context.computeExecutionStacks(new XSuspendContext.XExecutionStackContainer() {
+ @Override
+ public void addExecutionStack(@NotNull final List<? extends XExecutionStack> executionStacks, boolean last) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ myThreadComboBox.removeItem(null);
+ addExecutionStacks(executionStacks);
+ ComboPopup popup = myThreadComboBox.getPopup();
+ if (popup != null && popup.isVisible()) {
+ popup.hide();
+ popup.show();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+
+ }
+ });
+ }
+ }
+ });
+ new ComboboxSpeedSearch(myThreadComboBox) {
+ @Override
+ protected String getElementText(Object element) {
+ return ((XExecutionStack)element).getDisplayName();
+ }
+ };
+
myToolbar = createToolbar();
myThreadsPanel = new Wrapper();
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, 1, 0);
@@ -156,6 +200,7 @@ public class XFramesView implements XDebugView {
if (suspendContext == null || event == SessionEvent.PAUSED) {
myThreadComboBox.removeAllItems();
myFramesList.clear();
+ myThreadsCalculated = false;
myExecutionStacks.clear();
if (suspendContext == null) {
return;
@@ -163,13 +208,8 @@ public class XFramesView implements XDebugView {
}
XExecutionStack[] executionStacks = suspendContext.getExecutionStacks();
- for (XExecutionStack executionStack : executionStacks) {
- if (!myExecutionStacks.contains(executionStack)) {
- //noinspection unchecked
- myThreadComboBox.addItem(executionStack);
- myExecutionStacks.add(executionStack);
- }
- }
+ addExecutionStacks(Arrays.asList(executionStacks));
+
XExecutionStack activeExecutionStack = suspendContext.getActiveExecutionStack();
myThreadComboBox.setSelectedItem(activeExecutionStack);
myThreadsPanel.removeAll();
@@ -183,6 +223,16 @@ public class XFramesView implements XDebugView {
myListenersEnabled = true;
}
+ private void addExecutionStacks(List<? extends XExecutionStack> executionStacks) {
+ for (XExecutionStack executionStack : executionStacks) {
+ if (!myExecutionStacks.contains(executionStack)) {
+ //noinspection unchecked
+ myThreadComboBox.addItem(executionStack);
+ myExecutionStacks.add(executionStack);
+ }
+ }
+ }
+
private void updateFrames(final XExecutionStack executionStack) {
if (mySelectedStack == executionStack) {
return;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
index 0cca39833e54..d9a1fdbcf0af 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java
@@ -19,6 +19,8 @@ import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.EditorColorsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.util.Computable;
@@ -261,6 +263,16 @@ public class DebuggerUIUtil {
return balloon;
}
+ @NotNull
+ public static EditorColorsScheme getColorScheme() {
+ return EditorColorsUtil.getGlobalOrDefaultColorScheme();
+ }
+
+ @NotNull
+ public static EditorColorsScheme getColorScheme(@Nullable JComponent component) {
+ return EditorColorsUtil.getColorSchemeForComponent(component);
+ }
+
private static class FullValueEvaluationCallbackImpl implements XFullValueEvaluator.XFullValueEvaluationCallback {
private final AtomicBoolean myObsolete = new AtomicBoolean(false);
private final EditorTextField myTextArea;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java
index 9fed59c966b0..0065a2843aac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/ExecutionPointHighlighter.java
@@ -65,6 +65,7 @@ public class ExecutionPointHighlighter {
mySourcePosition = position;
+ clearDescriptor();
myOpenFileDescriptor = XSourcePositionImpl.createOpenFileDescriptor(myProject, position);
//see IDEA-125645 and IDEA-63459
//myOpenFileDescriptor.setUseCurrentWindow(true);
@@ -84,13 +85,20 @@ public class ExecutionPointHighlighter {
updateRequested.set(false);
removeHighlighter();
- myOpenFileDescriptor = null;
+ clearDescriptor();
myEditor = null;
myGutterIconRenderer = null;
}
});
}
+ private void clearDescriptor() {
+ if (myOpenFileDescriptor != null) {
+ myOpenFileDescriptor.dispose();
+ myOpenFileDescriptor = null;
+ }
+ }
+
public void navigateTo() {
if (myOpenFileDescriptor != null) {
myOpenFileDescriptor.navigateInEditor(myProject, true);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java
index 16a5a2ed96f8..0b0145948ecd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java
@@ -46,6 +46,8 @@ public final class TextViewer extends EditorTextField {
editor.setEmbeddedIntoDialogWrapper(myEmbeddedIntoDialogWrapper);
editor.getComponent().setPreferredSize(null);
editor.getSettings().setUseSoftWraps(myUseSoftWraps);
+
+ editor.setColorsScheme(DebuggerUIUtil.getColorScheme());
return editor;
}
} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index ef0b72008cf7..2e5f8a337385 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -168,7 +168,8 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
}
DefaultActionGroup leftToolbar = new DefaultActionGroup();
- final Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();
+ final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance();
+ final Executor executor = environment != null ? environment.getExecutor() : debugExecutor;
if (runner != null && environment != null) {
RestartAction restartAction = new RestartAction(executor, runner, myRunContentDescriptor, environment);
leftToolbar.add(restartAction);
@@ -222,7 +223,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
leftToolbar.add(PinToolwindowTabAction.getPinAction());
leftToolbar.add(new CloseAction(executor, myRunContentDescriptor, getProject()));
- leftToolbar.add(new ContextHelpAction(executor.getHelpId()));
+ leftToolbar.add(new ContextHelpAction(debugExecutor.getHelpId()));
DefaultActionGroup topToolbar = new DefaultActionGroup();
topToolbar.addAll(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP));
@@ -237,6 +238,10 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
initLogConsoles(runConfiguration, myRunContentDescriptor.getProcessHandler(), myConsole);
}
+ final DefaultActionGroup focus = new DefaultActionGroup();
+ focus.add(ActionManager.getInstance().getAction(XDebuggerActions.FOCUS_ON_BREAKPOINT));
+ myUi.getOptions().setAdditionalFocusActions(focus);
+
rebuildViews();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
index 0c41a5d1015b..aa3445b4b421 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
@@ -56,6 +56,7 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase {
return false;
}
};
+ myEditorTextField.setFontInheritedFromLAF(false);
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
index 3db287f84210..629385c9ad20 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
@@ -69,14 +69,13 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
if (!isShown()) {
return;
}
+ myInplaceEditorComponent = null;
onHidden();
for (Runnable action : myRemoveActions) {
action.run();
}
myRemoveActions.clear();
- myInplaceEditorComponent = null;
-
final JTree tree = getTree();
tree.repaint();
tree.requestFocus();
@@ -172,7 +171,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
@Override
public void run() {
tree.removeHierarchyListener(hierarchyListener);
- tree.addComponentListener(componentListener);
+ tree.removeComponentListener(componentListener);
rootPane.removeComponentListener(componentListener);
}
});
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
index 3b3a481f9870..afb22607d5d6 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
@@ -27,6 +27,7 @@ import com.intellij.ui.PopupHandler;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
+import com.intellij.util.containers.TransferToEDTQueue;
import com.intellij.util.ui.TextTransferable;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
@@ -56,6 +57,8 @@ import java.util.List;
* @author nik
*/
public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposable {
+ private final TransferToEDTQueue<Runnable> myLaterInvocator = TransferToEDTQueue.createRunnableMerger("XDebuggerTree later invocator", 100);
+
private static final DataKey<XDebuggerTree> XDEBUGGER_TREE_KEY = DataKey.create("xdebugger.tree");
private static final Convertor<TreePath, String> SPEED_SEARCH_CONVERTER = new Convertor<TreePath, String>() {
@Override
@@ -324,4 +327,8 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
public static XDebuggerTree getTree(DataContext context) {
return XDEBUGGER_TREE_KEY.getData(context);
}
+
+ public TransferToEDTQueue<Runnable> getLaterInvocator() {
+ return myLaterInvocator;
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
index c4bb274400ea..66f22bbfd4f1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
@@ -55,9 +55,9 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (view == null && project != null) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
- return ((XDebugSessionImpl)session).getSessionTab().getWatchesView();
+ view = ((XDebugSessionImpl)session).getSessionTab().getWatchesView();
}
}
- return null;
+ return view;
}
} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
index dccd5fd4f3f2..e01d0ad7ce79 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java
@@ -189,4 +189,8 @@ public abstract class XDebuggerTreeNode implements TreeNode, TreeSpeedSearch.Pat
component.append(link.getLinkText(), link.getTextAttributes(), link);
}
}
+
+ void invokeNodeUpdate(Runnable runnable) {
+ myTree.getLaterInvocator().offer(runnable);
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index a7059a4a10e0..38d2547831fe 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -22,7 +22,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.SortedList;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
-import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -75,7 +74,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
@Override
public void addChildren(@NotNull final XValueChildrenList children, final boolean last) {
- DebuggerUIUtil.invokeLater(new Runnable() {
+ invokeNodeUpdate(new Runnable() {
@Override
public void run() {
if (myValueChildren == null) {
@@ -125,7 +124,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
@Override
public void tooManyChildren(final int remaining) {
- DebuggerUIUtil.invokeLater(new Runnable() {
+ invokeNodeUpdate(new Runnable() {
@Override
public void run() {
setTemporaryMessageNode(MessageTreeNode.createEllipsisNode(myTree, XValueContainerNode.this, remaining));
@@ -162,7 +161,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
@Override
public void setMessage(@NotNull final String message,
final Icon icon, @NotNull final SimpleTextAttributes attributes, @Nullable final XDebuggerTreeNodeHyperlink link) {
- DebuggerUIUtil.invokeLater(new Runnable() {
+ invokeNodeUpdate(new Runnable() {
@Override
public void run() {
setMessageNodes(MessageTreeNode.createMessages(myTree, XValueContainerNode.this, message, link,
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java
index 6bc3e56e0934..536822734d86 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodePresentationConfigurator.java
@@ -94,12 +94,18 @@ public final class XValueNodePresentationConfigurator {
node.applyPresentation(icon, presentation, hasChildren);
}
else {
- application.invokeLater(new Runnable() {
+ Runnable updater = new Runnable() {
@Override
public void run() {
node.applyPresentation(icon, presentation, hasChildren);
}
- });
+ };
+ if (node instanceof XDebuggerTreeNode) {
+ ((XDebuggerTreeNode)node).invokeNodeUpdate(updater);
+ }
+ else {
+ application.invokeLater(updater);
+ }
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresentationUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresentationUtil.java
index 188b20d27da4..5f202d8de278 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresentationUtil.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValuePresentationUtil.java
@@ -16,16 +16,13 @@
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
-import com.intellij.openapi.editor.colors.EditorColorsManager;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
-import com.intellij.ui.ColorUtil;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -49,7 +46,7 @@ public class XValuePresentationUtil {
lastOffset = i + 1;
if (escapeAttributes == null) {
- TextAttributes fromHighlighter = getColorScheme().getAttributes(DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE);
+ TextAttributes fromHighlighter = DebuggerUIUtil.getColorScheme().getAttributes(DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE);
if (fromHighlighter != null) {
escapeAttributes = SimpleTextAttributes.fromTextAttributes(fromHighlighter);
}
@@ -123,6 +120,11 @@ public class XValuePresentationUtil {
}
@Override
+ public void renderError(@NotNull String error) {
+ myBuilder.append(error);
+ }
+
+ @Override
public void renderSpecialSymbol(@NotNull String symbol) {
myBuilder.append(symbol);
}
@@ -131,16 +133,4 @@ public class XValuePresentationUtil {
return myBuilder.toString();
}
}
-
- @NotNull
- public static EditorColorsScheme getColorScheme() {
- EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
- if (UIUtil.isUnderDarcula() != ColorUtil.isDark(globalScheme.getDefaultBackground())) {
- EditorColorsScheme scheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME);
- if (scheme != null) {
- return scheme;
- }
- }
- return globalScheme;
- }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java
index 90fd00268724..e8b8616e6b69 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,14 +41,14 @@ class XValueTextRendererImpl extends XValueTextRendererBase {
@Override
protected void renderRawValue(@NotNull String value, @NotNull TextAttributesKey key) {
- TextAttributes textAttributes = XValuePresentationUtil.getColorScheme().getAttributes(key);
+ TextAttributes textAttributes = DebuggerUIUtil.getColorScheme().getAttributes(key);
SimpleTextAttributes attributes = SimpleTextAttributes.fromTextAttributes(textAttributes);
myText.append(value, attributes);
}
@Override
public void renderStringValue(@NotNull String value, @Nullable String additionalSpecialCharsToHighlight, int maxLength) {
- TextAttributes textAttributes = XValuePresentationUtil.getColorScheme().getAttributes(DefaultLanguageHighlighterColors.STRING);
+ TextAttributes textAttributes = DebuggerUIUtil.getColorScheme().getAttributes(DefaultLanguageHighlighterColors.STRING);
SimpleTextAttributes attributes = SimpleTextAttributes.fromTextAttributes(textAttributes);
myText.append("\"", attributes);
XValuePresentationUtil.renderValue(value, myText, attributes, maxLength, additionalSpecialCharsToHighlight);
@@ -60,6 +61,11 @@ class XValueTextRendererImpl extends XValueTextRendererBase {
}
@Override
+ public void renderError(@NotNull String error) {
+ myText.append(error, SimpleTextAttributes.ERROR_ATTRIBUTES);
+ }
+
+ @Override
public void renderSpecialSymbol(@NotNull String symbol) {
myText.append(symbol, SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java
index 7220922e7f75..7c03c4b548b3 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XBreakpointsTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,6 +15,8 @@
*/
package com.intellij.xdebugger;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.TempFiles;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
@@ -54,7 +56,11 @@ public abstract class XBreakpointsTestCase extends XDebuggerTestCase {
}
protected List<XBreakpoint<?>> getAllBreakpoints() {
- final XBreakpointBase<?,?,?>[] breakpoints = myBreakpointManager.getAllBreakpoints();
+ final XBreakpointBase<?,?,?>[] breakpoints = ApplicationManager.getApplication().runReadAction(new Computable<XBreakpointBase<?,?,?>[]>() {
+ public XBreakpointBase<?,?,?>[] compute() {
+ return myBreakpointManager.getAllBreakpoints();
+ }
+ });
final List<XBreakpoint<?>> result = new ArrayList<XBreakpoint<?>>();
for (XBreakpointBase<?, ?, ?> breakpoint : breakpoints) {
final XBreakpointType type = breakpoint.getType();
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
index 0401532e74f9..e47002649d5a 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerTestUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
@@ -367,7 +368,7 @@ public class XDebuggerTestUtil {
public static void removeAllBreakpoints(@NotNull final Project project) {
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
- XBreakpoint<?>[] breakpoints = breakpointManager.getAllBreakpoints();
+ XBreakpoint<?>[] breakpoints = getBreakpoints(breakpointManager);
for (final XBreakpoint b : breakpoints) {
new WriteAction() {
@Override
@@ -378,6 +379,14 @@ public class XDebuggerTestUtil {
}
}
+ public static XBreakpoint<?>[] getBreakpoints(final XBreakpointManager breakpointManager) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<XBreakpoint<?>[]>() {
+ public XBreakpoint<?>[] compute() {
+ return breakpointManager.getAllBreakpoints();
+ }
+ });
+ }
+
public static <B extends XBreakpoint<?>>
void setDefaultBreakpointEnabled(@NotNull final Project project, Class<? extends XBreakpointType<B, ?>> bpTypeClass, boolean enabled) {
final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
@@ -390,7 +399,7 @@ public class XDebuggerTestUtil {
public static void setBreakpointCondition(Project project, int line, final String condition) {
XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
- for (XBreakpoint breakpoint : breakpointManager.getAllBreakpoints()) {
+ for (XBreakpoint breakpoint : getBreakpoints(breakpointManager)) {
if (breakpoint instanceof XLineBreakpoint) {
final XLineBreakpoint lineBreakpoint = (XLineBreakpoint)breakpoint;
@@ -408,7 +417,7 @@ public class XDebuggerTestUtil {
public static void setBreakpointLogExpression(Project project, int line, final String logExpression) {
XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager();
- for (XBreakpoint breakpoint : breakpointManager.getAllBreakpoints()) {
+ for (XBreakpoint breakpoint : getBreakpoints(breakpointManager)) {
if (breakpoint instanceof XLineBreakpoint) {
final XLineBreakpoint lineBreakpoint = (XLineBreakpoint)breakpoint;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 6bde0a908ba4..890da15b546b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -90,6 +90,10 @@
key="assignment.to.for.loop.parameter.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.assignment.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.assignment.AssignmentToForLoopParameterInspection"/>
+ <localInspection language="JAVA" shortName="AssignmentToLambdaParameter" bundle="com.siyeh.InspectionGadgetsBundle"
+ key="assignment.to.lambda.parameter.display.name" groupBundle="messages.InspectionsBundle"
+ groupKey="group.names.assignment.issues" enabledByDefault="false" level="WARNING"
+ implementationClass="com.siyeh.ig.assignment.AssignmentToLambdaParameterInspection"/>
<localInspection language="JAVA" shortName="AssignmentToMethodParameter" bundle="com.siyeh.InspectionGadgetsBundle"
key="assignment.to.method.parameter.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.assignment.issues" enabledByDefault="false" level="WARNING"
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 04419fb871e9..efeb65889a93 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -2093,4 +2093,6 @@ bigdecimal.legacy.method.quickfix=Use 'RoundingMode' enum constant
serializable.stores.non.serializable.display.name=Serializable object implicitly stores non-Serializable object
serializable.lambda.stores.non.serializable.problem.descriptor=Serializable lambda implicitly stores non-Serializable object of type ''{0}''
serializable.local.class.stores.non.serializable.problem.descriptor=Serializable local class ''{1}'' implicitly stores non-Serializable object of type ''{0}''
-serializable.anonymous.class.stores.non.serializable.problem.descriptor=Serializable anonymous class implicitly stores non-Serializable object of type ''{0}'' \ No newline at end of file
+serializable.anonymous.class.stores.non.serializable.problem.descriptor=Serializable anonymous class implicitly stores non-Serializable object of type ''{0}''
+assignment.to.lambda.parameter.display.name=Assignment to lambda parameter
+assignment.to.lambda.parameter.problem.descriptor=Assignment to lambda parameter <code>#ref</code> #loc
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspection.java
index 1b079275a49f..8be9ce07a5ef 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspection.java
@@ -27,6 +27,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.ui.DocumentAdapter;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.UIUtil;
import com.siyeh.ig.telemetry.InspectionGadgetsTelemetry;
import org.jetbrains.annotations.Nls;
@@ -37,7 +38,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.Document;
-import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.List;
@@ -104,46 +104,33 @@ public abstract class BaseInspection extends BaseJavaBatchLocalInspectionTool {
return visitor;
}
- protected JFormattedTextField prepareNumberEditor(@NonNls String fieldName) {
- try {
- final NumberFormat formatter = NumberFormat.getIntegerInstance();
- formatter.setParseIntegerOnly(true);
- final JFormattedTextField valueField = new JFormattedTextField(formatter);
- final Field field = getClass().getField(fieldName);
- valueField.setValue(field.get(this));
- valueField.setColumns(2);
-
- // hack to work around text field becoming unusably small sometimes when using GridBagLayout
- valueField.setMinimumSize(valueField.getPreferredSize());
-
- UIUtil.fixFormattedField(valueField);
- final Document document = valueField.getDocument();
- document.addDocumentListener(new DocumentAdapter() {
- @Override
- public void textChanged(DocumentEvent evt) {
- try {
- valueField.commitEdit();
- final Number number = (Number)valueField.getValue();
- field.set(BaseInspection.this,
- Integer.valueOf(number.intValue()));
- }
- catch (IllegalAccessException e) {
- LOG.error(e);
- }
- catch (ParseException e) {
- // No luck this time. Will update the field when correct value is entered.
- }
+ protected JFormattedTextField prepareNumberEditor(@NonNls final String fieldName) {
+ final NumberFormat formatter = NumberFormat.getIntegerInstance();
+ formatter.setParseIntegerOnly(true);
+ final JFormattedTextField valueField = new JFormattedTextField(formatter);
+ Object value = ReflectionUtil.getField(getClass(), this, null, fieldName);
+ valueField.setValue(value);
+ valueField.setColumns(2);
+
+ // hack to work around text field becoming unusably small sometimes when using GridBagLayout
+ valueField.setMinimumSize(valueField.getPreferredSize());
+
+ UIUtil.fixFormattedField(valueField);
+ final Document document = valueField.getDocument();
+ document.addDocumentListener(new DocumentAdapter() {
+ @Override
+ public void textChanged(DocumentEvent evt) {
+ try {
+ valueField.commitEdit();
+ final Number number = (Number)valueField.getValue();
+ ReflectionUtil.setField(BaseInspection.this.getClass(), BaseInspection.this, int.class, fieldName, number.intValue());
}
- });
- return valueField;
- }
- catch (NoSuchFieldException e) {
- LOG.error(e);
- }
- catch (IllegalAccessException e) {
- LOG.error(e);
- }
- return null;
+ catch (ParseException e) {
+ // No luck this time. Will update the field when correct value is entered.
+ }
+ }
+ });
+ return valueField;
}
protected static void parseString(String string, List<String>... outs) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
index bf185ea030ce..e979a678c4d8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspection.java
@@ -175,6 +175,9 @@ public class OverlyStrongTypeCastInspection extends BaseInspection {
if (castTypeElement == null) {
return;
}
+ if (operand instanceof PsiFunctionalExpression && !LambdaUtil.isFunctionalType(expectedType)) {
+ return;
+ }
registerError(castTypeElement, expectedType);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToCatchBlockParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToCatchBlockParameterInspection.java
index 3eb05ecc5a26..737996ed64dd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToCatchBlockParameterInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToCatchBlockParameterInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,68 +15,27 @@
*/
package com.siyeh.ig.assignment;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiCatchSection;
+import com.intellij.psi.PsiElement;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.fixes.ExtractParameterAsLocalVariableFix;
-import com.siyeh.ig.psiutils.WellFormednessUtils;
import org.jetbrains.annotations.NotNull;
-public class AssignmentToCatchBlockParameterInspection
- extends BaseInspection {
+public class AssignmentToCatchBlockParameterInspection extends BaseAssignmentToParameterInspection {
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "assignment.to.catch.block.parameter.display.name");
+ return InspectionGadgetsBundle.message("assignment.to.catch.block.parameter.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "assignment.to.catch.block.parameter.problem.descriptor");
+ return InspectionGadgetsBundle.message("assignment.to.catch.block.parameter.problem.descriptor");
}
@Override
- protected InspectionGadgetsFix buildFix(Object... infos) {
- return new ExtractParameterAsLocalVariableFix();
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new AssignmentToCatchBlockParameterVisitor();
- }
-
- private static class AssignmentToCatchBlockParameterVisitor
- extends BaseInspectionVisitor {
-
- @Override
- public void visitAssignmentExpression(
- @NotNull PsiAssignmentExpression expression) {
- super.visitAssignmentExpression(expression);
- if (!WellFormednessUtils.isWellFormed(expression)) {
- return;
- }
- final PsiExpression lhs = expression.getLExpression();
- if (!(lhs instanceof PsiReferenceExpression)) {
- return;
- }
- final PsiReferenceExpression reference =
- (PsiReferenceExpression)lhs;
- final PsiElement variable = reference.resolve();
- if (!(variable instanceof PsiParameter)) {
- return;
- }
- final PsiParameter parameter = (PsiParameter)variable;
- final PsiElement declarationScope = parameter.getDeclarationScope();
- if (!(declarationScope instanceof PsiCatchSection)) {
- return;
- }
- registerError(lhs);
- }
+ protected boolean isCorrectScope(PsiElement declarationScope) {
+ return declarationScope instanceof PsiCatchSection;
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspection.java
new file mode 100644
index 000000000000..4694a0152e12
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspection.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.assignment;
+
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiLambdaExpression;
+import com.intellij.psi.PsiLocalVariable;
+import com.siyeh.InspectionGadgetsBundle;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class AssignmentToLambdaParameterInspection extends BaseAssignmentToParameterInspection {
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("assignment.to.lambda.parameter.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message("assignment.to.lambda.parameter.problem.descriptor");
+ }
+
+ @Override
+ @Nullable
+ public JComponent createOptionsPanel() {
+ return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
+ "assignment.to.method.parameter.ignore.transformation.option"), this, "ignoreTransformationOfOriginalParameter");
+ }
+
+ @Override
+ protected boolean isCorrectScope(PsiElement declarationScope) {
+ return declarationScope instanceof PsiLambdaExpression;
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToMethodParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToMethodParameterInspection.java
index ae616c40d42a..56dbecc83d6b 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToMethodParameterInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToMethodParameterInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,22 +15,16 @@
*/
package com.siyeh.ig.assignment;
-import com.intellij.psi.*;
-import com.intellij.psi.tree.IElementType;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.fixes.ExtractParameterAsLocalVariableFix;
-import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-public class AssignmentToMethodParameterInspection
- extends BaseInspection {
+public class AssignmentToMethodParameterInspection extends BaseAssignmentToParameterInspection {
@SuppressWarnings({"PublicField"})
public boolean ignoreTransformationOfOriginalParameter = false;
@@ -38,134 +32,23 @@ public class AssignmentToMethodParameterInspection
@Override
@NotNull
public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "assignment.to.method.parameter.display.name");
+ return InspectionGadgetsBundle.message("assignment.to.method.parameter.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "assignment.to.method.parameter.problem.descriptor");
+ return InspectionGadgetsBundle.message("assignment.to.method.parameter.problem.descriptor");
}
@Override
@Nullable
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
- "assignment.to.method.parameter.ignore.transformation.option"), this,
- "ignoreTransformationOfOriginalParameter");
+ "assignment.to.method.parameter.ignore.transformation.option"), this, "ignoreTransformationOfOriginalParameter");
}
- @Override
- protected InspectionGadgetsFix buildFix(Object... infos) {
- return new ExtractParameterAsLocalVariableFix();
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new AssignmentToMethodParameterVisitor();
- }
-
- private class AssignmentToMethodParameterVisitor
- extends BaseInspectionVisitor {
-
- @Override
- public void visitAssignmentExpression(
- @NotNull PsiAssignmentExpression expression) {
- super.visitAssignmentExpression(expression);
- final PsiExpression lhs = expression.getLExpression();
- final PsiParameter parameter = getMethodParameter(lhs);
- if (parameter == null) {
- return;
- }
- if (ignoreTransformationOfOriginalParameter) {
- final PsiExpression rhs = expression.getRExpression();
- if (rhs != null && VariableAccessUtils.variableIsUsed(parameter, rhs)) {
- return;
- }
- final IElementType tokenType =
- expression.getOperationTokenType();
- if (tokenType == JavaTokenType.PLUSEQ ||
- tokenType == JavaTokenType.MINUSEQ ||
- tokenType == JavaTokenType.ASTERISKEQ ||
- tokenType == JavaTokenType.DIVEQ ||
- tokenType == JavaTokenType.ANDEQ ||
- tokenType == JavaTokenType.OREQ ||
- tokenType == JavaTokenType.XOREQ ||
- tokenType == JavaTokenType.PERCEQ ||
- tokenType == JavaTokenType.LTLTEQ ||
- tokenType == JavaTokenType.GTGTEQ ||
- tokenType == JavaTokenType.GTGTGTEQ) {
- return;
- }
- }
- registerError(lhs);
- }
-
- @Override
- public void visitPrefixExpression(
- @NotNull PsiPrefixExpression expression) {
- if (ignoreTransformationOfOriginalParameter) {
- return;
- }
- super.visitPrefixExpression(expression);
- final IElementType tokenType = expression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return;
- }
- final PsiExpression operand = expression.getOperand();
- if (operand == null) {
- return;
- }
- final PsiParameter parameter = getMethodParameter(operand);
- if (parameter == null) {
- return;
- }
- registerError(operand);
- }
-
- @Override
- public void visitPostfixExpression(
- @NotNull PsiPostfixExpression expression) {
- if (ignoreTransformationOfOriginalParameter) {
- return;
- }
- super.visitPostfixExpression(expression);
- final IElementType tokenType = expression.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
- !tokenType.equals(JavaTokenType.MINUSMINUS)) {
- return;
- }
- final PsiExpression operand = expression.getOperand();
- final PsiParameter parameter = getMethodParameter(operand);
- if (parameter == null) {
- return;
- }
- registerError(operand);
- }
-
- @Nullable
- private PsiParameter getMethodParameter(PsiExpression expression) {
- if (!(expression instanceof PsiReferenceExpression)) {
- return null;
- }
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)expression;
- final PsiElement variable = referenceExpression.resolve();
- if (!(variable instanceof PsiParameter)) {
- return null;
- }
- final PsiParameter parameter = (PsiParameter)variable;
- final PsiElement declarationScope = parameter.getDeclarationScope();
- if (declarationScope instanceof PsiCatchSection) {
- return null;
- }
- if (declarationScope instanceof PsiForeachStatement) {
- return null;
- }
- return parameter;
- }
+ protected boolean isCorrectScope(PsiElement declarationScope) {
+ return declarationScope instanceof PsiMethod;
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/BaseAssignmentToParameterInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/BaseAssignmentToParameterInspection.java
new file mode 100644
index 000000000000..7f27c6bf762a
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/BaseAssignmentToParameterInspection.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.assignment;
+
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.fixes.ExtractParameterAsLocalVariableFix;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public abstract class BaseAssignmentToParameterInspection extends BaseInspection {
+
+ @SuppressWarnings({"PublicField"})
+ public boolean ignoreTransformationOfOriginalParameter = false;
+
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ return new ExtractParameterAsLocalVariableFix();
+ }
+
+ protected abstract boolean isCorrectScope(PsiElement declarationScope);
+
+ @Override
+ public final BaseInspectionVisitor buildVisitor() {
+ return new AssignmentToParameterVisitor();
+ }
+
+ private class AssignmentToParameterVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) {
+ super.visitAssignmentExpression(expression);
+ final PsiExpression lhs = expression.getLExpression();
+ final PsiParameter parameter = getParameter(lhs);
+ if (parameter == null) {
+ return;
+ }
+ if (ignoreTransformationOfOriginalParameter) {
+ final PsiExpression rhs = expression.getRExpression();
+ if (rhs != null && VariableAccessUtils.variableIsUsed(parameter, rhs)) {
+ return;
+ }
+ final IElementType tokenType =
+ expression.getOperationTokenType();
+ if (tokenType == JavaTokenType.PLUSEQ ||
+ tokenType == JavaTokenType.MINUSEQ ||
+ tokenType == JavaTokenType.ASTERISKEQ ||
+ tokenType == JavaTokenType.DIVEQ ||
+ tokenType == JavaTokenType.ANDEQ ||
+ tokenType == JavaTokenType.OREQ ||
+ tokenType == JavaTokenType.XOREQ ||
+ tokenType == JavaTokenType.PERCEQ ||
+ tokenType == JavaTokenType.LTLTEQ ||
+ tokenType == JavaTokenType.GTGTEQ ||
+ tokenType == JavaTokenType.GTGTGTEQ) {
+ return;
+ }
+ }
+ registerError(lhs);
+ }
+
+ @Override
+ public void visitPrefixExpression(@NotNull PsiPrefixExpression expression) {
+ if (ignoreTransformationOfOriginalParameter) {
+ return;
+ }
+ super.visitPrefixExpression(expression);
+ final IElementType tokenType = expression.getOperationTokenType();
+ if (!tokenType.equals(JavaTokenType.PLUSPLUS) && !tokenType.equals(JavaTokenType.MINUSMINUS)) {
+ return;
+ }
+ final PsiExpression operand = expression.getOperand();
+ if (operand == null) {
+ return;
+ }
+ final PsiParameter parameter = getParameter(operand);
+ if (parameter == null) {
+ return;
+ }
+ registerError(operand);
+ }
+
+ @Override
+ public void visitPostfixExpression(@NotNull PsiPostfixExpression expression) {
+ if (ignoreTransformationOfOriginalParameter) {
+ return;
+ }
+ super.visitPostfixExpression(expression);
+ final IElementType tokenType = expression.getOperationTokenType();
+ if (!tokenType.equals(JavaTokenType.PLUSPLUS) && !tokenType.equals(JavaTokenType.MINUSMINUS)) {
+ return;
+ }
+ final PsiExpression operand = expression.getOperand();
+ final PsiParameter parameter = getParameter(operand);
+ if (parameter == null) {
+ return;
+ }
+ registerError(operand);
+ }
+
+ @Nullable
+ private PsiParameter getParameter(PsiExpression expression) {
+ expression = ParenthesesUtils.stripParentheses(expression);
+ if (!(expression instanceof PsiReferenceExpression)) {
+ return null;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
+ final PsiElement variable = referenceExpression.resolve();
+ if (!(variable instanceof PsiParameter)) {
+ return null;
+ }
+ final PsiParameter parameter = (PsiParameter)variable;
+ final PsiElement declarationScope = parameter.getDeclarationScope();
+ if (!isCorrectScope(declarationScope)) {
+ return null;
+ }
+ return parameter;
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java
index cbf33121dd44..080a6e58c409 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2011 Bas Leijdekkers
+ * Copyright 2008-2014 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -57,11 +58,10 @@ public class ThrowableResultOfMethodCallIgnoredInspection
extends BaseInspectionVisitor {
@Override
- public void visitMethodCallExpression(
- PsiMethodCallExpression expression) {
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
PsiElement parent = expression.getParent();
- while (parent instanceof PsiParenthesizedExpression) {
+ while (parent instanceof PsiParenthesizedExpression || parent instanceof PsiTypeCastExpression) {
parent = parent.getParent();
}
if (parent instanceof PsiReturnStatement ||
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ScopeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ScopeUtils.java
index 368f1a13d773..cd61a938f8c1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ScopeUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/ScopeUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.siyeh.ig.dataflow;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.PsiElementOrderComparator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -86,7 +87,7 @@ class ScopeUtils {
final PsiExpression expression = statement.getExpression();
if (expression instanceof PsiAssignmentExpression) {
final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression;
- final PsiExpression lExpression = assignmentExpression.getLExpression();
+ final PsiExpression lExpression = ParenthesesUtils.stripParentheses(assignmentExpression.getLExpression());
if (!lExpression.equals(referenceElement)) {
commonParent = PsiTreeUtil.getParentOfType(commonParent, PsiCodeBlock.class);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
index 31a7987f40f1..277d95359624 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFix.java
@@ -26,6 +26,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
public class ExtractParameterAsLocalVariableFix
@@ -46,8 +47,15 @@ public class ExtractParameterAsLocalVariableFix
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
- final PsiReferenceExpression parameterReference =
- (PsiReferenceExpression)descriptor.getPsiElement();
+ final PsiElement element = descriptor.getPsiElement();
+ if (!(element instanceof PsiExpression)) {
+ return;
+ }
+ final PsiExpression expression = ParenthesesUtils.stripParentheses((PsiExpression)element);
+ if (!(expression instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression parameterReference = (PsiReferenceExpression)expression;
final PsiElement target = parameterReference.resolve();
if (!(target instanceof PsiParameter)) {
return;
@@ -102,12 +110,12 @@ public class ExtractParameterAsLocalVariableFix
if (reference == null) {
return;
}
- final PsiElement element = reference.getElement();
- if (!(element instanceof PsiReferenceExpression)) {
+ final PsiElement referenceElement = reference.getElement();
+ if (!(referenceElement instanceof PsiReferenceExpression)) {
return;
}
final PsiReferenceExpression firstReference =
- (PsiReferenceExpression)element;
+ (PsiReferenceExpression)referenceElement;
final PsiElement[] children = body.getChildren();
final int startIndex;
final int endIndex;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
index 9992f57f39dd..132193f02451 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2013 Bas Leijdekkers
+ * Copyright 2006-2014 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
@@ -79,7 +80,8 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
final PsiElement parent = element.getParent();
if (parent instanceof PsiTypeParameter) {
final PsiTypeParameter typeParameter = (PsiTypeParameter)parent;
- replaceTypeParameterAndReferencesWithType(typeParameter);
+ replaceTypeParameterUsagesWithType(typeParameter);
+ typeParameter.delete();
}
else if (parent instanceof PsiTypeElement) {
final PsiTypeElement typeElement = (PsiTypeElement)parent;
@@ -91,25 +93,18 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
}
}
- private static void replaceTypeParameterAndReferencesWithType(PsiTypeParameter typeParameter) {
- final PsiReferenceList extendsList = typeParameter.getExtendsList();
- final PsiClassType[] referenceElements = extendsList.getReferencedTypes();
- if (referenceElements.length < 1) {
- return;
- }
- final PsiClass finalClass = referenceElements[0].resolve();
- if (finalClass == null) {
+ private static void replaceTypeParameterUsagesWithType(PsiTypeParameter typeParameter) {
+ final PsiClassType[] types = typeParameter.getExtendsList().getReferencedTypes();
+ if (types.length < 1) {
return;
}
final Project project = typeParameter.getProject();
- final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- final PsiJavaCodeReferenceElement classReference = factory.createClassReferenceElement(finalClass);
+ final PsiJavaCodeReferenceElement classReference = JavaPsiFacade.getElementFactory(project).createReferenceElementByType(types[0]);
final Query<PsiReference> query = ReferencesSearch.search(typeParameter, typeParameter.getUseScope());
for (PsiReference reference : query) {
final PsiElement referenceElement = reference.getElement();
referenceElement.replace(classReference);
}
- typeParameter.delete();
}
}
@@ -123,6 +118,9 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
@Override
public void visitTypeParameter(PsiTypeParameter classParameter) {
super.visitTypeParameter(classParameter);
+ if (!PsiUtil.isLanguageLevel5OrHigher(classParameter)) {
+ return;
+ }
final PsiClassType[] extendsListTypes = classParameter.getExtendsListTypes();
if (extendsListTypes.length < 1) {
return;
@@ -140,6 +138,9 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
@Override
public void visitTypeElement(PsiTypeElement typeElement) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(typeElement)) {
+ return;
+ }
super.visitTypeElement(typeElement);
final PsiType type = typeElement.getType();
if (!(type instanceof PsiWildcardType)) {
@@ -155,6 +156,17 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
if (aClass == null || !aClass.hasModifierProperty(PsiModifier.FINAL)) {
return;
}
+ if (aClass.hasTypeParameters() && !PsiUtil.isLanguageLevel8OrHigher(typeElement)) {
+ final PsiType[] parameters = classType.getParameters();
+ if (parameters.length == 0) {
+ return;
+ }
+ for (PsiType parameter : parameters) {
+ if (parameter instanceof PsiWildcardType) {
+ return;
+ }
+ }
+ }
if (!shouldReport(typeElement)) {
return;
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
index 66ea85532660..000563d0312d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/SimplifiableIfStatementInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2013 Bas Leijdekkers
+ * Copyright 2006-2014 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,21 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
+import java.util.List;
+
public class SimplifiableIfStatementInspection extends BaseInspection {
@Override
@@ -280,21 +282,68 @@ public class SimplifiableIfStatementInspection extends BaseInspection {
}
@Override
- public void doFix(Project project, ProblemDescriptor descriptor)
- throws IncorrectOperationException {
+ public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
final PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
- final String newStatement = calculateReplacementStatement(ifStatement);
- if (newStatement == null) {
+ List<PsiComment> before = new ArrayList<PsiComment>();
+ List<PsiComment> after = new ArrayList<PsiComment>();
+ collectComments(ifStatement, true, before, after);
+ final String newStatementText = calculateReplacementStatement(ifStatement);
+ if (newStatementText == null) {
return;
}
+ final StringBuilder codeBlockText = new StringBuilder("{\n");
+ for (PsiComment comment : before) {
+ codeBlockText.append(comment.getText()).append('\n');
+ }
+ codeBlockText.append(newStatementText).append('\n');
+ for (PsiComment comment : after) {
+ codeBlockText.append(comment.getText()).append('\n');
+ }
+ codeBlockText.append('}');
if (ifStatement.getElseBranch() == null) {
final PsiElement nextStatement = PsiTreeUtil.skipSiblingsForward(ifStatement, PsiWhiteSpace.class);
if (nextStatement != null) {
nextStatement.delete();
}
}
- PsiReplacementUtil.replaceStatement(ifStatement, newStatement);
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiCodeBlock codeBlock = psiFacade.getElementFactory().createCodeBlockFromText(codeBlockText.toString(), ifStatement);
+ final PsiElement parent = ifStatement.getParent();
+ PsiElement child = codeBlock.getFirstBodyElement();
+ final PsiElement end = codeBlock.getLastBodyElement();
+ while (true) {
+ parent.addBefore(child, ifStatement);
+ if (child == end) {
+ break;
+ }
+ child = child.getNextSibling();
+ }
+ ifStatement.delete();
+ CodeStyleManager.getInstance(project).reformat(parent);
+ }
+
+ private static void collectComments(PsiElement element, boolean first, List<PsiComment> before, List<PsiComment> after) {
+ if (element instanceof PsiComment) {
+ if (first) {
+ before.add((PsiComment)element);
+ }
+ else {
+ after.add((PsiComment)element);
+ }
+ return;
+ }
+ for (PsiElement child : element.getChildren()) {
+ if (child instanceof PsiKeyword) {
+ final PsiKeyword keyword = (PsiKeyword)child;
+ if (keyword.getTokenType() == JavaTokenType.ELSE_KEYWORD) {
+ first = false;
+ }
+ }
+ else {
+ collectComments(child, first, before, after);
+ }
+ }
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoCommentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoCommentInspection.java
index 9b79d5453758..72ac229533ec 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoCommentInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoCommentInspection.java
@@ -15,40 +15,38 @@
*/
package com.siyeh.ig.maturity;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.InspectionManager;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.PsiTodoSearchHelper;
+import com.intellij.psi.search.TodoItem;
+import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-public class TodoCommentInspection extends BaseInspection {
+import java.util.ArrayList;
+import java.util.List;
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionGadgetsBundle.message("todo.comment.display.name");
- }
+public class TodoCommentInspection extends BaseJavaBatchLocalInspectionTool {
+ @Nullable
@Override
- @NotNull
- public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message("todo.comment.problem.descriptor");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new ClassWithoutToStringVisitor();
- }
-
- private static class ClassWithoutToStringVisitor
- extends BaseInspectionVisitor {
+ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ final PsiTodoSearchHelper searchHelper = PsiTodoSearchHelper.SERVICE.getInstance(file.getProject());
+ final TodoItem[] todoItems = searchHelper.findTodoItems(file);
- @Override
- public void visitComment(PsiComment comment) {
- super.visitComment(comment);
- if (TodoUtil.isTodoComment(comment)) {
- registerError(comment);
+ final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>();
+ for (TodoItem todoItem : todoItems) {
+ final PsiComment comment = PsiTreeUtil.getParentOfType(file.findElementAt(todoItem.getTextRange().getStartOffset()), PsiComment.class, false);
+ if (comment != null) {
+ result.add(manager.createProblemDescriptor(comment, InspectionGadgetsBundle.message("todo.comment.problem.descriptor"), isOnTheFly,
+ null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
}
}
+ return result.toArray(new ProblemDescriptor[result.size()]);
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoUtil.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoUtil.java
deleted file mode 100644
index a75f9185bf3e..000000000000
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/maturity/TodoUtil.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2003-2005 Dave Griffith
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.siyeh.ig.maturity;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiComment;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.PsiTodoSearchHelper;
-import com.intellij.psi.search.TodoItem;
-
-public class TodoUtil {
- private TodoUtil() {
- super();
- }
-
- public static boolean isTodoComment(PsiComment comment) {
- final PsiFile file = comment.getContainingFile();
- final PsiTodoSearchHelper searchHelper = PsiTodoSearchHelper.SERVICE.getInstance(comment.getProject());
- final TodoItem[] todoItems = searchHelper.findTodoItems(file);
- for (final TodoItem todoItem : todoItems) {
- final TextRange commentTextRange = comment.getTextRange();
- final TextRange todoTextRange = todoItem.getTextRange();
- if (commentTextRange.contains(todoTextRange)) {
- return true;
- }
- }
- return false;
- }
-} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java
index 26cbe4b72c0f..0a7d282dbb0a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldVisitor.java
@@ -15,10 +15,7 @@
*/
package com.siyeh.ig.serialization;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiModifier;
-import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.HardcodedMethodConstants;
@@ -39,12 +36,13 @@ class SerializableInnerClassHasSerialVersionUIDFieldVisitor
@Override
public void visitClass(@NotNull PsiClass aClass) {
// no call to super, so it doesn't drill down
- if (aClass.isInterface() || aClass.isAnnotationType() ||
- aClass.isEnum()) {
+ if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) {
return;
}
- if (inspection.ignoreAnonymousInnerClasses &&
- aClass instanceof PsiAnonymousClass) {
+ if (aClass instanceof PsiTypeParameter) {
+ return;
+ }
+ if (inspection.ignoreAnonymousInnerClasses && aClass instanceof PsiAnonymousClass) {
return;
}
if (aClass.findFieldByName(HardcodedMethodConstants.SERIAL_VERSION_UID, false) != null) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java
index e629e7485250..7596c3f57bfa 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassVisitor.java
@@ -15,10 +15,7 @@
*/
package com.siyeh.ig.serialization;
-import com.intellij.psi.PsiAnonymousClass;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiModifier;
-import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -37,12 +34,13 @@ class SerializableInnerClassWithNonSerializableOuterClassVisitor
@Override
public void visitClass(@NotNull PsiClass aClass) {
- if (aClass.isInterface() || aClass.isAnnotationType() ||
- aClass.isEnum()) {
+ if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) {
return;
}
- if (inspection.ignoreAnonymousInnerClasses &&
- aClass instanceof PsiAnonymousClass) {
+ if (aClass instanceof PsiTypeParameter) {
+ return;
+ }
+ if (inspection.ignoreAnonymousInnerClasses && aClass instanceof PsiAnonymousClass) {
return;
}
final PsiClass containingClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
index aa2d3ea2fce1..6c4051066ad5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnnecessaryThisInspection.java
@@ -15,6 +15,7 @@
*/
package com.siyeh.ig.style;
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemHighlightType;
@@ -136,6 +137,9 @@ public class UnnecessaryThisInspection extends BaseInspection implements Cleanup
if (!VariableSearchUtils.variableNameResolvesToTarget(referenceName, variable, expression)) {
return;
}
+ if (variable instanceof PsiField && HighlightUtil.isIllegalForwardReferenceToField(expression, (PsiField)variable, true) != null) {
+ return;
+ }
registerError(thisExpression, ProblemHighlightType.LIKE_UNUSED_SYMBOL);
}
else {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java
index b051e2e653a2..b4d67d6a5b89 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase.java
@@ -44,7 +44,11 @@ public class AccessToNonThreadSafeStaticFieldFromInstanceInspectionBase extends
@SuppressWarnings("PublicField")
public final ExternalizableStringSet nonThreadSafeClasses =
- new ExternalizableStringSet("java.text.SimpleDateFormat", "java.util.Calendar");
+ new ExternalizableStringSet("java.text.SimpleDateFormat",
+ "java.text.MessageFormat",
+ "java.text.DecimalFormat",
+ "java.text.ChoiceFormat",
+ "java.util.Calendar");
@NonNls
@SuppressWarnings({"PublicField"})
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
index b4a66996769e..0bba9c356c50 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/dataflow/TooBroadScopeInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,11 +96,23 @@ public class TooBroadScopeInspection extends TooBroadScopeInspectionBase {
PsiDeclarationStatement newDeclaration;
if (commonParent instanceof PsiForStatement) {
final PsiForStatement forStatement = (PsiForStatement)commonParent;
- newDeclaration = createNewDeclaration(variable, initializer);
final PsiStatement initialization = forStatement.getInitialization();
if (initialization == null) {
return;
}
+ if (initialization instanceof PsiExpressionStatement) {
+ final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)initialization;
+ final PsiExpression expression = expressionStatement.getExpression();
+ if (!(expression instanceof PsiAssignmentExpression)) {
+ return;
+ }
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression;
+ final PsiExpression rhs = assignmentExpression.getRExpression();
+ newDeclaration = createNewDeclaration(variable, rhs);
+ }
+ else {
+ newDeclaration = createNewDeclaration(variable, initializer);
+ }
newDeclaration = (PsiDeclarationStatement)initialization.replace(newDeclaration);
} else if (firstReferenceScope.equals(commonParent)) {
newDeclaration = moveDeclarationToLocation(variable, referenceElement);
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java
index bbd0f1491925..50459db5ecb1 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/ProblematicWhitespaceInspection.java
@@ -143,7 +143,7 @@ public class ProblematicWhitespaceInspection extends BaseInspection {
}
else if (!spaceSeen) {
final int currentIndent = Math.max(0, j);
- if (currentIndent != previousLineIndent) {
+ if (currentIndent < previousLineIndent) {
registerError(file, file.getName(), Boolean.valueOf(isOnTheFly()), Boolean.TRUE);
return;
}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToLambdaParameter.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToLambdaParameter.html
new file mode 100644
index 000000000000..1ed29bfee193
--- /dev/null
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AssignmentToLambdaParameter.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+Reports assignments to a lambda parameter, this includes compound assignments and incrementing or decrementing the parameter.
+While occasionally intended, this construct can be extremely confusing, and is often the result of a typo.
+<!-- tooltip end -->
+<p>
+<small>New in 14</small>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.after.java
new file mode 100644
index 000000000000..c0f859235f39
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.after.java
@@ -0,0 +1,8 @@
+package com.siyeh.igfixes.dataflow.too_broad_scope;
+
+public class ForStatement3 {
+ void m() {
+ for (int i = 0; i < 10; i++) {
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.java
new file mode 100644
index 000000000000..21b30a72e278
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/dataflow/too_broad_scope/ForStatement3.java
@@ -0,0 +1,9 @@
+package com.siyeh.igfixes.dataflow.too_broad_scope;
+
+public class ForStatement3 {
+ void m() {
+ int <caret>i;
+ for ((i) = 0; i < 10; i++) {
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.after.java
new file mode 100644
index 000000000000..ade4b5cadaae
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.after.java
@@ -0,0 +1,5 @@
+class FinalClassWithTypeParamer {
+
+ A<String> t;
+}
+final class A<T> {} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.java
new file mode 100644
index 000000000000..cd905b7b5def
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/inheritance/type_parameter_extends_final_class/FinalClassWithTypeParameter.java
@@ -0,0 +1,5 @@
+class FinalClassWithTypeParamer<T<caret> extends A<String>> {
+
+ T t;
+}
+final class A<T> {} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.after.java
new file mode 100644
index 000000000000..eb7d5ee00acb
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.after.java
@@ -0,0 +1,17 @@
+class Comments {
+
+ void m(boolean b) {
+ boolean c;
+ // 1
+// 2
+ c = b || f();
+// 3
+// 4
+//5
+//6
+ }
+
+ boolean f() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.java
new file mode 100644
index 000000000000..f88fcefa4bcf
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/j2me/simplifiable_if_statement/Comments.java
@@ -0,0 +1,16 @@
+class Comments {
+
+ void m(boolean b) {
+ boolean c;
+ if<caret> (b) // 1
+ c = true; // 2
+ else { // 3
+ c = f(); // 4
+ } //5
+ //6
+ }
+
+ boolean f() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java
index bb67aa939be7..255af72562f2 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/overly_strong_type_cast/OverlyStrongTypeCast.java
@@ -65,3 +65,9 @@ class SubClass2 extends SubClass{
super.doSmth();
}
}
+
+class SAM {
+ {
+ Object runnable = (Runnable) () -> {};
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_lambda_parameter/AssignmentToLambdaParameter.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_lambda_parameter/AssignmentToLambdaParameter.java
new file mode 100644
index 000000000000..7aecf144c635
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_lambda_parameter/AssignmentToLambdaParameter.java
@@ -0,0 +1,15 @@
+class AssignmentToLambdaParameter {
+
+ interface C {
+ void consume(Object o);
+ }
+
+ static {
+ C c = (o) -> {
+ System.out.println(o);
+ <warning descr="Assignment to lambda parameter 'o'">o</warning> = new Object();
+ System.out.println(o);
+ };
+ }
+
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/AssigmentToMethodParameterMissesCompoundAssign.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/AssigmentToMethodParameterMissesCompoundAssign.java
index e6bbe2677666..9139d1e883f6 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/AssigmentToMethodParameterMissesCompoundAssign.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/AssigmentToMethodParameterMissesCompoundAssign.java
@@ -3,26 +3,42 @@ package com.siyeh.igtest.assignment.method_parameter;
class AssigmentToMethodParameterMissesCompoundAssign {
public void incrementParameter(int value) {
- value++; // not flagged by the inspection
+ <warning descr="Assignment to method parameter 'value'">value</warning>++; // not flagged by the inspection
}
public void compoundAssignParameter(int value) {
- value += 1; // flagged by the inspection
+ <warning descr="Assignment to method parameter 'value'">value</warning> += 1; // flagged by the inspection
}
public void compoundAssignParameter(int value, int increment) {
- value += increment; // flagged by the inspection
+ <warning descr="Assignment to method parameter 'value'">value</warning> += increment; // flagged by the inspection
}
public void foo(String s) {
System.out.println(s);
- s = "other";
+ <warning descr="Assignment to method parameter 's'">s</warning> = "other";
System.out.println(s);
}
public void method(int decreased, int increased) {
- decreased += 10; // not highlighted
- increased -= 10; // highlighted
+ <warning descr="Assignment to method parameter 'decreased'">decreased</warning> += 10; // not highlighted
+ <warning descr="Assignment to method parameter 'increased'">increased</warning> -= 10; // highlighted
+ }
+
+ public void parenthesized(int p) {
+ System.out.println(p);
+ <warning descr="Assignment to method parameter '(p)'">(p)</warning> = 1;
+ }
+
+ public void leaveMyLambdaAlone() {
+ Consumer c = (p) -> {
+ p = null;
+ System.out.println(p);
+ };
+ }
+
+ interface Consumer {
+ void m(Object o);
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/IgnoreTransformationOfParameter.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/IgnoreTransformationOfParameter.java
new file mode 100644
index 000000000000..7de6a31afaad
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/IgnoreTransformationOfParameter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.igtest.assignment.method_parameter;
+
+class IgnoreTransformationOfParameter {
+
+ public void incrementParameter(int value) {
+ value++; // not flagged by the inspection
+ }
+
+ public void compoundAssignParameter(int value) {
+ value += 1; // flagged by the inspection
+ }
+
+ public void compoundAssignParameter(int value, int increment) {
+ value += increment; // flagged by the inspection
+ }
+
+ public void foo(String s) {
+ System.out.println(s);
+ <warning descr="Assignment to method parameter 's'">s</warning> = "other";
+ System.out.println(s);
+ }
+
+ public void method(int decreased, int increased) {
+ decreased += 10; // not highlighted
+ increased -= 10; // highlighted
+ }
+
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/expected.xml
deleted file mode 100644
index e6c64dc4141c..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter/expected.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>AssigmentToMethodParameterMissesCompoundAssign.java</file>
- <line>19</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Assignment to method parameter</problem_class>
- <description>Assignment to method parameter &lt;code&gt;s&lt;/code&gt; #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/A.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/A.java
index 488651f5481b..ee413b9cfe9e 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/A.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/A.java
@@ -5,7 +5,7 @@ package com.siyeh.igtest.bugs.throwable_result_of_method_call_ignored;
public class A {
public static void test() {
try {
- firstNonNull(new Throwable(), null);
+ <warning descr="Result of 'firstNonNull()' not thrown">firstNonNull</warning>(new Throwable(), null);
}
catch (Exception e) {
throw new RuntimeException(firstNonNull(e.getCause(), e));
@@ -15,4 +15,12 @@ public class A {
public static <T> T firstNonNull(T first, T second) {
return first != null ? first : second;
}
+
+ void m() {
+ throw (RuntimeException) b();
+ }
+
+ public Exception b() {
+ return new RuntimeException();
+ }
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/expected.xml
deleted file mode 100644
index a02d25eb9ecf..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored/expected.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>A.java</file>
- <line>8</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Throwable result of method call ignored</problem_class>
- <description>Result of &lt;code&gt;firstNonNull()&lt;/code&gt; not thrown #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
index 8302df83df11..fcca2f17ce70 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
@@ -9,7 +9,7 @@ public class TooBroadScope
public void test() {
// Example #1
{
- Collection<Integer> list = null; //scope too broad
+ Collection<Integer> <warning descr="Scope of variable 'list' is too broad">list</warning> = null; //scope too broad
{
list = new ArrayList<Integer>();
list.add(new Integer(0));
@@ -19,7 +19,7 @@ public class TooBroadScope
// Example #2
{
- Collection<Integer> list; // scope too broad
+ Collection<Integer> <warning descr="Scope of variable 'list' is too broad">list</warning>; // scope too broad
list = new ArrayList<Integer>();
list.add(new Integer(0));
}
@@ -27,14 +27,14 @@ public class TooBroadScope
// Example #3
{
- Collection<Integer> list = null; // nope
+ Collection<Integer> <warning descr="Scope of variable 'list' is too broad">list</warning> = null; // nope
list = new ArrayList<Integer>();
list.add(new Integer(0));
}
}
public void join() {
- String test;
+ String <warning descr="Scope of variable 'test' is too broad">test</warning>;
test = "asdf";
}
@@ -104,13 +104,13 @@ public class TooBroadScope
}
void forLoop() {
- int i = 0;
+ int <warning descr="Scope of variable 'i' is too broad">i</warning> = 0;
for ( ; i < 10; i++) {
System.out.println(i);
}
}
- void resourceVariable(boolean b) {
+ void resourceVariable(boolean b) throws Exception {
try (AutoCloseable ac = null) {
if (b) {
System.out.println(ac);
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/expected.xml
deleted file mode 100644
index 941a71eed17b..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/expected.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>TooBroadScope.java</file>
- <line>12</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Scope of variable is too broad</problem_class>
- <description>Scope of variable &lt;code&gt;list&lt;/code&gt; is too broad #loc</description>
- </problem>
-
- <problem>
- <file>TooBroadScope.java</file>
- <line>22</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Scope of variable is too broad</problem_class>
- <description>Scope of variable &lt;code&gt;list&lt;/code&gt; is too broad #loc</description>
- </problem>
-
- <problem>
- <file>TooBroadScope.java</file>
- <line>30</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Scope of variable is too broad</problem_class>
- <description>Scope of variable &lt;code&gt;list&lt;/code&gt; is too broad #loc</description>
- </problem>
-
- <problem>
- <file>TooBroadScope.java</file>
- <line>37</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Scope of variable is too broad</problem_class>
- <description>Scope of variable &lt;code&gt;test&lt;/code&gt; is too broad #loc</description>
- </problem>
-
- <problem>
- <file>TooBroadScope.java</file>
- <line>107</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Scope of variable is too broad</problem_class>
- <description>Scope of variable &lt;code&gt;i&lt;/code&gt; is too broad #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/TypeParameterExtendsFinalClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/TypeParameterExtendsFinalClass.java
index 422b1dd3b2d2..b92b7bfcdb5e 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/TypeParameterExtendsFinalClass.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/TypeParameterExtendsFinalClass.java
@@ -3,12 +3,16 @@ package com.siyeh.igtest.inheritance.type_parameter_extends_final_class;
import java.util.*;
-public class TypeParameterExtendsFinalClass<T extends String> {}
+public class TypeParameterExtendsFinalClass<<warning descr="Type parameter 'T' extends 'final' class 'String'">T</warning> extends String> {}
final class Usee {}
class User {
- List<? extends Usee> list;
+ List<<warning descr="Wildcard type argument '?' extends 'final' class 'Usee'">?</warning> extends Usee> list;
List<? extends List> l;
+ private static final Collection<? extends Class> ourStopSearch = Collections.singleton(String.class);
+ Collection<<warning descr="Wildcard type argument '?' extends 'final' class 'FieldIdentifier'">?</warning> extends FieldIdentifier<String>> a = Collections.singleton(new FieldIdentifier<String>());
+ Collection<? extends FieldIdentifier<?>> b = Collections.singleton(new FieldIdentifier<String>());
+ static final class FieldIdentifier<T> {}
}
abstract class MyList implements List<Integer> {
@Override
@@ -16,7 +20,7 @@ abstract class MyList implements List<Integer> {
return false;
}
}
-abstract class SampleMap<T extends String> implements Map<String, Object> {
+abstract class SampleMap<<warning descr="Type parameter 'T' extends 'final' class 'String'">T</warning> extends String> implements Map<String, Object> {
public void putAll(final Map<? extends String, ?> m) {
final Set<? extends Entry<? extends String,?>> entries = m.entrySet();
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/expected.xml
deleted file mode 100644
index df1d975903b3..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/type_parameter_extends_final_class/expected.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>TypeParameterExtendsFinalClass.java</file>
- <line>6</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Type parameter extends final class</problem_class>
- <description>Type parameter &lt;code&gt;T&lt;/code&gt; extends final class 'String' #loc</description>
- </problem>
-
- <problem>
- <file>TypeParameterExtendsFinalClass.java</file>
- <line>10</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Type parameter extends final class</problem_class>
- <description>Wildcard type argument &lt;code&gt;?&lt;/code&gt; extends final class 'Usee' #loc</description>
- </problem>
-
- <problem>
- <file>TypeParameterExtendsFinalClass.java</file>
- <line>19</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Type parameter extends final class</problem_class>
- <description>Type parameter &lt;code&gt;T&lt;/code&gt; extends 'final' class 'String' #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/SimplifiableIfStatement.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/SimplifiableIfStatement.java
index e16fa78944ed..a9fc8622513f 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/SimplifiableIfStatement.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/SimplifiableIfStatement.java
@@ -5,25 +5,25 @@ public class SimplifiableIfStatement {
boolean a = bar();
boolean b = bar();
final boolean i;
- if (a) {
+ <warning descr="'if' statement can be replaced with 'i = !a || b;'">if</warning> (a) {
i = b;
} else {
i = true;
}
final boolean j;
- if (a) {
+ <warning descr="'if' statement can be replaced with 'j = a || b;'">if</warning> (a) {
j = true;
} else {
j = b;
}
final boolean k;
- if (a) {
+ <warning descr="'if' statement can be replaced with 'k = a && b;'">if</warning> (a) {
k = b;
} else {
k = false;
}
final boolean l;
- if (a) {
+ <warning descr="'if' statement can be replaced with 'l = !a && b;'">if</warning> (a) {
l = false;
} else {
l = b;
@@ -37,7 +37,7 @@ public class SimplifiableIfStatement {
public boolean foo1() {
boolean a = bar();
boolean b = bar();
- if (a) {
+ <warning descr="'if' statement can be replaced with 'return !a || b;'">if</warning> (a) {
return b;
} else {
return true;
@@ -47,7 +47,7 @@ public class SimplifiableIfStatement {
public boolean foo2() {
boolean a = bar();
boolean b = bar();
- if (a) {
+ <warning descr="'if' statement can be replaced with 'return a || b;'">if</warning> (a) {
return true;
} else {
return b;
@@ -57,7 +57,7 @@ public class SimplifiableIfStatement {
public boolean foo3() {
boolean a = bar();
boolean b = bar();
- if (a) {
+ <warning descr="'if' statement can be replaced with 'return !a && b;'">if</warning> (a) {
return false;
} else {
return b;
@@ -67,7 +67,7 @@ public class SimplifiableIfStatement {
public boolean foo4() {
boolean a = bar();
boolean b = bar();
- if (a) {
+ <warning descr="'if' statement can be replaced with 'return a && b;'">if</warning> (a) {
return b;
} else {
return false;
@@ -76,7 +76,7 @@ public class SimplifiableIfStatement {
public static boolean original(boolean a, boolean b, boolean c, boolean d) {
- if (!(a || b)) {
+ <warning descr="'if' statement can be replaced with 'return (a || b) && (c || d);'">if</warning> (!(a || b)) {
return false;
}
@@ -100,7 +100,7 @@ public class SimplifiableIfStatement {
}
boolean m(boolean b1, boolean b2, boolean b3, boolean b4, boolean i) {
- if (b1 == b2 == b3 == b4) {
+ <warning descr="'if' statement can be replaced with 'return b1!=b2==b3!=b4 && (i = true);'">if</warning> (b1 == b2 == b3 == b4) {
return false;
}
return i = true;
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/expected.xml
deleted file mode 100644
index b03e23ee988b..000000000000
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/simplifiable_if_statement/expected.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>50</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return a || b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>70</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return a &amp;&amp; b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>8</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'i = !a || b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>14</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'j = a || b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>20</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'k = a &amp;&amp; b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>26</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'l = !a &amp;&amp; b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>40</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return !a || b;' #loc</description>
- </problem>
-
-
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>60</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return !a &amp;&amp; b;' #loc</description>
- </problem>
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>79</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">If statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return (a || b) &amp;&amp; (c || d);' #loc</description>
- </problem>
-
- <problem>
- <file>SimplifiableIfStatement.java</file>
- <line>103</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'if' statement may be replaced with &amp;&amp; or || expression</problem_class>
- <description>&lt;code&gt;if&lt;/code&gt; statement can be replaced with 'return b1!=b2==b3!=b4 &amp;amp;&amp;amp; (i = true);' #loc</description>
- </problem>
-</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
index 7a3bad556b03..d262e31333ba 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/LightInspectionTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.util.ArrayUtil;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
@@ -34,9 +35,13 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
for (String environmentClass : getEnvironmentClasses()) {
myFixture.addClass(environmentClass);
}
- myFixture.enableInspections(getInspection());
+ final InspectionProfileEntry inspection = getInspection();
+ if (inspection != null) {
+ myFixture.enableInspections(inspection);
+ }
}
+ @Nullable
protected abstract InspectionProfileEntry getInspection();
@NonNls
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java
index 2912c294528d..e2b54f8c6a1d 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OverlyStrongTypeCastInspectionTest.java
@@ -1,5 +1,6 @@
package com.siyeh.ig.abstraction;
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.siyeh.ig.IGInspectionTestCase;
public class OverlyStrongTypeCastInspectionTest extends IGInspectionTestCase {
@@ -7,6 +8,6 @@ public class OverlyStrongTypeCastInspectionTest extends IGInspectionTestCase {
public void test() throws Exception {
final OverlyStrongTypeCastInspection tool = new OverlyStrongTypeCastInspection();
tool.ignoreInMatchingInstanceof = true;
- doTest("com/siyeh/igtest/abstraction/overly_strong_type_cast", tool);
+ doTest("com/siyeh/igtest/abstraction/overly_strong_type_cast", new LocalInspectionToolWrapper(tool), "java 1.8");
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspectionTest.java
new file mode 100644
index 000000000000..50af7f1f9932
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToLambdaParameterInspectionTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.assignment;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class AssignmentToLambdaParameterInspectionTest extends LightInspectionTestCase {
+
+ public void testAssignmentToLambdaParameter() {
+ doTest();
+ }
+
+ @Nullable
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new AssignmentToLambdaParameterInspection();
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToMethodParameterInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToMethodParameterInspectionTest.java
index 40177fbf7286..5176a176d231 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToMethodParameterInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToMethodParameterInspectionTest.java
@@ -1,14 +1,32 @@
package com.siyeh.ig.assignment;
-import com.siyeh.ig.IGInspectionTestCase;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
-public class AssignmentToMethodParameterInspectionTest extends IGInspectionTestCase {
+/**
+ * @author bas
+ */
+public class AssignmentToMethodParameterInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- final AssignmentToMethodParameterInspection inspection =
- new AssignmentToMethodParameterInspection();
+ public void testAssigmentToMethodParameterMissesCompoundAssign() {
+ myFixture.enableInspections(new AssignmentToMethodParameterInspection());
+ doTest();
+ }
+
+ public void testIgnoreTransformationOfParameter() {
+ final AssignmentToMethodParameterInspection inspection = new AssignmentToMethodParameterInspection();
inspection.ignoreTransformationOfOriginalParameter = true;
- doTest("com/siyeh/igtest/assignment/method_parameter",
- inspection);
+ myFixture.enableInspections(inspection);
+ doTest();
+ }
+
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return null;
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/method_parameter";
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspectionTest.java
index 9f021f563e77..adeb8aeca497 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ThrowableResultOfMethodCallIgnoredInspectionTest.java
@@ -1,12 +1,17 @@
package com.siyeh.ig.bugs;
+import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.IGInspectionTestCase;
+import com.siyeh.ig.LightInspectionTestCase;
-public class ThrowableResultOfMethodCallIgnoredInspectionTest
- extends IGInspectionTestCase {
+public class ThrowableResultOfMethodCallIgnoredInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- doTest("com/siyeh/igtest/bugs/throwable_result_of_method_call_ignored",
- new ThrowableResultOfMethodCallIgnoredInspection());
+ public void testA() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new ThrowableResultOfMethodCallIgnoredInspection();
}
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/TooBroadScopeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/TooBroadScopeInspectionTest.java
index 51b6f9c69372..c575cafcdc36 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/TooBroadScopeInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/TooBroadScopeInspectionTest.java
@@ -1,10 +1,22 @@
package com.siyeh.ig.dataflow;
+import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.IGInspectionTestCase;
+import com.siyeh.ig.LightInspectionTestCase;
-public class TooBroadScopeInspectionTest extends IGInspectionTestCase {
+public class TooBroadScopeInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- doTest("com/siyeh/igtest/dataflow/scope", new TooBroadScopeInspection());
+ public void testTooBroadScope() {
+ doTest();
+ }
+
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new TooBroadScopeInspection();
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope";
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java
index b8b74aecf249..84328091b56f 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/ExtractParameterAsLocalVariableFixTest.java
@@ -20,6 +20,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.IGQuickFixesTestCase;
import com.siyeh.ig.assignment.AssignmentToCatchBlockParameterInspection;
import com.siyeh.ig.assignment.AssignmentToForLoopParameterInspection;
+import com.siyeh.ig.assignment.AssignmentToLambdaParameterInspection;
import com.siyeh.ig.assignment.AssignmentToMethodParameterInspection;
/**
@@ -35,7 +36,8 @@ public class ExtractParameterAsLocalVariableFixTest extends IGQuickFixesTestCase
return new BaseInspection[] {
new AssignmentToMethodParameterInspection(),
inspection2,
- new AssignmentToCatchBlockParameterInspection()
+ new AssignmentToCatchBlockParameterInspection(),
+ new AssignmentToLambdaParameterInspection()
};
}
@@ -79,6 +81,23 @@ public class ExtractParameterAsLocalVariableFixTest extends IGQuickFixesTestCase
);
}
+ public void testParenthesizedExpression() {
+ doTest(InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
+ "class X {" +
+ " void m(int i) {" +
+ " (/**/i)++;" +
+ " System.out.println(i);" +
+ " }" +
+ "}",
+ "class X {\n" +
+ " void m(int i) {\n" +
+ " int i1 = i;\n" +
+ " (i1)++;\n" +
+ " System.out.println(i1);\n" +
+ " }\n" +
+ "}");
+ }
+
public void testSimpleForeach() {
doTest(
InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
@@ -96,7 +115,7 @@ public class ExtractParameterAsLocalVariableFixTest extends IGQuickFixesTestCase
);
}
- public void testSimleCatchBlock() {
+ public void testSimpleCatchBlock() {
doTest(
InspectionGadgetsBundle.message("extract.parameter.as.local.variable.quickfix"),
"class X {" +
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/dataflow/TooBroadScopeInspectionFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/dataflow/TooBroadScopeInspectionFixTest.java
index 72f2dc39d7e6..27ca0a41387f 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/dataflow/TooBroadScopeInspectionFixTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/dataflow/TooBroadScopeInspectionFixTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -33,4 +33,5 @@ public class TooBroadScopeInspectionFixTest extends IGQuickFixesTestCase {
public void testForStatement() { doTest(InspectionGadgetsBundle.message("too.broad.scope.narrow.quickfix", "i")); }
public void testForStatement2() { doTest(InspectionGadgetsBundle.message("too.broad.scope.narrow.quickfix", "i")); }
+ public void testForStatement3() { doTest(InspectionGadgetsBundle.message("too.broad.scope.narrow.quickfix", "i")); }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/TypeParameterExtendsFinalClassFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/TypeParameterExtendsFinalClassFixTest.java
new file mode 100644
index 000000000000..77fea4770ca1
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/inheritance/TypeParameterExtendsFinalClassFixTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.fixes.inheritance;
+
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.IGQuickFixesTestCase;
+import com.siyeh.ig.inheritance.TypeParameterExtendsFinalClassInspection;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class TypeParameterExtendsFinalClassFixTest extends IGQuickFixesTestCase {
+
+ public void testFinalClassWithTypeParameter() { doTest(); }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myFixture.enableInspections(new TypeParameterExtendsFinalClassInspection());
+ myRelativePath = "inheritance/type_parameter_extends_final_class";
+ myDefaultHint = InspectionGadgetsBundle.message("type.parameter.extends.final.class.quickfix");
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/j2me/SimplifiableIfStatementFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/j2me/SimplifiableIfStatementFixTest.java
new file mode 100644
index 000000000000..8646a903e782
--- /dev/null
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/j2me/SimplifiableIfStatementFixTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.fixes.j2me;
+
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.IGQuickFixesTestCase;
+import com.siyeh.ig.j2me.SimplifiableIfStatementInspection;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class SimplifiableIfStatementFixTest extends IGQuickFixesTestCase {
+
+ public void testComments() { doTest(); }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myFixture.enableInspections(new SimplifiableIfStatementInspection());
+ myRelativePath = "j2me/simplifiable_if_statement";
+ myDefaultHint = InspectionGadgetsBundle.message("constant.conditional.expression.simplify.quickfix");
+ }
+}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspectionTest.java
index e6c3a53604db..94eca51f9b18 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/inheritance/TypeParameterExtendsFinalClassInspectionTest.java
@@ -1,10 +1,26 @@
package com.siyeh.ig.inheritance;
-import com.siyeh.ig.IGInspectionTestCase;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.NotNull;
-public class TypeParameterExtendsFinalClassInspectionTest extends IGInspectionTestCase {
+/**
+ * @author bas
+ */
+public class TypeParameterExtendsFinalClassInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- doTest("com/siyeh/igtest/inheritance/type_parameter_extends_final_class", new TypeParameterExtendsFinalClassInspection());
+ public void testTypeParameterExtendsFinalClass() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new TypeParameterExtendsFinalClassInspection();
+ }
+
+ @NotNull
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return JAVA_1_7;
}
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/j2me/SimplifiableIfStatementInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/j2me/SimplifiableIfStatementInspectionTest.java
index e10361c4e24d..db221fffd3ba 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/j2me/SimplifiableIfStatementInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/j2me/SimplifiableIfStatementInspectionTest.java
@@ -1,11 +1,16 @@
package com.siyeh.ig.j2me;
-import com.siyeh.ig.IGInspectionTestCase;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
-public class SimplifiableIfStatementInspectionTest extends IGInspectionTestCase {
+public class SimplifiableIfStatementInspectionTest extends LightInspectionTestCase {
- public void test() throws Exception {
- doTest("com/siyeh/igtest/j2me/simplifiable_if_statement",
- new SimplifiableIfStatementInspection());
+ public void testSimplifiableIfStatement() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected InspectionProfileEntry getInspection() {
+ return new SimplifiableIfStatementInspection();
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldInspectionTest.java
index a387c9c1e180..5bfc369e807c 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassHasSerialVersionUIDFieldInspectionTest.java
@@ -65,4 +65,8 @@ public class SerializableInnerClassHasSerialVersionUIDFieldInspectionTest extend
" }" +
"}");
}
+
+ public void testTypeParameter() {
+ doTest("class A<TypeParameter extends java.awt.Component> {}");
+ }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassInspectionTest.java
index 22c2dc68bd5b..49c7ee03886f 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/serialization/SerializableInnerClassWithNonSerializableOuterClassInspectionTest.java
@@ -58,4 +58,8 @@ public class SerializableInnerClassWithNonSerializableOuterClassInspectionTest e
" }" +
"}");
}
+
+ public void testTypeParameter() {
+ doTest("class A<TypeParameter extends java.awt.Component> {}");
+ }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java
index 3cfc26b152a2..9bce72a281af 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ProblematicWhitespaceInspectionTest.java
@@ -97,6 +97,17 @@ public class ProblematicWhitespaceInspectionTest extends LightInspectionTestCase
"}\n/**/");
}
+ public void testSmartTabsInFileWihtoutBinaryExpressionMultilineAlignment() {
+ final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
+ final CommonCodeStyleSettings.IndentOptions options = settings.getIndentOptions(JavaFileType.INSTANCE);
+ options.USE_TAB_CHARACTER = true;
+ options.SMART_TABS = true;
+ doTest("class X {{\n" +
+ "\tSystem.out.println(\"asdf\" +\n" +
+ "\t\t\t \"asdf\");\n" +
+ "}}");
+ }
+
@Override
protected InspectionProfileEntry getInspection() {
return new ProblematicWhitespaceInspection();
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java
index 0dad14e4009b..f3393eb74e24 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnnecessaryThisInspectionTest.java
@@ -134,6 +134,13 @@ public class UnnecessaryThisInspectionTest extends LightInspectionTestCase {
}
+ public void testLambdaMethodRefSelfRefs() {
+ doTest("class Main {" +
+ " Runnable lambdaExpression = () -> System.out.println(this.lambdaExpression);" +
+ " Runnable methodReference = this.methodReference::run;" +
+ "}");
+ }
+
@Override
protected LocalInspectionTool getInspection() {
return new UnnecessaryThisInspection();
diff --git a/plugins/IntelliLang/IntelliLang-java.iml b/plugins/IntelliLang/IntelliLang-java.iml
index 5d4b43c8d504..585a1f6d5a17 100644
--- a/plugins/IntelliLang/IntelliLang-java.iml
+++ b/plugins/IntelliLang/IntelliLang-java.iml
@@ -11,7 +11,7 @@
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="compiler-impl" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="java-impl" />
diff --git a/plugins/IntelliLang/IntelliLang-javaee.iml b/plugins/IntelliLang/IntelliLang-javaee.iml
deleted file mode 100644
index 00e420c8ab6f..000000000000
--- a/plugins/IntelliLang/IntelliLang-javaee.iml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module relativePaths="true" type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$/javaee-support">
- <sourceFolder url="file://$MODULE_DIR$/javaee-support" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="IntelliLang" />
- <orderEntry type="module" module-name="lang-api" />
- <orderEntry type="module" module-name="jsp-spi" />
- </component>
- <component name="copyright">
- <Base>
- <setting name="state" value="1" />
- </Base>
- </component>
-</module>
-
diff --git a/plugins/IntelliLang/IntelliLang-xml.iml b/plugins/IntelliLang/IntelliLang-xml.iml
index 4b8c7036d24d..20db7d65ff08 100644
--- a/plugins/IntelliLang/IntelliLang-xml.iml
+++ b/plugins/IntelliLang/IntelliLang-xml.iml
@@ -10,7 +10,7 @@
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="xml" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module" module-name="xpath" />
<orderEntry type="module" module-name="platform-api" />
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java
index e47eab83c397..5d337a1fd597 100644
--- a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/ErrorPostponingMethodVisitor.java
@@ -17,8 +17,8 @@ package org.jetbrains.jps.intellilang.instrumentation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.MethodVisitor;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.MethodVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
/**
* @author Eugene Zhuravlev
@@ -30,7 +30,7 @@ public class ErrorPostponingMethodVisitor extends MethodVisitor {
private final String myMethodName;
public ErrorPostponingMethodVisitor(@NotNull PatternInstrumenter instrumenter, String methodName, @Nullable MethodVisitor methodvisitor) {
- super(Opcodes.ASM4, methodvisitor);
+ super(Opcodes.ASM5, methodvisitor);
myInstrumenter = instrumenter;
myMethodName = methodName;
}
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/InstrumentationAdapter.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/InstrumentationAdapter.java
index 4d2a5ac6eedc..d782b69e3088 100644
--- a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/InstrumentationAdapter.java
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/InstrumentationAdapter.java
@@ -17,7 +17,7 @@ package org.jetbrains.jps.intellilang.instrumentation;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.*;
+import org.jetbrains.org.objectweb.asm.*;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -45,7 +45,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
Type returnType,
int access,
String name) {
- super(Opcodes.ASM4, methodvisitor);
+ super(Opcodes.ASM5, methodvisitor);
myInstrumenter = instrumenter;
myArgTypes = argTypes;
myReturnType = returnType;
@@ -180,8 +180,8 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
mv.visitIntInsn(BIPUSH, patternIndex);
mv.visitInsn(AALOAD);
mv.visitVarInsn(ALOAD, varIndex);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z", false);
mv.visitJumpInsn(Opcodes.IFNE, label);
}
@@ -206,7 +206,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
mv.visitTypeInsn(Opcodes.NEW, throwableClass);
mv.visitInsn(Opcodes.DUP);
mv.visitLdcInsn(message);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, throwableClass, "<init>", ctorSignature);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, throwableClass, "<init>", ctorSignature, false);
mv.visitInsn(Opcodes.ATHROW);
}
@@ -215,7 +215,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
private final PatternValue myPatternValue;
public MyAnnotationVisitor(AnnotationVisitor annotationvisitor, PatternValue v) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
av = annotationvisitor;
myPatternValue = v;
}
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
index 083252c17e58..ea215673b719 100644
--- a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternInstrumenter.java
@@ -20,8 +20,8 @@ import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.*;
import org.jetbrains.jps.intellilang.model.InstrumentationException;
+import org.jetbrains.org.objectweb.asm.*;
import java.io.IOException;
import java.io.InputStream;
@@ -53,7 +53,7 @@ class PatternInstrumenter extends ClassVisitor implements Opcodes {
public PatternInstrumenter(@NotNull String patternAnnotationClassName, ClassVisitor classvisitor,
InstrumentationType instrumentation,
InstrumentationClassFinder classFinder) {
- super(Opcodes.ASM4, classvisitor);
+ super(Opcodes.ASM5, classvisitor);
myPatternAnnotationClassName = patternAnnotationClassName;
myInstrumentationType = instrumentation;
@@ -156,7 +156,7 @@ class PatternInstrumenter extends ClassVisitor implements Opcodes {
mv.visitFieldInsn(GETSTATIC, myClassName, PATTERN_CACHE_NAME, JAVA_UTIL_REGEX_PATTERN);
mv.visitIntInsn(BIPUSH, i++);
mv.visitLdcInsn(pattern);
- mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;");
+ mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;", false);
mv.visitInsn(AASTORE);
}
}
@@ -164,7 +164,7 @@ class PatternInstrumenter extends ClassVisitor implements Opcodes {
// add assert startup code
private void initAssertions(MethodVisitor mv) {
mv.visitLdcInsn(Type.getType("L" + myClassName + ";"));
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
Label l0 = new Label();
mv.visitJumpInsn(IFNE, l0);
mv.visitInsn(ICONST_1);
@@ -251,14 +251,14 @@ class PatternInstrumenter extends ClassVisitor implements Opcodes {
final Ref<String> patternString = new Ref<String>(null);
// dig into annotation class and check if it is annotated with pattern annotation.
// if yes, load the pattern string from the pattern annotation and associate it with this annotation
- final ClassVisitor visitor = new ClassVisitor(Opcodes.ASM4) {
+ final ClassVisitor visitor = new ClassVisitor(Opcodes.ASM5) {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (patternString.get() != null || !myPatternAnnotationClassName.equals(Type.getType(desc).getClassName())) {
return null; // already found or is not pattern annotation
}
// dig into pattern annotation in order to discover the pattern string
- return new AnnotationVisitor(Opcodes.ASM4) {
+ return new AnnotationVisitor(Opcodes.ASM5) {
public void visit(@NonNls String name, Object value) {
if ("value".equals(name) && value instanceof String) {
patternString.set((String)value);
diff --git a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternValidatorBuilder.java b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternValidatorBuilder.java
index 36853633acfb..f2bbb9a8cbd7 100644
--- a/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternValidatorBuilder.java
+++ b/plugins/IntelliLang/intellilang-jps-plugin/src/org/jetbrains/jps/intellilang/instrumentation/PatternValidatorBuilder.java
@@ -18,8 +18,6 @@ package org.jetbrains.jps.intellilang.instrumentation;
import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.incremental.BinaryContent;
import org.jetbrains.jps.incremental.CompileContext;
@@ -30,6 +28,8 @@ import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.intellilang.model.InstrumentationException;
import org.jetbrains.jps.intellilang.model.JpsIntelliLangConfiguration;
import org.jetbrains.jps.intellilang.model.JpsIntelliLangExtensionService;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
/**
* @author Eugene Zhuravlev
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/LanguageReferenceProvider.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/LanguageReferenceProvider.java
index e8510b3b2974..2e8c74699f39 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/LanguageReferenceProvider.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/LanguageReferenceProvider.java
@@ -32,7 +32,7 @@ import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
*/
public final class LanguageReferenceProvider extends PsiReferenceContributor {
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
final Configuration configuration = Configuration.getInstance();
registrar.registerReferenceProvider(
literalExpression().annotationParam(StandardPatterns.string().with(new PatternCondition<String>("isLanguageAnnotation") {
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/Instrumenter.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/Instrumenter.java
index 53d9a6ae4d0f..b5e2cb018414 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/Instrumenter.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/Instrumenter.java
@@ -15,15 +15,15 @@
*/
package org.intellij.plugins.intelliLang.pattern.compiler;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
public abstract class Instrumenter extends ClassVisitor {
protected Instrumenter() {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
}
protected Instrumenter(ClassVisitor visitor) {
- super(Opcodes.ASM4, visitor);
+ super(Opcodes.ASM5, visitor);
}
public abstract boolean instrumented();
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/InstrumentationAdapter.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/InstrumentationAdapter.java
index cc5e1ad9753d..5949fd107c39 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/InstrumentationAdapter.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/InstrumentationAdapter.java
@@ -17,7 +17,7 @@ package org.intellij.plugins.intelliLang.pattern.compiler.impl;
import org.intellij.plugins.intelliLang.Configuration;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.asm4.*;
+import org.jetbrains.org.objectweb.asm.*;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -46,7 +46,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
Type returnType,
int access,
String name) {
- super(Opcodes.ASM4, methodvisitor);
+ super(Opcodes.ASM5, methodvisitor);
myInstrumenter = instrumenter;
myArgTypes = argTypes;
myReturnType = returnType;
@@ -178,8 +178,8 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
mv.visitIntInsn(BIPUSH, patternIndex);
mv.visitInsn(AALOAD);
mv.visitVarInsn(ALOAD, varIndex);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Pattern", "matcher", "(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;", false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/regex/Matcher", "matches", "()Z", false);
mv.visitJumpInsn(Opcodes.IFNE, label);
}
@@ -204,7 +204,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
mv.visitTypeInsn(Opcodes.NEW, throwableClass);
mv.visitInsn(Opcodes.DUP);
mv.visitLdcInsn(message);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, throwableClass, "<init>", ctorSignature);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, throwableClass, "<init>", ctorSignature, false);
mv.visitInsn(Opcodes.ATHROW);
}
@@ -213,7 +213,7 @@ class InstrumentationAdapter extends MethodVisitor implements Opcodes {
private final PatternValue myPatternValue;
public MyAnnotationVisitor(AnnotationVisitor annotationvisitor, PatternValue v) {
- super(Opcodes.ASM4);
+ super(Opcodes.ASM5);
av = annotationvisitor;
myPatternValue = v;
}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/PatternValidationInstrumenter.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/PatternValidationInstrumenter.java
index 12ee27843a4e..6fd88190a55d 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/PatternValidationInstrumenter.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/pattern/compiler/impl/PatternValidationInstrumenter.java
@@ -19,7 +19,7 @@ import org.intellij.plugins.intelliLang.Configuration;
import org.intellij.plugins.intelliLang.pattern.compiler.InstrumentationException;
import org.intellij.plugins.intelliLang.pattern.compiler.Instrumenter;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.asm4.*;
+import org.jetbrains.org.objectweb.asm.*;
import java.util.Arrays;
import java.util.HashMap;
@@ -140,7 +140,7 @@ public class PatternValidationInstrumenter extends Instrumenter implements Opcod
mv.visitFieldInsn(GETSTATIC, myClassName, PATTERN_CACHE_NAME, JAVA_UTIL_REGEX_PATTERN);
mv.visitIntInsn(BIPUSH, i++);
mv.visitLdcInsn(pattern);
- mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;");
+ mv.visitMethodInsn(INVOKESTATIC, "java/util/regex/Pattern", "compile", "(Ljava/lang/String;)Ljava/util/regex/Pattern;", false);
mv.visitInsn(AASTORE);
}
}
@@ -148,7 +148,7 @@ public class PatternValidationInstrumenter extends Instrumenter implements Opcod
// add assert startup code
private void initAssertions(MethodVisitor mv) {
mv.visitLdcInsn(Type.getType("L" + myClassName + ";"));
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
Label l0 = new Label();
mv.visitJumpInsn(IFNE, l0);
mv.visitInsn(ICONST_1);
@@ -167,7 +167,7 @@ public class PatternValidationInstrumenter extends Instrumenter implements Opcod
if ((access & ACC_STATIC) != 0 && name.equals("<clinit>")) {
myHasStaticInitializer = true;
- return new MethodVisitor(Opcodes.ASM4, methodvisitor) {
+ return new MethodVisitor(Opcodes.ASM5, methodvisitor) {
public void visitCode() {
super.visitCode();
patchStaticInitializer(mv);
diff --git a/plugins/IntelliLang/javaee-support/org/intellij/plugins/intelliLang/inject/config/JspSupportProxyImpl.java b/plugins/IntelliLang/javaee-support/org/intellij/plugins/intelliLang/inject/config/JspSupportProxyImpl.java
deleted file mode 100644
index e4f258927fa0..000000000000
--- a/plugins/IntelliLang/javaee-support/org/intellij/plugins/intelliLang/inject/config/JspSupportProxyImpl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.plugins.intelliLang.inject.config;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.IndexNotReadyException;
-import com.intellij.psi.impl.source.jsp.JspManager;
-import com.intellij.util.ArrayUtil;
-import org.jetbrains.annotations.NotNull;
-
-/**
-* @author Gregory.Shrago
-*/
-public class JspSupportProxyImpl extends JspSupportProxy {
- @NotNull
- @Override
- public String[] getPossibleTldUris(Module module) {
- try {
- return JspManager.getInstance(module.getProject()).getPossibleTldUris(module);
- }
- catch (IndexNotReadyException e) {
- return ArrayUtil.EMPTY_STRING_ARRAY;
- }
- }
-}
diff --git a/plugins/IntelliLang/src/META-INF/intellilang-javaee-support.xml b/plugins/IntelliLang/src/META-INF/intellilang-javaee-support.xml
deleted file mode 100644
index 19d55a8d9aac..000000000000
--- a/plugins/IntelliLang/src/META-INF/intellilang-javaee-support.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-
-<idea-plugin version="2">
-
- <extensions defaultExtensionNs="com.intellij">
- <applicationService serviceInterface="org.intellij.plugins.intelliLang.inject.config.JspSupportProxy"
- serviceImplementation="org.intellij.plugins.intelliLang.inject.config.JspSupportProxyImpl"/>
- </extensions>
-</idea-plugin> \ No newline at end of file
diff --git a/plugins/IntelliLang/src/META-INF/intellilang-js-support.xml b/plugins/IntelliLang/src/META-INF/intellilang-js-support.xml
deleted file mode 100644
index f24ab7aeeeb3..000000000000
--- a/plugins/IntelliLang/src/META-INF/intellilang-js-support.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-
-<idea-plugin version="2">
-
- <extensions defaultExtensionNs="org.intellij.intelliLang">
- <languageSupport implementation="com.intellij.plugins.intelliLang.inject.JSLanguageInjectionSupport"/>
- <injectionConfig config="resources/jsInjections.xml"/>
- </extensions>
- <extensions defaultExtensionNs="com.intellij">
- <patterns.patternClass className="com.intellij.lang.javascript.patterns.JSPatterns" alias="js"/>
- <lang.parserDefinition language="JSRegexp" implementationClass="com.intellij.lang.javascript.inject.JSRegexpParserDefinition"/>
- <regExpLanguageHost forClass="com.intellij.lang.javascript.psi.impl.JSLiteralExpressionImpl"
- implementationClass="com.intellij.lang.javascript.inject.JSRegexpHost"/>
- </extensions>
-</idea-plugin> \ No newline at end of file
diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml
index a6c430f242cf..a7f600958250 100644
--- a/plugins/IntelliLang/src/META-INF/plugin.xml
+++ b/plugins/IntelliLang/src/META-INF/plugin.xml
@@ -19,9 +19,7 @@
<depends optional="true" config-file="intellilang-xpath-support.xml">XPathView</depends>
<depends optional="true" config-file="intellilang-java-support.xml">com.intellij.modules.java</depends>
- <depends optional="true" config-file="intellilang-javaee-support.xml">com.intellij.javaee</depends>
<depends optional="true" config-file="intellilang-xml-support.xml">com.intellij.modules.xml</depends>
- <depends optional="true" config-file="intellilang-js-support.xml">JavaScript</depends>
<depends optional="true" config-file="intellilang-python-support.xml">com.intellij.modules.python</depends>
<extensionPoints>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
index 821284f9abc9..f55dbd7bdb04 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
@@ -66,8 +66,7 @@ import java.util.*;
* Making it a service may result in FileContentUtil.reparseFiles at a random loading moment which may cause
* mysterious PSI validity losses
*/
-public class Configuration implements PersistentStateComponent<Element>, ModificationTracker {
-
+public class Configuration extends SimpleModificationTracker implements PersistentStateComponent<Element>, ModificationTracker {
static final Logger LOG = Logger.getInstance(Configuration.class.getName());
private static final Condition<BaseInjection> LANGUAGE_INJECTION_CONDITION = new Condition<BaseInjection>() {
@Override
@@ -223,8 +222,6 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
}
});
- private volatile long myModificationCount;
-
public Configuration() {
}
@@ -436,11 +433,7 @@ public class Configuration implements PersistentStateComponent<Element>, Modific
}
private void configurationModified() {
- myModificationCount ++;
- }
-
- public long getModificationCount() {
- return myModificationCount;
+ incModificationCount();
}
@Nullable
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java
index 0ee07affca98..751eade99bb6 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/references/InjectedReferencesContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -57,7 +57,7 @@ public class InjectedReferencesContributor extends PsiReferenceContributor {
}
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(), new PsiReferenceProvider() {
@NotNull
@Override
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/CharToStringPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/CharToStringPredicate.java
index 9f3db5ec6d15..38b88f5920df 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/CharToStringPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/CharToStringPredicate.java
@@ -21,6 +21,8 @@ import com.intellij.psi.tree.IElementType;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NonNls;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
class CharToStringPredicate implements PsiElementPredicate {
public boolean satisfiedBy(PsiElement element) {
@@ -55,7 +57,7 @@ class CharToStringPredicate implements PsiElementPredicate {
return false;
}
final String parentTypeText = parentType.getCanonicalText();
- return "java.lang.String".equals(parentTypeText);
+ return JAVA_LANG_STRING.equals(parentTypeText);
}
else if (parent instanceof PsiAssignmentExpression) {
final PsiAssignmentExpression parentExpression =
@@ -69,7 +71,7 @@ class CharToStringPredicate implements PsiElementPredicate {
return false;
}
final String parentTypeText = parentType.getCanonicalText();
- return "java.lang.String".equals(parentTypeText);
+ return JAVA_LANG_STRING.equals(parentTypeText);
}
else if (parent instanceof PsiExpressionList) {
final PsiElement grandParent = parent.getParent();
@@ -106,7 +108,7 @@ class CharToStringPredicate implements PsiElementPredicate {
final PsiElement method = methodExpression.resolve();
return method != null;
}
- else if ("java.lang.String".equals(className)) {
+ else if (JAVA_LANG_STRING.equals(className)) {
@NonNls final String methodName =
methodExpression.getReferenceName();
if (!"indexOf".equals(methodName) &&
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/StringToCharPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/StringToCharPredicate.java
index 74d8801a9af2..f7aa3f9d6a79 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/StringToCharPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/chartostring/StringToCharPredicate.java
@@ -21,6 +21,8 @@ import com.intellij.util.ArrayUtil;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NonNls;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
class StringToCharPredicate implements PsiElementPredicate {
public boolean satisfiedBy(PsiElement element) {
@@ -34,7 +36,7 @@ class StringToCharPredicate implements PsiElementPredicate {
return false;
}
final String typeText = type.getCanonicalText();
- if (!"java.lang.String".equals(typeText)) {
+ if (!JAVA_LANG_STRING.equals(typeText)) {
return false;
}
final String value = (String)expression.getValue();
@@ -54,7 +56,7 @@ class StringToCharPredicate implements PsiElementPredicate {
return false;
}
final String parentTypeText = parentType.getCanonicalText();
- if (!"java.lang.String".equals(parentTypeText)) {
+ if (!JAVA_LANG_STRING.equals(parentTypeText)) {
return false;
}
if (parentExpression.getOperationTokenType() != JavaTokenType.PLUS) {
@@ -65,14 +67,14 @@ class StringToCharPredicate implements PsiElementPredicate {
if (index > 0) {
for (int i = 0; i < index && i < operands.length; i++) {
final PsiType type = operands[i].getType();
- if (type != null && type.equalsToText("java.lang.String")) {
+ if (type != null && type.equalsToText(JAVA_LANG_STRING)) {
return true;
}
}
}
else if (index == 0) {
final PsiType type = operands[index + 1].getType();
- return type != null && type.equalsToText("java.lang.String");
+ return type != null && type.equalsToText(JAVA_LANG_STRING);
}
return false;
}
@@ -88,7 +90,7 @@ class StringToCharPredicate implements PsiElementPredicate {
return false;
}
final String parentTypeText = parentType.getCanonicalText();
- return "java.lang.String".equals(parentTypeText);
+ return JAVA_LANG_STRING.equals(parentTypeText);
}
if (parent instanceof PsiExpressionList) {
final PsiElement grandParent = parent.getParent();
@@ -125,7 +127,7 @@ class StringToCharPredicate implements PsiElementPredicate {
final PsiElement method = methodExpression.resolve();
return method != null;
}
- else if ("java.lang.String".equals(className)) {
+ else if (JAVA_LANG_STRING.equals(className)) {
@NonNls final String methodName =
methodExpression.getReferenceName();
if (!"indexOf".equals(methodName) &&
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java
index 3f4fd9083b32..e903663fac2d 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java
@@ -26,6 +26,8 @@ import org.jetbrains.annotations.NotNull;
import java.awt.datatransfer.StringSelection;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class CopyConcatenatedStringToClipboardIntention extends Intention {
@Override
@@ -50,7 +52,7 @@ public class CopyConcatenatedStringToClipboardIntention extends Intention {
return;
}
final PsiType type = concatenationExpression.getType();
- if (type == null || !type.equalsToText("java.lang.String")) {
+ if (type == null || !type.equalsToText(JAVA_LANG_STRING)) {
return;
}
final StringBuilder text = buildConcatenationText(concatenationExpression, new StringBuilder());
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java
index dc276341d813..a70489b7c8a7 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java
@@ -21,6 +21,8 @@ import com.intellij.psi.util.PsiUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
class ConstantExpressionPredicate implements PsiElementPredicate {
public boolean satisfiedBy(PsiElement element) {
@@ -32,7 +34,7 @@ class ConstantExpressionPredicate implements PsiElementPredicate {
}
final PsiPolyadicExpression expression = (PsiPolyadicExpression)element;
final PsiType expressionType = expression.getType();
- if (expressionType == null || expressionType.equalsToText("java.lang.String")) {
+ if (expressionType == null || expressionType.equalsToText(JAVA_LANG_STRING)) {
// intention disabled for string concatenations because of performance issues on
// relatively common large string expressions.
return false;
@@ -43,7 +45,7 @@ class ConstantExpressionPredicate implements PsiElementPredicate {
return false;
}
final PsiType type = operand.getType();
- if (type == null || type.equalsToText("java.lang.String")) {
+ if (type == null || type.equalsToText(JAVA_LANG_STRING)) {
return false;
}
}
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java
index fc94093dec35..352f6fe6cc7e 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java
@@ -21,6 +21,8 @@ import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.Nullable;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
class ConstantSubexpressionPredicate implements PsiElementPredicate {
@Override
@@ -45,7 +47,7 @@ class ConstantSubexpressionPredicate implements PsiElementPredicate {
}
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent;
final PsiType type = polyadicExpression.getType();
- if (type == null || type.equalsToText("java.lang.String")) {
+ if (type == null || type.equalsToText(JAVA_LANG_STRING)) {
// handled by JoinConcatenatedStringLiteralsIntention
return false;
}
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ConvertToNestedIfIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ConvertToNestedIfIntention.java
index c73febe194fd..aadbef9b2c60 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ConvertToNestedIfIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/trivialif/ConvertToNestedIfIntention.java
@@ -62,7 +62,7 @@ public class ConvertToNestedIfIntention extends Intention {
if (returnValue == null || ErrorUtil.containsDeepError(returnValue)) {
return;
}
- final String newStatementText = buildIf(returnValue, new StringBuilder()).toString();
+ final String newStatementText = buildIf(returnValue, true, new StringBuilder()).toString();
final Project project = returnStatement.getProject();
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiBlockStatement blockStatement = (PsiBlockStatement)elementFactory.createStatementFromText("{" + newStatementText + "}", returnStatement);
@@ -73,23 +73,23 @@ public class ConvertToNestedIfIntention extends Intention {
PsiReplacementUtil.replaceStatement(returnStatement, "return false;");
}
- private static StringBuilder buildIf(@Nullable PsiExpression expression, StringBuilder out) {
+ private static StringBuilder buildIf(@Nullable PsiExpression expression, boolean top, StringBuilder out) {
if (expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
final PsiExpression[] operands = polyadicExpression.getOperands();
final IElementType tokenType = polyadicExpression.getOperationTokenType();
if (JavaTokenType.ANDAND.equals(tokenType)) {
for (PsiExpression operand : operands) {
- buildIf(operand, out);
+ buildIf(operand, false, out);
}
- if (!StringUtil.endsWith(out, "return true;")) {
+ if (top && !StringUtil.endsWith(out, "return true;")) {
out.append("return true;");
}
return out;
}
- else if (JavaTokenType.OROR.equals(tokenType)) {
+ else if (top && JavaTokenType.OROR.equals(tokenType)) {
for (PsiExpression operand : operands) {
- buildIf(operand, out);
+ buildIf(operand, false, out);
if (!StringUtil.endsWith(out, "return true;")) {
out.append("return true;");
}
@@ -99,7 +99,7 @@ public class ConvertToNestedIfIntention extends Intention {
}
else if (expression instanceof PsiParenthesizedExpression) {
final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
- buildIf(parenthesizedExpression.getExpression(), out);
+ buildIf(parenthesizedExpression.getExpression(), top, out);
return out;
}
if (expression != null) {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntention.java
index 26ca6de593ed..d2ff97ae98ab 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntention.java
@@ -141,7 +141,8 @@ public class ReplaceLambdaWithAnonymousIntention extends Intention {
@Override
public boolean satisfiedBy(PsiElement element) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
- if (lambdaExpression != null && PsiTreeUtil.isAncestor(lambdaExpression.getParameterList(), element, false)) {
+ if (lambdaExpression != null && (element.getParent() == lambdaExpression && element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.ARROW ||
+ PsiTreeUtil.isAncestor(lambdaExpression.getParameterList(), element, false))) {
final PsiClass thisClass = PsiTreeUtil.getParentOfType(lambdaExpression, PsiClass.class, true);
if (thisClass == null || thisClass instanceof PsiAnonymousClass) {
final PsiElement body = lambdaExpression.getBody();
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside.java
new file mode 100644
index 000000000000..521db40592e9
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside.java
@@ -0,0 +1,7 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ boolean f(boolean a, boolean b, boolean c, boolean d) {
+ return a |<caret>| (b && c) || d;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside_after.java
new file mode 100644
index 000000000000..0f3ea890809f
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/OrStaircaseInside_after.java
@@ -0,0 +1,10 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ boolean f(boolean a, boolean b, boolean c, boolean d) {
+ if (a) return true;
+ if (b) if (c) return true;
+ if (d) return true;
+ return false;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside.java
new file mode 100644
index 000000000000..81b9b0f86333
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside.java
@@ -0,0 +1,7 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ boolean f(boolean a, boolean b, boolean c, boolean d) {
+ return a &<caret>& (b || c) && d;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside_after.java
new file mode 100644
index 000000000000..768a17905219
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithOrInside_after.java
@@ -0,0 +1,8 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ boolean f(boolean a, boolean b, boolean c, boolean d) {
+ if (a) if (b || c) if (d) return true;
+ return false;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis.java
new file mode 100644
index 000000000000..71c207f828b2
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis.java
@@ -0,0 +1,19 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ public static boolean foo(double a, double b, double c)
+ {
+ // the following return statement is converted by "Convert to multiple 'ifs'" (on the second &&) to the below, incorrect if-then-else
+ return (a > c && a < b) &<caret>& !bar1(a) && !bar2(a);
+ }
+
+ private static boolean bar1(double a)
+ {
+ return true;
+ }
+
+ private static boolean bar2(double a)
+ {
+ return true;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis_after.java
new file mode 100644
index 000000000000..e17ed504d460
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/trivialif/convert_to_nested_if/StaircaseWithParenthesis_after.java
@@ -0,0 +1,20 @@
+package com.siyeh.ipp.trivialif.convert_to_nested_if;
+
+public class X {
+ public static boolean foo(double a, double b, double c)
+ {
+ // the following return statement is converted by "Convert to multiple 'ifs'" (on the second &&) to the below, incorrect if-then-else
+ if (a > c) if (a < b) if (!bar1(a)) if (!bar2(a)) return true;
+ return false;
+ }
+
+ private static boolean bar1(double a)
+ {
+ return true;
+ }
+
+ private static boolean bar2(double a)
+ {
+ return true;
+ }
+}
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow.java
new file mode 100644
index 000000000000..950f3dbd84e4
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow.java
@@ -0,0 +1,7 @@
+class Test {
+ {
+ Runnable r = () <caret>-> {
+ System.out.println("");
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow_after.java
new file mode 100644
index 000000000000..3618fefef78a
--- /dev/null
+++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/SimpleRunnableOnArrow_after.java
@@ -0,0 +1,10 @@
+class Test {
+ {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ <selection>System.out.println("");</selection>
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ConvertToNestedIfIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ConvertToNestedIfIntentionTest.java
index 84b140376ff4..1515c61030f3 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ConvertToNestedIfIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/trivialif/ConvertToNestedIfIntentionTest.java
@@ -22,6 +22,9 @@ public class ConvertToNestedIfIntentionTest extends IPPTestCase {
public void testNested() { doTest(); }
public void testStaircase() { doTest(); }
+ public void testStaircaseWithParenthesis() { doTest(); }
+ public void testStaircaseWithOrInside() { doTest(); }
+ public void testOrStaircaseInside() { doTest(); }
public void testOneLevelStaircase() { assertIntentionNotAvailable(); }
public void testAndOrMixed() { doTest(); }
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
index 6f209415d468..f92138431b74 100644
--- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
+++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/types/ReplaceLambdaWithAnonymousIntentionTest.java
@@ -23,6 +23,10 @@ public class ReplaceLambdaWithAnonymousIntentionTest extends IPPTestCase {
doTest();
}
+ public void testSimpleRunnableOnArrow() {
+ doTest();
+ }
+
public void testWithSubstitution() {
doTest();
}
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java b/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java
index ba71d8568f0a..e27d23434fef 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,11 +20,12 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
-public abstract class AntConfiguration {
+public abstract class AntConfiguration extends SimpleModificationTracker {
private final Project myProject;
@NonNls public static final String ACTION_ID_PREFIX = "Ant_";
diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
index f758fe660202..01b880adc3dd 100644
--- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
+++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java
@@ -72,7 +72,7 @@ import java.util.*;
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/ant.xml", scheme = StorageScheme.DIRECTORY_BASED)
}
)
-public class AntConfigurationImpl extends AntConfigurationBase implements PersistentStateComponent<Element>, ModificationTracker {
+public class AntConfigurationImpl extends AntConfigurationBase implements PersistentStateComponent<Element> {
public static final ValueProperty<AntReference> DEFAULT_ANT = new ValueProperty<AntReference>("defaultAnt", AntReference.BUNDLED_ANT);
public static final ValueProperty<AntConfiguration> INSTANCE = new ValueProperty<AntConfiguration>("$instance", null);
@@ -118,7 +118,6 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
private final AntWorkspaceConfiguration myAntWorkspaceConfiguration;
private final StartupManager myStartupManager;
private boolean myInitializing;
- private volatile long myModificationCount = 0;
public AntConfigurationImpl(final Project project, final AntWorkspaceConfiguration antWorkspaceConfiguration, final DaemonCodeAnalyzer daemon) {
super(project);
@@ -232,7 +231,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
indicator.pushState();
try {
indicator.setText(title);
- myModificationCount++;
+ incModificationCount();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
try {
@@ -264,7 +263,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
}
public void removeBuildFile(final AntBuildFile file) {
- myModificationCount++;
+ incModificationCount();
removeBuildFileImpl(file);
updateRegisteredActions();
}
@@ -371,7 +370,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
}
public void updateBuildFile(final AntBuildFile buildFile) {
- myModificationCount++;
+ incModificationCount();
myEventDispatcher.getMulticaster().buildFileChanged(buildFile);
updateRegisteredActions();
}
@@ -398,10 +397,6 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis
return getModel(buildFile);
}
- public long getModificationCount() {
- return myModificationCount;
- }
-
private void readExternal(final Element parentNode) throws InvalidDataException {
myIsInitialized = Boolean.FALSE;
myAntWorkspaceConfiguration.loadFromProjectSettings(parentNode);
diff --git a/plugins/copyright/src/META-INF/java.xml b/plugins/copyright/src/META-INF/java.xml
index d4af28f67a1e..0412d933d6ab 100644
--- a/plugins/copyright/src/META-INF/java.xml
+++ b/plugins/copyright/src/META-INF/java.xml
@@ -4,5 +4,7 @@
<updater filetype="JSP" implementationClass="com.maddyhome.idea.copyright.psi.UpdateJspFileCopyright$UpdateJspCopyrightsProvider"/>
<updater filetype="JAVA" implementationClass="com.maddyhome.idea.copyright.psi.UpdateJavaFileCopyright$UpdateJavaCopyrightsProvider"/>
<updater filetype="SPI" implementationClass="com.maddyhome.idea.copyright.psi.UpdateSPIFileCopyright"/>
+
+ <variablesProvider filetype="JAVA" implementationClass="com.maddyhome.idea.copyright.pattern.JavaCopyrightVariablesProvider"/>
</extensions>
</idea-plugin>
diff --git a/plugins/copyright/src/META-INF/plugin.xml b/plugins/copyright/src/META-INF/plugin.xml
index bc3914316ed1..ea667615982f 100644
--- a/plugins/copyright/src/META-INF/plugin.xml
+++ b/plugins/copyright/src/META-INF/plugin.xml
@@ -36,6 +36,10 @@
<extensionPoint name="updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
<with attribute="implementationClass" implements="com.maddyhome.idea.copyright.psi.UpdateCopyrightsProvider"/>
</extensionPoint>
+ <extensionPoint name="variablesProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint">
+ <with attribute="implementationClass" implements="com.maddyhome.idea.copyright.pattern.CopyrightVariablesProvider"/>
+ </extensionPoint>
+
</extensionPoints>
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProvider.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProvider.java
new file mode 100644
index 000000000000..623e71eec613
--- /dev/null
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.maddyhome.idea.copyright.pattern;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+public abstract class CopyrightVariablesProvider {
+ public abstract void collectVariables(@NotNull Map<String, Object> context, Project project, Module module, @NotNull PsiFile file);
+}
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProviders.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProviders.java
new file mode 100644
index 000000000000..939601c2baea
--- /dev/null
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/CopyrightVariablesProviders.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.maddyhome.idea.copyright.pattern;
+
+import com.intellij.openapi.fileTypes.FileTypeExtension;
+
+public class CopyrightVariablesProviders extends FileTypeExtension<CopyrightVariablesProvider> {
+ public static CopyrightVariablesProviders INSTANCE = new CopyrightVariablesProviders();
+
+ private CopyrightVariablesProviders() {
+ super("com.intellij.copyright.variablesProvider");
+ }
+}
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/FileInfo.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/FileInfo.java
index f5cf378955ef..33b523e7dc5e 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/FileInfo.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/FileInfo.java
@@ -18,7 +18,6 @@ package com.maddyhome.idea.copyright.pattern;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiJavaFile;
public class FileInfo
{
@@ -39,26 +38,12 @@ public class FileInfo
public String getClassName()
{
- if (file instanceof PsiJavaFile)
- {
- return ((PsiJavaFile)file).getClasses()[0].getName();
- }
- else
- {
- return getFileName();
- }
+ return getFileName();
}
public String getQualifiedClassName()
{
- if (file instanceof PsiJavaFile)
- {
- return ((PsiJavaFile)file).getClasses()[0].getQualifiedName();
- }
- else
- {
- return getPathName();
- }
+ return getPathName();
}
public DateInfo getLastModified()
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/JavaCopyrightVariablesProvider.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/JavaCopyrightVariablesProvider.java
new file mode 100644
index 000000000000..3d76074a3935
--- /dev/null
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/JavaCopyrightVariablesProvider.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.maddyhome.idea.copyright.pattern;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClassOwner;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiJavaFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+public class JavaCopyrightVariablesProvider extends CopyrightVariablesProvider {
+ @Override
+ public void collectVariables(@NotNull Map<String, Object> context, Project project, Module module, @NotNull final PsiFile file) {
+ if (file instanceof PsiClassOwner) {
+ final FileInfo info = new FileInfo(file) {
+ @Override
+ public String getClassName() {
+ if (file instanceof PsiJavaFile) {
+ return ((PsiJavaFile)file).getClasses()[0].getName();
+ }
+ else {
+ return super.getClassName();
+ }
+ }
+
+ @Override
+ public String getQualifiedClassName() {
+ if (file instanceof PsiJavaFile) {
+ return ((PsiJavaFile)file).getClasses()[0].getQualifiedName();
+ } else {
+ return super.getQualifiedClassName();
+ }
+ }
+ };
+ context.put("file", info);
+ }
+ }
+}
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java
index 2ecc629eb135..7284d0d989f3 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/pattern/VelocityHelper.java
@@ -20,7 +20,9 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilCore;
import com.maddyhome.idea.copyright.CopyrightManager;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.VelocityContext;
@@ -29,6 +31,8 @@ import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.log.SimpleLog4JLogSystem;
import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
public class VelocityHelper
{
@@ -43,7 +47,22 @@ public class VelocityHelper
if (module != null) vc.put("module", new ModuleInfo(module));
vc.put("username", System.getProperty("user.name"));
- try
+ if (file != null) {
+ final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(file);
+ if (virtualFile != null) {
+ final CopyrightVariablesProvider variablesProvider = CopyrightVariablesProviders.INSTANCE.forFileType(virtualFile.getFileType());
+ if (variablesProvider != null) {
+ final Map<String, Object> context = new HashMap<String, Object>();
+ variablesProvider.collectVariables(context, project, module, file);
+ for (Map.Entry<String, Object> entry : context.entrySet()) {
+ vc.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+
+
+ try
{
StringWriter sw = new StringWriter();
boolean stripLineBreak = false;
diff --git a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProjectConfigurable.java b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProjectConfigurable.java
index e3af27e387fa..4bf8d7b5f235 100644
--- a/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProjectConfigurable.java
+++ b/plugins/copyright/src/com/maddyhome/idea/copyright/ui/CopyrightProjectConfigurable.java
@@ -81,10 +81,6 @@ public class CopyrightProjectConfigurable extends SearchableConfigurable.Parent.
return true;
}
- public boolean isVisible() {
- return true;
- }
-
@NotNull
public String getId() {
return "copyright";
diff --git a/plugins/coverage-common/coverage-common.iml b/plugins/coverage-common/coverage-common.iml
new file mode 100644
index 000000000000..389fc6b1bd7e
--- /dev/null
+++ b/plugins/coverage-common/coverage-common.iml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="platform-api" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="util" />
+ <orderEntry type="module" module-name="extensions" />
+ <orderEntry type="module" module-name="annotations" />
+ <orderEntry type="library" exported="" name="asm5" level="project" />
+ <orderEntry type="module-library" exported="">
+ <library name="Coverage">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/coverage-agent.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/instrumenter.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/coverage-util.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$MODULE_DIR$/lib/coverage-src.zip!/" />
+ </SOURCES>
+ </library>
+ </orderEntry>
+ <orderEntry type="library" exported="" name="Trove4j" level="project" />
+ <orderEntry type="module" module-name="testRunner" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="lvcs-api" />
+ </component>
+</module>
+
diff --git a/plugins/coverage-common/lib/coverage-agent.jar b/plugins/coverage-common/lib/coverage-agent.jar
new file mode 100644
index 000000000000..2f403fef94ba
--- /dev/null
+++ b/plugins/coverage-common/lib/coverage-agent.jar
Binary files differ
diff --git a/plugins/coverage-common/lib/coverage-src.zip b/plugins/coverage-common/lib/coverage-src.zip
new file mode 100644
index 000000000000..c094a3a80b9d
--- /dev/null
+++ b/plugins/coverage-common/lib/coverage-src.zip
Binary files differ
diff --git a/plugins/coverage-common/lib/coverage-util.jar b/plugins/coverage-common/lib/coverage-util.jar
new file mode 100644
index 000000000000..dbfe4a3786ec
--- /dev/null
+++ b/plugins/coverage-common/lib/coverage-util.jar
Binary files differ
diff --git a/plugins/coverage-common/lib/instrumenter.jar b/plugins/coverage-common/lib/instrumenter.jar
new file mode 100644
index 000000000000..54953f575420
--- /dev/null
+++ b/plugins/coverage-common/lib/instrumenter.jar
Binary files differ
diff --git a/plugins/coverage-common/src/META-INF/coverage-common-plugin.xml b/plugins/coverage-common/src/META-INF/coverage-common-plugin.xml
new file mode 100644
index 000000000000..dcc83cecb41c
--- /dev/null
+++ b/plugins/coverage-common/src/META-INF/coverage-common-plugin.xml
@@ -0,0 +1,26 @@
+<idea-plugin version="2">
+ <extensionPoints>
+ <extensionPoint qualifiedName="com.intellij.coverageRunner" interface="com.intellij.coverage.CoverageRunner"/>
+ <extensionPoint qualifiedName="com.intellij.coverageEngine" interface="com.intellij.coverage.CoverageEngine"/>
+ <extensionPoint qualifiedName="com.intellij.coverageOptions" interface="com.intellij.coverage.CoverageOptions" area="IDEA_PROJECT"/>
+ </extensionPoints>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <testActionProvider implementation="com.intellij.coverage.actions.TrackCoverageActionProvider"/>
+ <projectViewNodeDecorator implementation="com.intellij.coverage.CoverageProjectViewDirectoryNodeDecorator"/>
+ <projectConfigurable instance="com.intellij.coverage.CoverageOptionsConfigurable" id="coverage" displayName="Coverage" />
+ <projectService serviceImplementation="com.intellij.coverage.CoverageOptionsProvider"/>
+ <projectService serviceImplementation="com.intellij.coverage.view.CoverageViewManager"/>
+ <executor implementation="com.intellij.coverage.CoverageExecutor" />
+ </extensions>
+ <actions>
+ <group id="CoverageMenu">
+ <action id="SwitchCoverage" class="com.intellij.coverage.actions.SwitchCoverageSuiteAction" text="Show Co_verage Data..."/>
+ <action id="GenerateCoverageReport" class="com.intellij.coverage.actions.GenerateCoverageReportAction"
+ text="_Generate Coverage Report..." icon="AllIcons.Actions.Export"/>
+ <action id="HideCoverage" class="com.intellij.coverage.actions.HideCoverageInfoAction"/>
+ <separator/>
+ </group>
+ </actions>
+
+</idea-plugin>
diff --git a/plugins/coverage-common/src/com/intellij/coverage/AbstractCoverageProvejctViewNodeDecorator.java b/plugins/coverage-common/src/com/intellij/coverage/AbstractCoverageProvejctViewNodeDecorator.java
new file mode 100644
index 000000000000..0231fb3d54b0
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/AbstractCoverageProvejctViewNodeDecorator.java
@@ -0,0 +1,26 @@
+package com.intellij.coverage;
+
+import com.intellij.ide.projectView.ProjectViewNodeDecorator;
+import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.SimpleTextAttributes;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public abstract class AbstractCoverageProvejctViewNodeDecorator implements ProjectViewNodeDecorator {
+ private final CoverageDataManager myCoverageDataManager;
+
+ public AbstractCoverageProvejctViewNodeDecorator(final CoverageDataManager coverageDataManager) {
+ myCoverageDataManager = coverageDataManager;
+ }
+
+ protected CoverageDataManager getCoverageDataManager() {
+ return myCoverageDataManager;
+ }
+
+ protected static void appendCoverageInfo(ColoredTreeCellRenderer cellRenderer, String coverageInfo) {
+ if (coverageInfo != null) {
+ cellRenderer.append(" (" + coverageInfo + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageAnnotator.java b/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageAnnotator.java
new file mode 100644
index 000000000000..08d99d792e06
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageAnnotator.java
@@ -0,0 +1,63 @@
+package com.intellij.coverage;
+
+import com.intellij.coverage.view.CoverageView;
+import com.intellij.coverage.view.CoverageViewManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public abstract class BaseCoverageAnnotator implements CoverageAnnotator {
+
+ private final Project myProject;
+
+ @Nullable
+ protected abstract Runnable createRenewRequest(@NotNull final CoverageSuitesBundle suite, @NotNull final CoverageDataManager dataManager);
+
+ public BaseCoverageAnnotator(final Project project) {
+ myProject = project;
+ }
+
+ public void onSuiteChosen(CoverageSuitesBundle newSuite) {
+ }
+
+ public void renewCoverageData(@NotNull final CoverageSuitesBundle suite, @NotNull final CoverageDataManager dataManager) {
+ final Runnable request = createRenewRequest(suite, dataManager);
+ if (request != null) {
+ if (myProject.isDisposed()) return;
+ ProgressManager.getInstance().run(new Task.Backgroundable(myProject, "Loading coverage data...", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ request.run();
+ }
+
+ @Override
+ public void onSuccess() {
+ final CoverageView coverageView = CoverageViewManager.getInstance(myProject).getToolwindow(suite);
+ if (coverageView != null) {
+ coverageView.updateParentTitle();
+ }
+ }
+ });
+ }
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public static class FileCoverageInfo {
+ public int totalLineCount;
+ public int coveredLineCount;
+ }
+
+ public static class DirCoverageInfo extends FileCoverageInfo {
+ public int totalFilesCount;
+ public int coveredFilesCount;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageSuite.java b/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageSuite.java
new file mode 100644
index 000000000000..2b612f988049
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/BaseCoverageSuite.java
@@ -0,0 +1,277 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.rt.coverage.data.ProjectData;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.lang.ref.SoftReference;
+
+/**
+ * @author ven
+ */
+public abstract class BaseCoverageSuite implements CoverageSuite, JDOMExternalizable {
+ private static final Logger LOG = Logger.getInstance(BaseCoverageSuite.class.getName());
+
+ @NonNls
+ private static final String FILE_PATH = "FILE_PATH";
+
+ @NonNls
+ private static final String SOURCE_PROVIDER = "SOURCE_PROVIDER";
+
+ @NonNls
+ private static final String MODIFIED_STAMP = "MODIFIED";
+
+ @NonNls
+ private static final String NAME_ATTRIBUTE = "NAME";
+
+ @NonNls
+ private static final String COVERAGE_RUNNER = "RUNNER";
+
+ @NonNls
+ private static final String COVERAGE_BY_TEST_ENABLED_ATTRIBUTE_NAME = "COVERAGE_BY_TEST_ENABLED";
+
+ @NonNls
+ private static final String TRACING_ENABLED_ATTRIBUTE_NAME = "COVERAGE_TRACING_ENABLED";
+
+ private SoftReference<ProjectData> myCoverageData = new SoftReference<ProjectData>(null);
+
+ private String myName;
+ private long myLastCoverageTimeStamp;
+ private boolean myCoverageByTestEnabled;
+ private CoverageRunner myRunner;
+ private CoverageFileProvider myCoverageDataFileProvider;
+ private boolean myTrackTestFolders;
+ private boolean myTracingEnabled;
+ private Project myProject;
+
+ private RunConfigurationBase myConfiguration;
+
+ protected BaseCoverageSuite() {
+ }
+
+ public BaseCoverageSuite(final String name,
+ @Nullable final CoverageFileProvider fileProvider,
+ final long lastCoverageTimeStamp,
+ final boolean coverageByTestEnabled,
+ final boolean tracingEnabled,
+ final boolean trackTestFolders,
+ final CoverageRunner coverageRunner) {
+ this(name, fileProvider, lastCoverageTimeStamp, coverageByTestEnabled, tracingEnabled, trackTestFolders, coverageRunner, null);
+ }
+
+ public BaseCoverageSuite(final String name,
+ @Nullable final CoverageFileProvider fileProvider,
+ final long lastCoverageTimeStamp,
+ final boolean coverageByTestEnabled,
+ final boolean tracingEnabled,
+ final boolean trackTestFolders,
+ final CoverageRunner coverageRunner,
+ Project project) {
+ myCoverageDataFileProvider = fileProvider;
+ myName = name;
+ myLastCoverageTimeStamp = lastCoverageTimeStamp;
+ myCoverageByTestEnabled = coverageByTestEnabled;
+ myTrackTestFolders = trackTestFolders;
+ myTracingEnabled = tracingEnabled;
+ myRunner = coverageRunner;
+ myProject = project;
+ }
+
+ @Nullable
+ public static CoverageRunner readRunnerAttribute(Element element) {
+ final String runner = element.getAttributeValue(COVERAGE_RUNNER);
+ if (runner != null) {
+ for (CoverageRunner coverageRunner : Extensions.getExtensions(CoverageRunner.EP_NAME)) {
+ if (Comparing.strEqual(coverageRunner.getId(), runner)) {
+ return coverageRunner;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static CoverageFileProvider readDataFileProviderAttribute(Element element) {
+ final String sourceProvider = element.getAttributeValue(SOURCE_PROVIDER);
+ final String relativePath = FileUtil.toSystemDependentName(element.getAttributeValue(FILE_PATH));
+ final File file = new File(relativePath);
+ return new DefaultCoverageFileProvider(file.exists() ? file
+ : new File(PathManager.getSystemPath(), relativePath),
+ sourceProvider != null ? sourceProvider
+ : DefaultCoverageFileProvider.class.getName());
+ }
+
+ public boolean isValid() {
+ return myCoverageDataFileProvider.isValid();
+ }
+
+ @NotNull
+ public String getCoverageDataFileName() {
+ return myCoverageDataFileProvider.getCoverageDataFilePath();
+ }
+
+ public
+ @NotNull
+ CoverageFileProvider getCoverageDataFileProvider() {
+ return myCoverageDataFileProvider;
+ }
+
+ public String getPresentableName() {
+ return myName;
+ }
+
+ public long getLastCoverageTimeStamp() {
+ return myLastCoverageTimeStamp;
+ }
+
+ public boolean isTrackTestFolders() {
+ return myTrackTestFolders;
+ }
+
+ public boolean isTracingEnabled() {
+ return myTracingEnabled;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ myCoverageDataFileProvider = readDataFileProviderAttribute(element);
+
+ // name
+ myName = element.getAttributeValue(NAME_ATTRIBUTE);
+ if (myName == null) myName = generateName();
+
+ // tc
+ myLastCoverageTimeStamp = Long.parseLong(element.getAttributeValue(MODIFIED_STAMP));
+
+ // runner
+ myRunner = readRunnerAttribute(element);
+
+ // coverage per test
+ final String collectedLineInfo = element.getAttributeValue(COVERAGE_BY_TEST_ENABLED_ATTRIBUTE_NAME);
+ myCoverageByTestEnabled = collectedLineInfo != null && Boolean.valueOf(collectedLineInfo).booleanValue();
+
+
+ // tracing
+ final String tracingEnabled = element.getAttributeValue(TRACING_ENABLED_ATTRIBUTE_NAME);
+ myTracingEnabled = tracingEnabled != null && Boolean.valueOf(tracingEnabled).booleanValue();
+ }
+
+ public void writeExternal(final Element element) throws WriteExternalException {
+ final String fileName =
+ FileUtil.getRelativePath(new File(PathManager.getSystemPath()), new File(myCoverageDataFileProvider.getCoverageDataFilePath()));
+ element.setAttribute(FILE_PATH, fileName != null ? FileUtil.toSystemIndependentName(fileName) : myCoverageDataFileProvider.getCoverageDataFilePath());
+ element.setAttribute(NAME_ATTRIBUTE, myName);
+ element.setAttribute(MODIFIED_STAMP, String.valueOf(myLastCoverageTimeStamp));
+ element.setAttribute(SOURCE_PROVIDER, myCoverageDataFileProvider instanceof DefaultCoverageFileProvider
+ ? ((DefaultCoverageFileProvider)myCoverageDataFileProvider).getSourceProvider()
+ : myCoverageDataFileProvider.getClass().getName());
+ // runner
+ if (getRunner() != null) {
+ element.setAttribute(COVERAGE_RUNNER, myRunner.getId());
+ }
+
+ // cover by test
+ element.setAttribute(COVERAGE_BY_TEST_ENABLED_ATTRIBUTE_NAME, String.valueOf(myCoverageByTestEnabled));
+
+ // tracing
+ element.setAttribute(TRACING_ENABLED_ATTRIBUTE_NAME, String.valueOf(myTracingEnabled));
+ }
+
+ public void setCoverageData(final ProjectData projectData) {
+ myCoverageData = new SoftReference<ProjectData>(projectData);
+ }
+
+ public ProjectData getCoverageData() {
+ return myCoverageData.get();
+ }
+
+ public void restoreCoverageData() {
+ setCoverageData(loadProjectInfo());
+ }
+
+ public boolean isCoverageByTestApplicable() {
+ return getRunner().isCoverageByTestApplicable();
+ }
+
+ public boolean isCoverageByTestEnabled() {
+ return myCoverageByTestEnabled;
+ }
+
+ @Nullable
+ public ProjectData getCoverageData(final CoverageDataManager coverageDataManager) {
+ final ProjectData data = getCoverageData();
+ if (data != null) {
+ return data;
+ }
+ ProjectData map = loadProjectInfo();
+ setCoverageData(map);
+ return map;
+ }
+
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final String thisName = myCoverageDataFileProvider.getCoverageDataFilePath();
+ final String thatName = ((BaseCoverageSuite)o).myCoverageDataFileProvider.getCoverageDataFilePath();
+ return thisName.equals(thatName);
+ }
+
+ public int hashCode() {
+ return myCoverageDataFileProvider.getCoverageDataFilePath().hashCode();
+ }
+
+ @Nullable
+ protected ProjectData loadProjectInfo() {
+ String sessionDataFileName = getCoverageDataFileName();
+ File sessionDataFile = new File(sessionDataFileName);
+ if (!sessionDataFile.exists()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Nonexistent file given +" + sessionDataFileName);
+ }
+ return null;
+ }
+ return myRunner.loadCoverageData(sessionDataFile, this);
+ }
+
+ public CoverageRunner getRunner() {
+ return myRunner;
+ }
+
+ protected void setRunner(CoverageRunner runner) {
+ myRunner = runner;
+ }
+
+ private String generateName() {
+ String text = myCoverageDataFileProvider.getCoverageDataFilePath();
+ int i = text.lastIndexOf(File.separatorChar);
+ if (i >= 0) text = text.substring(i + 1);
+ i = text.lastIndexOf('.');
+ if (i >= 0) text = text.substring(0, i);
+ return text;
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public void setConfiguration(RunConfigurationBase configuration) {
+ myConfiguration = configuration;
+ }
+
+ @Nullable
+ public RunConfigurationBase getConfiguration() {
+ return myConfiguration;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageAnnotator.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageAnnotator.java
new file mode 100644
index 000000000000..ebec547c9275
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageAnnotator.java
@@ -0,0 +1,35 @@
+package com.intellij.coverage;
+
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public interface CoverageAnnotator {
+ /**
+ *
+ * @param directory {@link com.intellij.psi.PsiDirectory} to obtain coverage information for
+ * @param manager
+ * @return human-readable coverage information
+ */
+ @Nullable
+ String getDirCoverageInformationString(@NotNull PsiDirectory directory, @NotNull CoverageSuitesBundle currentSuite,
+ @NotNull CoverageDataManager manager);
+
+ /**
+ *
+ * @param file {@link com.intellij.psi.PsiFile} to obtain coverage information for
+ * @param manager
+ * @return human-readable coverage information
+ */
+ @Nullable
+ String getFileCoverageInformationString(@NotNull PsiFile file, @NotNull CoverageSuitesBundle currentSuite,
+ @NotNull CoverageDataManager manager);
+
+ void onSuiteChosen(@Nullable CoverageSuitesBundle newSuite);
+
+ void renewCoverageData(@NotNull CoverageSuitesBundle suite, @NotNull CoverageDataManager dataManager);
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManager.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManager.java
new file mode 100644
index 000000000000..23e1243f5f59
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManager.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.JDOMExternalizable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public abstract class CoverageDataManager implements ProjectComponent, JDOMExternalizable {
+
+ public static CoverageDataManager getInstance(Project project) {
+ return project.getComponent(CoverageDataManager.class);
+ }
+
+ /**
+ * TeamCity compatibility
+ *
+ * List coverage suite for presentation from IDEA
+ *
+ * @param name presentable name of a suite
+ * @param fileProvider
+ * @param filters configured filters for this suite
+ * @param lastCoverageTimeStamp when this coverage data was gathered
+ * @param suiteToMergeWith null remove coverage pack from prev run and get from new
+ * @param coverageRunner
+ * @param collectLineInfo
+ * @param tracingEnabled
+ */
+ public abstract CoverageSuite addCoverageSuite(String name,
+ CoverageFileProvider fileProvider,
+ String[] filters,
+ long lastCoverageTimeStamp,
+ @Nullable String suiteToMergeWith, final CoverageRunner coverageRunner,
+ final boolean collectLineInfo, final boolean tracingEnabled);
+
+ public abstract CoverageSuite addExternalCoverageSuite(String selectedFileName,
+ long timeStamp,
+ CoverageRunner coverageRunner, CoverageFileProvider fileProvider);
+
+
+ public abstract CoverageSuite addCoverageSuite(CoverageEnabledConfiguration config);
+ /**
+ * TeamCity 3.1.1 compatibility
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ @Deprecated
+ public CoverageSuite addCoverageSuite(String name,
+ CoverageFileProvider fileProvider,
+ String[] filters,
+ long lastCoverageTimeStamp,
+ boolean suiteToMergeWith) {
+ return addCoverageSuite(name, fileProvider, filters, lastCoverageTimeStamp, null, null, false, false);
+ }
+
+
+ /**
+ * @return registered suites
+ */
+ public abstract CoverageSuite[] getSuites();
+
+ /**
+ * @return currently active suite
+ */
+ public abstract CoverageSuitesBundle getCurrentSuitesBundle();
+
+ @Deprecated
+ @Nullable
+ public CoverageSuite getCurrentSuite() {
+ final CoverageSuitesBundle bundle = getCurrentSuitesBundle();
+ return bundle != null ? bundle.getSuites()[0] : null;
+ }
+
+ /**
+ * Choose active suite. Calling this method triggers updating the presentations in project view, editors etc.
+ * @param suite coverage suite to choose. <b>null</b> means no coverage information should be presented
+ */
+ public abstract void chooseSuitesBundle(@Nullable CoverageSuitesBundle suite);
+
+ @Deprecated
+ public void chooseSuite(CoverageSuite suite) {
+ chooseSuitesBundle(suite != null ? new CoverageSuitesBundle(suite) : null);
+ }
+
+ public abstract void coverageGathered(@NotNull CoverageSuite suite);
+
+ /**
+ * Remove suite
+ * @param suite coverage suite to remove
+ */
+ public abstract void removeCoverageSuite(CoverageSuite suite);
+
+ /**
+ * runs computation in read action, blocking project close till action has been run,
+ * and doing nothing in case projectClosing() event has been already broadcasted.
+ * Note that actions must not be long running not to cause significant pauses on project close.
+ * @param computation {@link com.intellij.openapi.util.Computable to be run}
+ * @return result of the computation or null if the project is already closing.
+ */
+ @Nullable
+ public abstract <T> T doInReadActionIfProjectOpen(Computable<T> computation);
+
+ public abstract boolean isSubCoverageActive();
+
+ public abstract void selectSubCoverage(@NotNull final CoverageSuitesBundle suite, final List<String> methodNames);
+
+ public abstract void restoreMergedCoverage(@NotNull final CoverageSuitesBundle suite);
+
+ public abstract void addSuiteListener(CoverageSuiteListener listener, Disposable parentDisposable);
+
+ public abstract void triggerPresentationUpdate();
+
+ /**
+ * This method attach process listener to process handler. Listener will load coverage information after process termination
+ * @param handler
+ * @param configuration
+ * @param runnerSettings
+ */
+ public abstract void attachToProcess(@NotNull final ProcessHandler handler,
+ @NotNull final RunConfigurationBase configuration, RunnerSettings runnerSettings);
+
+ public abstract void processGatheredCoverage(@NotNull RunConfigurationBase configuration, RunnerSettings runnerSettings);
+
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManagerImpl.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManagerImpl.java
new file mode 100644
index 000000000000..2db8835ff8b2
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageDataManagerImpl.java
@@ -0,0 +1,711 @@
+package com.intellij.coverage;
+
+import com.intellij.CommonBundle;
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.coverage.view.CoverageViewManager;
+import com.intellij.coverage.view.CoverageViewSuiteListener;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.process.ProcessAdapter;
+import com.intellij.execution.process.ProcessEvent;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.colors.EditorColorsAdapter;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.event.EditorFactoryEvent;
+import com.intellij.openapi.editor.event.EditorFactoryListener;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.Alarm;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.ui.UIUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author ven
+ */
+public class CoverageDataManagerImpl extends CoverageDataManager {
+ private static final String REPLACE_ACTIVE_SUITES = "&Replace active suites";
+ private static final String ADD_TO_ACTIVE_SUITES = "&Add to active suites";
+ private static final String DO_NOT_APPLY_COLLECTED_COVERAGE = "Do not apply &collected coverage";
+
+ private final List<CoverageSuiteListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private static final Logger LOG = Logger.getInstance("#" + CoverageDataManagerImpl.class.getName());
+ @NonNls
+ private static final String SUITE = "SUITE";
+
+ private final Project myProject;
+ private final Set<CoverageSuite> myCoverageSuites = new HashSet<CoverageSuite>();
+ private boolean myIsProjectClosing = false;
+
+ private final Object myLock = new Object();
+ private boolean mySubCoverageIsActive;
+
+ public CoverageSuitesBundle getCurrentSuitesBundle() {
+ return myCurrentSuitesBundle;
+ }
+
+ private CoverageSuitesBundle myCurrentSuitesBundle;
+
+ private final Object ANNOTATORS_LOCK = new Object();
+ private final Map<Editor, SrcFileAnnotator> myAnnotators = new HashMap<Editor, SrcFileAnnotator>();
+
+ public CoverageDataManagerImpl(final Project project) {
+ myProject = project;
+ EditorColorsManager.getInstance().addEditorColorsListener(new EditorColorsAdapter() {
+ @Override
+ public void globalSchemeChange(EditorColorsScheme scheme) {
+ chooseSuitesBundle(myCurrentSuitesBundle);
+ }
+ }, project);
+ addSuiteListener(new CoverageViewSuiteListener(this, myProject), myProject);
+ }
+
+
+ @NotNull @NonNls
+ public String getComponentName() {
+ return "CoverageDataManager";
+ }
+
+ public void initComponent() {
+ }
+
+ public void disposeComponent() {
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ //noinspection unchecked
+ for (Element suiteElement : element.getChildren(SUITE)) {
+ final CoverageRunner coverageRunner = BaseCoverageSuite.readRunnerAttribute(suiteElement);
+ // skip unknown runners
+ if (coverageRunner == null) {
+ // collect gc
+ final CoverageFileProvider fileProvider = BaseCoverageSuite.readDataFileProviderAttribute(suiteElement);
+ if (fileProvider.isValid()) {
+ //deleteCachedCoverage(fileProvider.getCoverageDataFilePath());
+ }
+ continue;
+ }
+
+ CoverageSuite suite = null;
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (coverageRunner.acceptsCoverageEngine(engine)) {
+ suite = engine.createEmptyCoverageSuite(coverageRunner);
+ if (suite != null) {
+ break;
+ }
+ }
+ }
+ if (suite != null) {
+ try {
+ suite.readExternal(suiteElement);
+ myCoverageSuites.add(suite);
+ }
+ catch (NumberFormatException e) {
+ //try next suite
+ }
+ }
+ }
+ }
+
+ public void writeExternal(final Element element) throws WriteExternalException {
+ for (CoverageSuite coverageSuite : myCoverageSuites) {
+ final Element suiteElement = new Element(SUITE);
+ element.addContent(suiteElement);
+ coverageSuite.writeExternal(suiteElement);
+ }
+ }
+
+ public CoverageSuite addCoverageSuite(final String name, final CoverageFileProvider fileProvider, final String[] filters, final long lastCoverageTimeStamp,
+ @Nullable final String suiteToMergeWith,
+ final CoverageRunner coverageRunner,
+ final boolean collectLineInfo,
+ final boolean tracingEnabled) {
+ final CoverageSuite suite = createCoverageSuite(coverageRunner, name, fileProvider, filters, lastCoverageTimeStamp, suiteToMergeWith, collectLineInfo, tracingEnabled);
+ if (suiteToMergeWith == null || !name.equals(suiteToMergeWith)) {
+ removeCoverageSuite(suite);
+ }
+ myCoverageSuites.remove(suite); // remove previous instance
+ myCoverageSuites.add(suite); // add new instance
+ return suite;
+ }
+
+ @Override
+ public CoverageSuite addExternalCoverageSuite(String selectedFileName,
+ long timeStamp,
+ CoverageRunner coverageRunner,
+ CoverageFileProvider fileProvider) {
+ final CoverageSuite suite = createCoverageSuite(coverageRunner, selectedFileName, fileProvider, ArrayUtil.EMPTY_STRING_ARRAY, timeStamp, null, false, false);
+ myCoverageSuites.add(suite);
+ return suite;
+ }
+
+ @Override
+ public CoverageSuite addCoverageSuite(final CoverageEnabledConfiguration config) {
+ final String name = config.getName() + " Coverage Results";
+ final String covFilePath = config.getCoverageFilePath();
+ assert covFilePath != null; // Shouldn't be null here!
+
+ final CoverageRunner coverageRunner = config.getCoverageRunner();
+ LOG.assertTrue(coverageRunner != null, "Coverage runner id = " + config.getRunnerId());
+
+ final DefaultCoverageFileProvider fileProvider = new DefaultCoverageFileProvider(new File(covFilePath));
+ final CoverageSuite suite = createCoverageSuite(config, name, coverageRunner, fileProvider);
+
+ // remove previous instance
+ removeCoverageSuite(suite);
+
+ // add new instance
+ myCoverageSuites.add(suite);
+ return suite;
+ }
+
+ public void removeCoverageSuite(final CoverageSuite suite) {
+ final String fileName = suite.getCoverageDataFileName();
+
+ boolean deleteTraces = suite.isTracingEnabled();
+ if (!FileUtil.isAncestor(PathManager.getSystemPath(), fileName, false)) {
+ String message = "Would you like to delete file \'" + fileName + "\' ";
+ if (deleteTraces) {
+ message += "and traces directory \'" + FileUtil.getNameWithoutExtension(new File(fileName)) + "\' ";
+ }
+ message += "on disk?";
+ if (Messages.showYesNoDialog(myProject, message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()) == Messages.YES) {
+ deleteCachedCoverage(fileName, deleteTraces);
+ }
+ } else {
+ deleteCachedCoverage(fileName, deleteTraces);
+ }
+
+ myCoverageSuites.remove(suite);
+ if (myCurrentSuitesBundle != null && myCurrentSuitesBundle.contains(suite)) {
+ CoverageSuite[] suites = myCurrentSuitesBundle.getSuites();
+ suites = ArrayUtil.remove(suites, suite);
+ chooseSuitesBundle(suites.length > 0 ? new CoverageSuitesBundle(suites) : null);
+ }
+ }
+
+ private void deleteCachedCoverage(String coverageDataFileName, boolean deleteTraces) {
+ FileUtil.delete(new File(coverageDataFileName));
+ if (deleteTraces) {
+ FileUtil.delete(getTracesDirectory(coverageDataFileName));
+ }
+ }
+
+ public CoverageSuite[] getSuites() {
+ return myCoverageSuites.toArray(new CoverageSuite[myCoverageSuites.size()]);
+ }
+
+ public void chooseSuitesBundle(final CoverageSuitesBundle suite) {
+ if (myCurrentSuitesBundle == suite && suite == null) {
+ return;
+ }
+
+ LOG.assertTrue(!myProject.isDefault());
+
+ fireBeforeSuiteChosen();
+
+ mySubCoverageIsActive = false;
+ if (myCurrentSuitesBundle != null) {
+ myCurrentSuitesBundle.getCoverageEngine().getCoverageAnnotator(myProject).onSuiteChosen(suite);
+ }
+
+ myCurrentSuitesBundle = suite;
+ disposeAnnotators();
+
+ if (suite == null) {
+ triggerPresentationUpdate();
+ return;
+ }
+
+ for (CoverageSuite coverageSuite : myCurrentSuitesBundle.getSuites()) {
+ final boolean suiteFileExists = coverageSuite.getCoverageDataFileProvider().ensureFileExists();
+ if (!suiteFileExists) {
+ chooseSuitesBundle(null);
+ return;
+ }
+ }
+
+ renewCoverageData(suite);
+
+ fireAfterSuiteChosen();
+ }
+
+ public void coverageGathered(@NotNull final CoverageSuite suite) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myProject.isDisposed()) return;
+ if (myCurrentSuitesBundle != null) {
+ final String message = CodeInsightBundle.message("display.coverage.prompt", suite.getPresentableName());
+
+ final CoverageOptionsProvider coverageOptionsProvider = CoverageOptionsProvider.getInstance(myProject);
+ final DialogWrapper.DoNotAskOption doNotAskOption = new DialogWrapper.DoNotAskOption() {
+ @Override
+ public boolean isToBeShown() {
+ return coverageOptionsProvider.getOptionToReplace() == 3;
+ }
+
+ @Override
+ public void setToBeShown(boolean value, int exitCode) {
+ coverageOptionsProvider.setOptionsToReplace(value ? 3 : exitCode);
+ }
+
+ @Override
+ public boolean canBeHidden() {
+ return true;
+ }
+
+ @Override
+ public boolean shouldSaveOptionsOnCancel() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public String getDoNotShowMessage() {
+ return CommonBundle.message("dialog.options.do.not.show");
+ }
+ };
+ final String[] options = myCurrentSuitesBundle.getCoverageEngine() == suite.getCoverageEngine() ?
+ new String[] {REPLACE_ACTIVE_SUITES, ADD_TO_ACTIVE_SUITES, DO_NOT_APPLY_COLLECTED_COVERAGE} :
+ new String[] {REPLACE_ACTIVE_SUITES, DO_NOT_APPLY_COLLECTED_COVERAGE};
+ final int answer = doNotAskOption.isToBeShown() ? Messages.showDialog(message, CodeInsightBundle.message("code.coverage"),
+ options, 1, Messages.getQuestionIcon(),
+ doNotAskOption) : coverageOptionsProvider.getOptionToReplace();
+ if (answer == DialogWrapper.OK_EXIT_CODE) {
+ chooseSuitesBundle(new CoverageSuitesBundle(suite));
+ }
+ else if (answer == 1) {
+ chooseSuitesBundle(new CoverageSuitesBundle(ArrayUtil.append(myCurrentSuitesBundle.getSuites(), suite)));
+ }
+ }
+ else {
+ chooseSuitesBundle(new CoverageSuitesBundle(suite));
+ }
+ }
+ });
+ }
+
+ public void triggerPresentationUpdate() {
+ renewInformationInEditors();
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ public void run() {
+ if (myProject.isDisposed()) return;
+ ProjectView.getInstance(myProject).refresh();
+ CoverageViewManager.getInstance(myProject).setReady(true);
+ }
+ });
+ }
+
+ public void attachToProcess(@NotNull final ProcessHandler handler,
+ @NotNull final RunConfigurationBase configuration,
+ final RunnerSettings runnerSettings) {
+ handler.addProcessListener(new ProcessAdapter() {
+ public void processTerminated(final ProcessEvent event) {
+ processGatheredCoverage(configuration, runnerSettings);
+ }
+ });
+ }
+
+ @Override
+ public void processGatheredCoverage(@NotNull RunConfigurationBase configuration, RunnerSettings runnerSettings) {
+ if (runnerSettings instanceof CoverageRunnerData) {
+ processGatheredCoverage(configuration);
+ }
+ }
+
+ public static void processGatheredCoverage(RunConfigurationBase configuration) {
+ final Project project = configuration.getProject();
+ if (project.isDisposed()) return;
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(project);
+ final CoverageEnabledConfiguration coverageEnabledConfiguration = CoverageEnabledConfiguration.getOrCreate(configuration);
+ //noinspection ConstantConditions
+ final CoverageSuite coverageSuite = coverageEnabledConfiguration.getCurrentCoverageSuite();
+ if (coverageSuite != null) {
+ ((BaseCoverageSuite)coverageSuite).setConfiguration(configuration);
+ coverageDataManager.coverageGathered(coverageSuite);
+ }
+ }
+
+ protected void renewCoverageData(@NotNull final CoverageSuitesBundle suite) {
+ if (myCurrentSuitesBundle != null) {
+ myCurrentSuitesBundle.getCoverageEngine().getCoverageAnnotator(myProject).renewCoverageData(suite, this);
+ }
+ }
+
+ private void renewInformationInEditors() {
+ final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
+ final VirtualFile[] openFiles = fileEditorManager.getOpenFiles();
+ for (VirtualFile openFile : openFiles) {
+ final FileEditor[] allEditors = fileEditorManager.getAllEditors(openFile);
+ applyInformationToEditor(allEditors, openFile);
+ }
+ }
+
+ private void applyInformationToEditor(FileEditor[] editors, final VirtualFile file) {
+ final PsiFile psiFile = doInReadActionIfProjectOpen(new Computable<PsiFile>() {
+ @Nullable
+ @Override
+ public PsiFile compute() {
+ return PsiManager.getInstance(myProject).findFile(file);
+ }
+ });
+ if (psiFile != null && myCurrentSuitesBundle != null && psiFile.isPhysical()) {
+ final CoverageEngine engine = myCurrentSuitesBundle.getCoverageEngine();
+ if (!engine.coverageEditorHighlightingApplicableTo(psiFile)) {
+ return;
+ }
+
+ for (FileEditor editor : editors) {
+ if (editor instanceof TextEditor) {
+ final Editor textEditor = ((TextEditor)editor).getEditor();
+ SrcFileAnnotator annotator;
+ synchronized (ANNOTATORS_LOCK) {
+ annotator = myAnnotators.remove(textEditor);
+ }
+ if (annotator != null) {
+ Disposer.dispose(annotator);
+ }
+ break;
+ }
+ }
+
+ for (FileEditor editor : editors) {
+ if (editor instanceof TextEditor) {
+ final Editor textEditor = ((TextEditor)editor).getEditor();
+ SrcFileAnnotator annotator = getAnnotator(textEditor);
+ if (annotator == null) {
+ annotator = new SrcFileAnnotator(psiFile, textEditor);
+ synchronized (ANNOTATORS_LOCK) {
+ myAnnotators.put(textEditor, annotator);
+ }
+ }
+
+ if (myCurrentSuitesBundle != null && engine.acceptedByFilters(psiFile, myCurrentSuitesBundle)) {
+ annotator.showCoverageInformation(myCurrentSuitesBundle);
+ }
+ }
+ }
+ }
+ }
+
+ public void projectOpened() {
+ EditorFactory.getInstance().addEditorFactoryListener(new CoverageEditorFactoryListener(), myProject);
+ ProjectManagerAdapter projectManagerListener = new ProjectManagerAdapter() {
+ public void projectClosing(Project project) {
+ synchronized (myLock) {
+ myIsProjectClosing = true;
+ }
+ }
+ };
+ ProjectManager.getInstance().addProjectManagerListener(myProject, projectManagerListener);
+ }
+
+ public void projectClosed() {
+ }
+
+ public <T> T doInReadActionIfProjectOpen(Computable<T> computation) {
+ synchronized(myLock) {
+ if (myIsProjectClosing) return null;
+ }
+ return ApplicationManager.getApplication().runReadAction(computation);
+ }
+
+ public void selectSubCoverage(@NotNull final CoverageSuitesBundle suite, final List<String> testNames) {
+ suite.restoreCoverageData();
+ final ProjectData data = suite.getCoverageData();
+ if (data == null) return;
+ mySubCoverageIsActive = true;
+ final Map<String, Set<Integer>> executionTrace = new HashMap<String, Set<Integer>>();
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ final String fileName = coverageSuite.getCoverageDataFileName();
+ final File tracesDir = getTracesDirectory(fileName);
+ for (String testName : testNames) {
+ final File file = new File(tracesDir, FileUtil.sanitizeFileName(testName) + ".tr");
+ if (file.exists()) {
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new FileInputStream(file));
+ int traceSize = in.readInt();
+ for (int i = 0; i < traceSize; i++) {
+ final String className = in.readUTF();
+ final int linesSize = in.readInt();
+ Set<Integer> lines = executionTrace.get(className);
+ if (lines == null) {
+ lines = new HashSet<Integer>();
+ executionTrace.put(className, lines);
+ }
+ for(int l = 0; l < linesSize; l++) {
+ lines.add(in.readInt());
+ }
+ }
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+ }
+ final ProjectData projectData = new ProjectData();
+ for (String className : executionTrace.keySet()) {
+ ClassData loadedClassData = projectData.getClassData(className);
+ if (loadedClassData == null) {
+ loadedClassData = projectData.getOrCreateClassData(className);
+ }
+ final Set<Integer> lineNumbers = executionTrace.get(className);
+ final ClassData oldData = data.getClassData(className);
+ LOG.assertTrue(oldData != null, "missed className: \"" + className + "\"");
+ final Object[] oldLines = oldData.getLines();
+ LOG.assertTrue(oldLines != null);
+ int maxNumber = oldLines.length;
+ for (Integer lineNumber : lineNumbers) {
+ if (lineNumber >= maxNumber) {
+ maxNumber = lineNumber + 1;
+ }
+ }
+ final LineData[] lines = new LineData[maxNumber];
+ for (Integer line : lineNumbers) {
+ final int lineIdx = line.intValue() - 1;
+ String methodSig = null;
+ if (lineIdx < oldData.getLines().length) {
+ final LineData oldLineData = oldData.getLineData(lineIdx);
+ if (oldLineData != null) {
+ methodSig = oldLineData.getMethodSignature();
+ }
+ }
+ final LineData lineData = new LineData(lineIdx, methodSig);
+ if (methodSig != null) {
+ loadedClassData.registerMethodSignature(lineData);
+ }
+ lineData.setStatus(LineCoverage.FULL);
+ lines[lineIdx] = lineData;
+ }
+ loadedClassData.setLines(lines);
+ }
+ suite.setCoverageData(projectData);
+ renewCoverageData(suite);
+ }
+
+ private File getTracesDirectory(final String fileName) {
+ return new File(new File(fileName).getParentFile(), FileUtil.getNameWithoutExtension(new File(fileName)));
+ }
+
+ public void restoreMergedCoverage(@NotNull final CoverageSuitesBundle suite) {
+ mySubCoverageIsActive = false;
+ suite.restoreCoverageData();
+ renewCoverageData(suite);
+ }
+
+ @Override
+ public void addSuiteListener(final CoverageSuiteListener listener, Disposable parentDisposable) {
+ myListeners.add(listener);
+ Disposer.register(parentDisposable, new Disposable() {
+ public void dispose() {
+ myListeners.remove(listener);
+ }
+ });
+ }
+
+ public void fireBeforeSuiteChosen() {
+ for (CoverageSuiteListener listener : myListeners) {
+ listener.beforeSuiteChosen();
+ }
+ }
+
+ public void fireAfterSuiteChosen() {
+ for (CoverageSuiteListener listener : myListeners) {
+ listener.afterSuiteChosen();
+ }
+ }
+
+ public boolean isSubCoverageActive() {
+ return mySubCoverageIsActive;
+ }
+
+ @Nullable
+ public SrcFileAnnotator getAnnotator(Editor editor) {
+ synchronized (ANNOTATORS_LOCK) {
+ return myAnnotators.get(editor);
+ }
+ }
+
+ public void disposeAnnotators() {
+ synchronized (ANNOTATORS_LOCK) {
+ for (SrcFileAnnotator annotator : myAnnotators.values()) {
+ if (annotator != null) {
+ Disposer.dispose(annotator);
+ }
+ }
+ myAnnotators.clear();
+ }
+ }
+
+ @NotNull
+ private CoverageSuite createCoverageSuite(final CoverageEnabledConfiguration config,
+ final String name,
+ final CoverageRunner coverageRunner,
+ final DefaultCoverageFileProvider fileProvider) {
+ CoverageSuite suite = null;
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (coverageRunner.acceptsCoverageEngine(engine) && engine.isApplicableTo(config.getConfiguration())) {
+ suite = engine.createCoverageSuite(coverageRunner, name, fileProvider, config);
+ if (suite != null) {
+ break;
+ }
+ }
+ }
+ LOG.assertTrue(suite != null, "Cannot create coverage suite for runner: " + coverageRunner.getPresentableName());
+ return suite;
+ }
+
+ @NotNull
+ private CoverageSuite createCoverageSuite(final CoverageRunner coverageRunner,
+ final String name,
+ final CoverageFileProvider fileProvider,
+ final String[] filters,
+ final long lastCoverageTimeStamp,
+ final String suiteToMergeWith,
+ final boolean collectLineInfo,
+ final boolean tracingEnabled) {
+
+ CoverageSuite suite = null;
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (coverageRunner.acceptsCoverageEngine(engine)) {
+ suite = engine.createCoverageSuite(coverageRunner, name, fileProvider, filters, lastCoverageTimeStamp,
+ suiteToMergeWith, collectLineInfo, tracingEnabled, false, myProject);
+ if (suite != null) {
+ break;
+ }
+ }
+ }
+
+ LOG.assertTrue(suite != null, "Cannot create coverage suite for runner: " + coverageRunner.getPresentableName());
+ return suite;
+ }
+
+ private class CoverageEditorFactoryListener implements EditorFactoryListener {
+ private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, myProject);
+ private final Map<Editor, Runnable> myCurrentEditors = new HashMap<Editor, Runnable>();
+
+ public void editorCreated(@NotNull EditorFactoryEvent event) {
+ synchronized (myLock) {
+ if (myIsProjectClosing) return;
+ }
+
+ final Editor editor = event.getEditor();
+ if (editor.getProject() != myProject) return;
+ final PsiFile psiFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Nullable
+ @Override
+ public PsiFile compute() {
+ if (myProject.isDisposed()) return null;
+ final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
+ final Document document = editor.getDocument();
+ return documentManager.getPsiFile(document);
+ }
+ });
+
+ if (psiFile != null && myCurrentSuitesBundle != null && psiFile.isPhysical()) {
+ final CoverageEngine engine = myCurrentSuitesBundle.getCoverageEngine();
+ if (!engine.coverageEditorHighlightingApplicableTo(psiFile)) {
+ return;
+ }
+
+ SrcFileAnnotator annotator = getAnnotator(editor);
+ if (annotator == null) {
+ annotator = new SrcFileAnnotator(psiFile, editor);
+ }
+
+ final SrcFileAnnotator finalAnnotator = annotator;
+
+ synchronized (ANNOTATORS_LOCK) {
+ myAnnotators.put(editor, finalAnnotator);
+ }
+
+ final Runnable request = new Runnable() {
+ @Override
+ public void run() {
+ if (myProject.isDisposed()) return;
+ if (myCurrentSuitesBundle != null) {
+ if (engine.acceptedByFilters(psiFile, myCurrentSuitesBundle)) {
+ finalAnnotator.showCoverageInformation(myCurrentSuitesBundle);
+ }
+ }
+ }
+ };
+ myCurrentEditors.put(editor, request);
+ myAlarm.addRequest(request, 100);
+ }
+ }
+
+ public void editorReleased(@NotNull EditorFactoryEvent event) {
+ final Editor editor = event.getEditor();
+ if (editor.getProject() != myProject) return;
+ try {
+ final SrcFileAnnotator fileAnnotator;
+ synchronized (ANNOTATORS_LOCK) {
+ fileAnnotator = myAnnotators.remove(editor);
+ }
+ if (fileAnnotator != null) {
+ Disposer.dispose(fileAnnotator);
+ }
+ }
+ finally {
+ final Runnable request = myCurrentEditors.remove(editor);
+ if (request != null) {
+ myAlarm.cancelRequest(request);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageEngine.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageEngine.java
new file mode 100644
index 000000000000..f8d8fdaaa884
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageEngine.java
@@ -0,0 +1,360 @@
+package com.intellij.coverage;
+
+import com.intellij.codeInspection.export.ExportToHTMLDialog;
+import com.intellij.coverage.view.CoverageViewExtension;
+import com.intellij.coverage.view.CoverageViewManager;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * @author Roman.Chernyatchik
+ * <p/>
+ * Coverage engine provide coverage support for different languages or coverage runner classes.
+ * E.g. engine for JVM languages, Ruby, Python
+ * <p/>
+ * Each coverage engine may work with several coverage runner. E.g. Java coverage engine supports IDEA/EMMA/Cobertura,
+ * Ruby engine works with RCov
+ */
+public abstract class CoverageEngine {
+ public static final ExtensionPointName<CoverageEngine> EP_NAME = ExtensionPointName.create("com.intellij.coverageEngine");
+
+ /**
+ * Checks whether coverage feature is supported by this engine for given configuration or not.
+ *
+ * @param conf Run Configuration
+ * @return True if coverage for given run configuration is supported by this engine
+ */
+ public abstract boolean isApplicableTo(@Nullable final RunConfigurationBase conf);
+
+ public abstract boolean canHavePerTestCoverage(@Nullable final RunConfigurationBase conf);
+
+ /**
+ * Creates coverage enabled configuration for given RunConfiguration. It is supposed that one run configuration may be associated
+ * not more than one coverage engine.
+ *
+ * @param conf Run Configuration
+ * @return Coverage enabled configuration with engine specific settings
+ */
+ @NotNull
+ public abstract CoverageEnabledConfiguration createCoverageEnabledConfiguration(@Nullable final RunConfigurationBase conf);
+
+ /**
+ * Coverage suite is coverage settings & coverage data gather by coverage runner (for suites provided by TeamCity server)
+ *
+ * @param covRunner Coverage Runner
+ * @param name Suite name
+ * @param coverageDataFileProvider Coverage raw data file provider
+ * @param filters Coverage data filters
+ * @param lastCoverageTimeStamp timestamp
+ * @param suiteToMerge Suite to merge this coverage data with
+ * @param coverageByTestEnabled Collect coverage for test option
+ * @param tracingEnabled Tracing option
+ * @param trackTestFolders Track test folders option
+ * @return Suite
+ */
+ @Nullable
+ public CoverageSuite createCoverageSuite(@NotNull final CoverageRunner covRunner,
+ @NotNull final String name,
+ @NotNull final CoverageFileProvider coverageDataFileProvider,
+ @Nullable final String[] filters,
+ final long lastCoverageTimeStamp,
+ @Nullable final String suiteToMerge,
+ final boolean coverageByTestEnabled,
+ final boolean tracingEnabled,
+ final boolean trackTestFolders) {
+ return createCoverageSuite(covRunner, name, coverageDataFileProvider, filters, lastCoverageTimeStamp, suiteToMerge,
+ coverageByTestEnabled, tracingEnabled, trackTestFolders, null);
+ }
+
+ /**
+ * Coverage suite is coverage settings & coverage data gather by coverage runner (for suites provided by TeamCity server)
+ *
+ *
+ * @param covRunner Coverage Runner
+ * @param name Suite name
+ * @param coverageDataFileProvider Coverage raw data file provider
+ * @param filters Coverage data filters
+ * @param lastCoverageTimeStamp timestamp
+ * @param suiteToMerge Suite to merge this coverage data with
+ * @param coverageByTestEnabled Collect coverage for test option
+ * @param tracingEnabled Tracing option
+ * @param trackTestFolders Track test folders option
+ * @param project
+ * @return Suite
+ */
+ @Nullable
+ public abstract CoverageSuite createCoverageSuite(@NotNull final CoverageRunner covRunner,
+ @NotNull final String name,
+ @NotNull final CoverageFileProvider coverageDataFileProvider,
+ @Nullable final String[] filters,
+ final long lastCoverageTimeStamp,
+ @Nullable final String suiteToMerge,
+ final boolean coverageByTestEnabled,
+ final boolean tracingEnabled,
+ final boolean trackTestFolders, Project project);
+
+ /**
+ * Coverage suite is coverage settings & coverage data gather by coverage runner
+ *
+ * @param covRunner Coverage Runner
+ * @param name Suite name
+ * @param coverageDataFileProvider
+ * @param config Coverage engine configuration
+ * @return Suite
+ */
+ @Nullable
+ public abstract CoverageSuite createCoverageSuite(@NotNull final CoverageRunner covRunner,
+ @NotNull final String name,
+ @NotNull final CoverageFileProvider coverageDataFileProvider,
+ @NotNull final CoverageEnabledConfiguration config);
+
+ @Nullable
+ public abstract CoverageSuite createEmptyCoverageSuite(@NotNull final CoverageRunner coverageRunner);
+
+ /**
+ * Coverage annotator which annotates smth(e.g. Project view nodes / editor) with coverage information
+ *
+ * @param project Project
+ * @return Annotator
+ */
+ @NotNull
+ public abstract CoverageAnnotator getCoverageAnnotator(Project project);
+
+ /**
+ * Determines if coverage information should be displayed for given file. E.g. coverage may be applicable
+ * only to user source files or only for files of specific types
+ *
+ * @param psiFile file
+ * @return false if coverage N/A for given file
+ */
+ public abstract boolean coverageEditorHighlightingApplicableTo(@NotNull final PsiFile psiFile);
+
+ /**
+ * Checks whether file is accepted by coverage filters or not. Is used in Project View Nodes annotator.
+ *
+ * @param psiFile Psi file
+ * @param suite Coverage suite
+ * @return true if included in coverage
+ */
+ public abstract boolean acceptedByFilters(@NotNull final PsiFile psiFile, @NotNull final CoverageSuitesBundle suite);
+
+ /**
+ * E.g. all *.class files for java source file with several classes
+ *
+ *
+ * @param srcFile
+ * @param module
+ * @return files
+ */
+ @NotNull
+ public Set<File> getCorrespondingOutputFiles(@NotNull final PsiFile srcFile,
+ @Nullable final Module module,
+ @NotNull final CoverageSuitesBundle suite) {
+ final VirtualFile virtualFile = srcFile.getVirtualFile();
+ return virtualFile == null ? Collections.<File>emptySet() : Collections.singleton(VfsUtilCore.virtualToIoFile(virtualFile));
+ }
+
+ /**
+ * When output directory is empty we probably should recompile source and then choose suite again
+ *
+ * @param module
+ * @param chooseSuiteAction @return True if should stop and wait compilation (e.g. for Java). False if we can ignore output (e.g. for Ruby)
+ */
+ public abstract boolean recompileProjectAndRerunAction(@NotNull final Module module, @NotNull final CoverageSuitesBundle suite,
+ @NotNull final Runnable chooseSuiteAction);
+
+ /**
+ * Qualified name same as in coverage raw project data
+ * E.g. java class qualified name by *.class file of some Java class in corresponding source file
+ *
+ * @param outputFile
+ * @param sourceFile
+ * @return
+ */
+ @Nullable
+ public String getQualifiedName(@NotNull final File outputFile,
+ @NotNull final PsiFile sourceFile) {
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(outputFile);
+ if (virtualFile != null) {
+ return getQualifiedName(virtualFile, sourceFile);
+ }
+ return null;
+ }
+
+ @Deprecated
+ @Nullable
+ public String getQualifiedName(@NotNull final VirtualFile outputFile,
+ @NotNull final PsiFile sourceFile) {
+ return null;
+ }
+
+ @NotNull
+ public abstract Set<String> getQualifiedNames(@NotNull final PsiFile sourceFile);
+
+ /**
+ * Decide include a file or not in coverage report if coverage data isn't available for the file. E.g file wasn't touched by coverage
+ * util
+ *
+ * @param qualifiedName
+ * @param outputFile
+ * @param sourceFile
+ * @param suite
+ * @return
+ */
+ public boolean includeUntouchedFileInCoverage(@NotNull final String qualifiedName,
+ @NotNull final File outputFile,
+ @NotNull final PsiFile sourceFile,
+ @NotNull final CoverageSuitesBundle suite) {
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(outputFile);
+ if (virtualFile != null) {
+ return includeUntouchedFileInCoverage(qualifiedName, virtualFile, sourceFile, suite);
+ }
+ return false;
+ }
+
+ @Deprecated
+ public boolean includeUntouchedFileInCoverage(@NotNull final String qualifiedName,
+ @NotNull final VirtualFile outputFile,
+ @NotNull final PsiFile sourceFile,
+ @NotNull final CoverageSuitesBundle suite) {
+ return false;
+ }
+
+ /**
+ * Collect code lines if untouched file should be included in coverage information. These lines will be marked as uncovered.
+ *
+ * @param suite
+ * @return List (probably empty) of code lines or null if all lines should be marked as uncovered
+ */
+ @Nullable
+ public List<Integer> collectSrcLinesForUntouchedFile(@NotNull final File classFile,
+ @NotNull final CoverageSuitesBundle suite) {
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(classFile);
+ if (virtualFile != null) {
+ return collectSrcLinesForUntouchedFile(virtualFile, suite);
+ }
+ return null;
+ }
+
+ @Deprecated
+ @Nullable
+ public List<Integer> collectSrcLinesForUntouchedFile(@NotNull final VirtualFile classFile,
+ @NotNull final CoverageSuitesBundle suite) {
+ return null;
+ }
+
+ /**
+ * Content of brief report which will be shown by click on coverage icon
+ *
+ * @param editor
+ * @param psiFile
+ * @param lineNumber
+ * @param startOffset
+ * @param endOffset
+ * @param lineData
+ * @return
+ */
+ public String generateBriefReport(@NotNull Editor editor,
+ @NotNull PsiFile psiFile,
+ int lineNumber,
+ int startOffset,
+ int endOffset,
+ @Nullable LineData lineData) {
+ final int hits = lineData == null ? 0 : lineData.getHits();
+ return "Hits: " + hits;
+ }
+
+ public abstract List<PsiElement> findTestsByNames(@NotNull final String[] testNames, @NotNull final Project project);
+
+ @Nullable
+ public abstract String getTestMethodName(@NotNull final PsiElement element, @NotNull final AbstractTestProxy testProxy);
+
+ /**
+ * @return true to enable 'Generate Coverage Report...' action
+ */
+ public boolean isReportGenerationAvailable(@NotNull Project project,
+ @NotNull DataContext dataContext,
+ @NotNull CoverageSuitesBundle currentSuite) {
+ return false;
+ }
+
+ public void generateReport(@NotNull final Project project,
+ @NotNull final DataContext dataContext,
+ @NotNull final CoverageSuitesBundle currentSuite) {
+ }
+
+ @NotNull
+ public ExportToHTMLDialog createGenerateReportDialog(@NotNull final Project project,
+ @NotNull final DataContext dataContext,
+ @NotNull final CoverageSuitesBundle currentSuite) {
+ final ExportToHTMLDialog dialog = new ExportToHTMLDialog(project, true);
+ dialog.setTitle("Generate Coverage Report for: \'" + currentSuite.getPresentableName() + "\'");
+
+ return dialog;
+ }
+
+ public abstract String getPresentableText();
+
+ public boolean coverageProjectViewStatisticsApplicableTo(VirtualFile fileOrDir) {
+ return false;
+ }
+
+ public Object[] postProcessExecutableLines(Object[] lines, Editor editor) {
+ return lines;
+ }
+
+ public CoverageLineMarkerRenderer getLineMarkerRenderer(int lineNumber,
+ @Nullable final String className,
+ final TreeMap<Integer, LineData> lines,
+ final boolean coverageByTestApplicable,
+ @NotNull final CoverageSuitesBundle coverageSuite,
+ final Function<Integer, Integer> newToOldConverter,
+ final Function<Integer, Integer> oldToNewConverter, boolean subCoverageActive) {
+ return CoverageLineMarkerRenderer
+ .getRenderer(lineNumber, className, lines, coverageByTestApplicable, coverageSuite, newToOldConverter, oldToNewConverter,
+ subCoverageActive);
+ }
+
+ public boolean shouldHighlightFullLines() {
+ return false;
+ }
+
+ public static String getEditorTitle() {
+ return "Code Coverage";
+ }
+
+ public CoverageViewExtension createCoverageViewExtension(Project project,
+ CoverageSuitesBundle suiteBundle,
+ CoverageViewManager.StateBean stateBean) {
+ return null;
+ }
+
+ public boolean isInLibraryClasses(Project project, VirtualFile file) {
+ final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+
+ return projectFileIndex.isInLibraryClasses(file);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageExecutor.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageExecutor.java
new file mode 100644
index 000000000000..1a38ba9ce3ee
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageExecutor.java
@@ -0,0 +1,69 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.Executor;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.ToolWindowId;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+public class CoverageExecutor extends Executor {
+
+ public static final String EXECUTOR_ID = "Coverage";
+
+ @NotNull
+ public String getStartActionText() {
+ return "Run with Co_verage";
+ }
+
+ @Override
+ public String getStartActionText(String configurationName) {
+ final String name = configurationName != null ? escapeMnemonicsInConfigurationName(StringUtil.first(configurationName, 30, true)) : null;
+ return "Run" + (StringUtil.isEmpty(name) ? "" : " '" + name + "'") + " with Co_verage";
+ }
+
+
+ private static String escapeMnemonicsInConfigurationName(String configurationName) {
+ return configurationName.replace("_", "__");
+ }
+
+ public String getToolWindowId() {
+ return ToolWindowId.RUN;
+ }
+
+ public Icon getToolWindowIcon() {
+ return AllIcons.General.RunWithCoverage;
+ }
+
+ @NotNull
+ public Icon getIcon() {
+ return AllIcons.General.RunWithCoverage;
+ }
+
+ public Icon getDisabledIcon() {
+ return null;
+ }
+
+ public String getDescription() {
+ return "Run selected configuration with coverage enabled";
+ }
+
+ @NotNull
+ public String getActionName() {
+ return "Cover";
+ }
+
+ @NotNull
+ public String getId() {
+ return EXECUTOR_ID;
+ }
+
+ public String getContextActionId() {
+ return "RunCoverage";
+ }
+
+ public String getHelpId() {
+ return null;//todo
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageFileProvider.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageFileProvider.java
new file mode 100644
index 000000000000..dee3efd68f50
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageFileProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.coverage;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Jul 7, 2006
+ */
+public interface CoverageFileProvider {
+
+ String getCoverageDataFilePath();
+
+ /**
+ * @return true if the coverage file exists, false otherwise
+ */
+ boolean ensureFileExists();
+
+ boolean isValid();
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageHelper.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageHelper.java
new file mode 100644
index 000000000000..527dde1d8940
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageHelper.java
@@ -0,0 +1,51 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author traff
+ */
+public class CoverageHelper {
+ private CoverageHelper() {
+ }
+
+ public static void attachToProcess(@NotNull RunConfigurationBase configuration,
+ @NotNull ProcessHandler handler,
+ RunnerSettings runnerSettings) {
+ resetCoverageSuit(configuration);
+
+ // attach to process termination listener
+ CoverageDataManager.getInstance(configuration.getProject()).attachToProcess(handler, configuration, runnerSettings);
+ }
+
+ public static void resetCoverageSuit(RunConfigurationBase configuration) {
+ final CoverageEnabledConfiguration covConfig = CoverageEnabledConfiguration.getOrCreate(configuration);
+
+ // reset coverage suite
+ covConfig.setCurrentCoverageSuite(null);
+
+ // register new coverage suite
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(configuration.getProject());
+
+ covConfig.setCurrentCoverageSuite(coverageDataManager.addCoverageSuite(covConfig));
+ }
+
+ public static void doReadExternal(RunConfigurationBase runConfiguration, Element element) throws InvalidDataException {
+ final CoverageEnabledConfiguration covConf = CoverageEnabledConfiguration.getOrCreate(runConfiguration);
+
+ covConf.readExternal(element);
+ }
+
+ public static void doWriteExternal(RunConfigurationBase runConfiguration, Element element) throws WriteExternalException {
+ final CoverageEnabledConfiguration covConf = CoverageEnabledConfiguration.getOrCreate(runConfiguration);
+
+ covConf.writeExternal(element);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageLineMarkerRenderer.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageLineMarkerRenderer.java
new file mode 100644
index 000000000000..6463a7a6e746
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageLineMarkerRenderer.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ */
+
+package com.intellij.coverage;
+
+import com.intellij.application.options.colors.ColorAndFontOptions;
+import com.intellij.application.options.colors.ColorAndFontPanelFactory;
+import com.intellij.application.options.colors.NewColorAndFontPanel;
+import com.intellij.application.options.colors.SimpleEditorPreview;
+import com.intellij.codeInsight.hint.EditorFragmentComponent;
+import com.intellij.codeInsight.hint.HintManagerImpl;
+import com.intellij.coverage.actions.HideCoverageInfoAction;
+import com.intellij.coverage.actions.ShowCoveringTestsAction;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
+import com.intellij.openapi.editor.impl.EditorImpl;
+import com.intellij.openapi.editor.markup.ActiveGutterRenderer;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.options.colors.pages.GeneralColorsPage;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.ui.ColorUtil;
+import com.intellij.ui.ColoredSideBorder;
+import com.intellij.ui.HintHint;
+import com.intellij.ui.LightweightHint;
+import com.intellij.util.Function;
+import com.intellij.util.ImageLoader;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.TreeMap;
+
+/**
+ * @author ven
+ */
+public class CoverageLineMarkerRenderer implements ActiveGutterRenderer {
+ private static final int THICKNESS = 8;
+ private final TextAttributesKey myKey;
+ private final String myClassName;
+ private final TreeMap<Integer, LineData> myLines;
+ private final boolean myCoverageByTestApplicable;
+ private final Function<Integer, Integer> myNewToOldConverter;
+ private final Function<Integer, Integer> myOldToNewConverter;
+ private final CoverageSuitesBundle myCoverageSuite;
+ private final boolean mySubCoverageActive;
+
+ protected CoverageLineMarkerRenderer(final TextAttributesKey textAttributesKey, @Nullable final String className, final TreeMap<Integer, LineData> lines,
+ final boolean coverageByTestApplicable,
+ final Function<Integer, Integer> newToOldConverter,
+ final Function<Integer, Integer> oldToNewConverter,
+ final CoverageSuitesBundle coverageSuite, boolean subCoverageActive) {
+ myKey = textAttributesKey;
+ myClassName = className;
+ myLines = lines;
+ myCoverageByTestApplicable = coverageByTestApplicable;
+ myNewToOldConverter = newToOldConverter;
+ myOldToNewConverter = oldToNewConverter;
+ myCoverageSuite = coverageSuite;
+ mySubCoverageActive = subCoverageActive;
+ }
+
+ public void paint(Editor editor, Graphics g, Rectangle r) {
+ final TextAttributes color = editor.getColorsScheme().getAttributes(myKey);
+ Color bgColor = color.getBackgroundColor();
+ if (bgColor == null) {
+ bgColor = color.getForegroundColor();
+ }
+ if (editor.getSettings().isLineNumbersShown() || ((EditorGutterComponentEx)editor.getGutter()).isAnnotationsShown()) {
+ if (bgColor != null) {
+ bgColor = ColorUtil.toAlpha(bgColor, 150);
+ }
+ }
+ if (bgColor != null) {
+ g.setColor(bgColor);
+ }
+ g.fillRect(0, r.y, THICKNESS, r.height);
+ final LineData lineData = getLineData(editor.xyToLogicalPosition(new Point(0, r.y)).line);
+ if (lineData != null && lineData.isCoveredByOneTest()) {
+ g.drawImage( ImageLoader.loadFromResource("/gutter/unique.png"), 0, r.y, 8, 8, editor.getComponent());
+ }
+ }
+
+ public static CoverageLineMarkerRenderer getRenderer(int lineNumber,
+ @Nullable final String className,
+ final TreeMap<Integer, LineData> lines,
+ final boolean coverageByTestApplicable,
+ @NotNull final CoverageSuitesBundle coverageSuite,
+ final Function<Integer, Integer> newToOldConverter,
+ final Function<Integer, Integer> oldToNewConverter, boolean subCoverageActive) {
+ return new CoverageLineMarkerRenderer(getAttributesKey(lineNumber, lines), className, lines, coverageByTestApplicable, newToOldConverter,
+ oldToNewConverter, coverageSuite, subCoverageActive);
+ }
+
+ public static TextAttributesKey getAttributesKey(final int lineNumber,
+ final TreeMap<Integer, LineData> lines) {
+
+ return getAttributesKey(lines.get(lineNumber));
+ }
+
+ private static TextAttributesKey getAttributesKey(LineData lineData) {
+ if (lineData != null) {
+ switch (lineData.getStatus()) {
+ case LineCoverage.FULL:
+ return CodeInsightColors.LINE_FULL_COVERAGE;
+ case LineCoverage.PARTIAL:
+ return CodeInsightColors.LINE_PARTIAL_COVERAGE;
+ }
+ }
+
+ return CodeInsightColors.LINE_NONE_COVERAGE;
+ }
+
+ public boolean canDoAction(final MouseEvent e) {
+ return e.getX() < THICKNESS;
+ }
+
+ public void doAction(final Editor editor, final MouseEvent e) {
+ e.consume();
+ final JComponent comp = (JComponent)e.getComponent();
+ final JRootPane rootPane = comp.getRootPane();
+ final JLayeredPane layeredPane = rootPane.getLayeredPane();
+ final Point point = SwingUtilities.convertPoint(comp, THICKNESS, e.getY(), layeredPane);
+ showHint(editor, point, editor.xyToLogicalPosition(e.getPoint()).line);
+ }
+
+ private void showHint(final Editor editor, final Point point, final int lineNumber) {
+ final JPanel panel = new JPanel(new BorderLayout());
+ panel.add(createActionsToolbar(editor, lineNumber), BorderLayout.NORTH);
+
+ final LineData lineData = getLineData(lineNumber);
+ final EditorImpl uEditor;
+ if (lineData != null && lineData.getStatus() != LineCoverage.NONE && !mySubCoverageActive) {
+ final EditorFactory factory = EditorFactory.getInstance();
+ final Document doc = factory.createDocument(getReport(editor, lineNumber));
+ doc.setReadOnly(true);
+ uEditor = (EditorImpl)factory.createEditor(doc, editor.getProject());
+ panel.add(EditorFragmentComponent.createEditorFragmentComponent(uEditor, 0, doc.getLineCount(), false, false), BorderLayout.CENTER);
+ } else {
+ uEditor = null;
+ }
+
+
+ final LightweightHint hint = new LightweightHint(panel){
+ @Override
+ public void hide() {
+ if (uEditor != null) EditorFactory.getInstance().releaseEditor(uEditor);
+ super.hide();
+
+ }
+ };
+ HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, point,
+ HintManagerImpl.HIDE_BY_ANY_KEY | HintManagerImpl.HIDE_BY_TEXT_CHANGE | HintManagerImpl.HIDE_BY_OTHER_HINT | HintManagerImpl.HIDE_BY_SCROLLING, -1, false, new HintHint(editor, point));
+ }
+
+ private String getReport(final Editor editor, final int lineNumber) {
+ final LineData lineData = getLineData(lineNumber);
+
+ final Document document = editor.getDocument();
+ final Project project = editor.getProject();
+ assert project != null;
+
+ final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
+ assert psiFile != null;
+
+ final int lineStartOffset = document.getLineStartOffset(lineNumber);
+ final int lineEndOffset = document.getLineEndOffset(lineNumber);
+
+ return myCoverageSuite.getCoverageEngine().generateBriefReport(editor, psiFile, lineNumber, lineStartOffset, lineEndOffset, lineData);
+ }
+
+ protected JComponent createActionsToolbar(final Editor editor, final int lineNumber) {
+
+ final JComponent editorComponent = editor.getComponent();
+
+ final DefaultActionGroup group = new DefaultActionGroup();
+ final GotoPreviousCoveredLineAction prevAction = new GotoPreviousCoveredLineAction(editor, lineNumber);
+ final GotoNextCoveredLineAction nextAction = new GotoNextCoveredLineAction(editor, lineNumber);
+
+ group.add(prevAction);
+ group.add(nextAction);
+
+ prevAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_MASK|InputEvent.SHIFT_MASK)), editorComponent);
+ nextAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_MASK|InputEvent.SHIFT_MASK)), editorComponent);
+
+ final LineData lineData = getLineData(lineNumber);
+ if (myCoverageByTestApplicable) {
+ group.add(new ShowCoveringTestsAction(myClassName, lineData));
+ }
+ final AnAction byteCodeViewAction = ActionManager.getInstance().getAction("ByteCodeViewer");
+ if (byteCodeViewAction != null) {
+ group.add(byteCodeViewAction);
+ }
+ group.add(new EditCoverageColorsAction(editor, lineNumber));
+ group.add(new HideCoverageInfoAction());
+
+ final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent();
+
+ final Color background = ((EditorEx)editor).getBackgroundColor();
+ final Color foreground = editor.getColorsScheme().getColor(EditorColors.CARET_COLOR);
+ toolbar.setBackground(background);
+ toolbar.setBorder(new ColoredSideBorder(foreground, foreground, lineData == null || lineData.getStatus() == LineCoverage.NONE || mySubCoverageActive ? foreground : null, foreground, 1));
+ return toolbar;
+ }
+
+ public void moveToLine(final int lineNumber, final Editor editor) {
+ final int firstOffset = editor.getDocument().getLineStartOffset(lineNumber);
+ editor.getCaretModel().moveToOffset(firstOffset);
+ editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
+
+ editor.getScrollingModel().runActionOnScrollingFinished(new Runnable() {
+ public void run() {
+ Point p = editor.visualPositionToXY(editor.offsetToVisualPosition(firstOffset));
+ EditorGutterComponentEx editorComponent = (EditorGutterComponentEx)editor.getGutter();
+ JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();
+ p = SwingUtilities.convertPoint(editorComponent, THICKNESS, p.y, layeredPane);
+ showHint(editor, p, lineNumber);
+ }
+ });
+ }
+
+ @Nullable
+ public LineData getLineData(int lineNumber) {
+ return myLines != null ? myLines.get(myNewToOldConverter != null ? myNewToOldConverter.fun(lineNumber).intValue() : lineNumber) : null;
+ }
+
+ public Color getErrorStripeColor(final Editor editor) {
+ return editor.getColorsScheme().getAttributes(myKey).getErrorStripeColor();
+ }
+
+ private class GotoPreviousCoveredLineAction extends BaseGotoCoveredLineAction {
+
+ public GotoPreviousCoveredLineAction(final Editor editor, final int lineNumber) {
+ super(editor, lineNumber);
+ copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_PREVIOUS_OCCURENCE));
+ getTemplatePresentation().setText("Previous Coverage Mark");
+ }
+
+ protected boolean hasNext(final int idx, final List<Integer> list) {
+ return idx > 0;
+ }
+
+ protected int next(final int idx) {
+ return idx - 1;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ final String nextChange = getNextChange();
+ if (nextChange != null) {
+ e.getPresentation().setText("Previous " + nextChange);
+ }
+ }
+ }
+
+ private class GotoNextCoveredLineAction extends BaseGotoCoveredLineAction {
+
+ public GotoNextCoveredLineAction(final Editor editor, final int lineNumber) {
+ super(editor, lineNumber);
+ copyFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_NEXT_OCCURENCE));
+ getTemplatePresentation().setText("Next Coverage Mark");
+ }
+
+ protected boolean hasNext(final int idx, final List<Integer> list) {
+ return idx < list.size() - 1;
+ }
+
+ protected int next(final int idx) {
+ return idx + 1;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ final String nextChange = getNextChange();
+ if (nextChange != null) {
+ e.getPresentation().setText("Next " + nextChange);
+ }
+ }
+ }
+
+ private abstract class BaseGotoCoveredLineAction extends AnAction {
+ private final Editor myEditor;
+ private final int myLineNumber;
+
+ public BaseGotoCoveredLineAction(final Editor editor, final int lineNumber) {
+ myEditor = editor;
+ myLineNumber = lineNumber;
+ }
+
+ public void actionPerformed(final AnActionEvent e) {
+ final Integer lineNumber = getLineEntry();
+ if (lineNumber != null) {
+ moveToLine(lineNumber.intValue(), myEditor);
+ }
+ }
+
+ protected abstract boolean hasNext(int idx, List<Integer> list);
+ protected abstract int next(int idx);
+
+ @Nullable
+ private Integer getLineEntry() {
+ final ArrayList<Integer> list = new ArrayList<Integer>(myLines.keySet());
+ Collections.sort(list);
+ final LineData data = getLineData(myLineNumber);
+ final int currentStatus = data != null ? data.getStatus() : LineCoverage.NONE;
+ int idx = list.indexOf(myNewToOldConverter != null ? myNewToOldConverter.fun(myLineNumber).intValue() : myLineNumber);
+ while (hasNext(idx, list)) {
+ final int index = next(idx);
+ final LineData lineData = myLines.get(list.get(index));
+ idx = index;
+ if (lineData != null && lineData.getStatus() != currentStatus) {
+ final Integer line = list.get(idx);
+ if (myOldToNewConverter != null) {
+ final int newLine = myOldToNewConverter.fun(line).intValue();
+ if (newLine != 0) return newLine;
+ } else {
+ return line;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ protected String getNextChange() {
+ Integer entry = getLineEntry();
+ if (entry != null) {
+ final LineData lineData = getLineData(entry);
+ if (lineData != null) {
+ switch (lineData.getStatus()) {
+ case LineCoverage.NONE:
+ return "Uncovered";
+ case LineCoverage.PARTIAL:
+ return "Partial Covered";
+ case LineCoverage.FULL:
+ return "Fully Covered";
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ e.getPresentation().setEnabled(getLineEntry() != null);
+ }
+ }
+
+ private class EditCoverageColorsAction extends AnAction {
+ private final Editor myEditor;
+ private final int myLineNumber;
+
+ private EditCoverageColorsAction(Editor editor, int lineNumber) {
+ super("Edit coverage colors", "Edit coverage colors", AllIcons.General.EditColors);
+ myEditor = editor;
+ myLineNumber = lineNumber;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setVisible(getLineData(myLineNumber) != null);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final ColorAndFontOptions colorAndFontOptions = new ColorAndFontOptions(){
+ @Override
+ protected List<ColorAndFontPanelFactory> createPanelFactories() {
+ final GeneralColorsPage colorsPage = new GeneralColorsPage();
+ final ColorAndFontPanelFactory panelFactory = new ColorAndFontPanelFactory() {
+ @NotNull
+ @Override
+ public NewColorAndFontPanel createPanel(@NotNull ColorAndFontOptions options) {
+ final SimpleEditorPreview preview = new SimpleEditorPreview(options, colorsPage);
+ return NewColorAndFontPanel.create(preview, colorsPage.getDisplayName(), options, null, colorsPage);
+ }
+
+ @NotNull
+ @Override
+ public String getPanelDisplayName() {
+ return "Editor | " + getDisplayName() + " | " + colorsPage.getDisplayName();
+ }
+ };
+ return Collections.singletonList(panelFactory);
+ }
+ };
+ final Configurable[] configurables = colorAndFontOptions.buildConfigurables();
+ try {
+ final SearchableConfigurable general = colorAndFontOptions.findSubConfigurable(GeneralColorsPage.class);
+ if (general != null) {
+ final LineData lineData = getLineData(myLineNumber);
+ ShowSettingsUtil.getInstance().editConfigurable(myEditor.getProject(), general,
+ general.enableSearch(getAttributesKey(lineData).getExternalName()));
+ }
+ }
+ finally {
+ for (Configurable configurable : configurables) {
+ configurable.disposeUIResources();
+ }
+ colorAndFontOptions.disposeUIResources();
+ }
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageOptions.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptions.java
new file mode 100644
index 000000000000..4c348a18b784
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptions.java
@@ -0,0 +1,22 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+import javax.swing.*;
+
+/**
+ * @author traff
+ */
+public abstract class CoverageOptions {
+ public static final ExtensionPointName<CoverageOptions> EP_NAME = ExtensionPointName.create("com.intellij.coverageOptions");
+
+ public abstract JComponent getComponent();
+
+ public abstract boolean isModified();
+
+ public abstract void apply();
+
+ public abstract void reset();
+
+ public abstract void disposeUIResources();
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.form b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.form
new file mode 100644
index 000000000000..41de96e00c15
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.form
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.coverage.CoverageOptionsConfigurable.CoverageOptionsPanel">
+ <grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="66f0f" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title="When new coverage is gathered"/>
+ <children>
+ <component id="752a8" class="javax.swing.JRadioButton" binding="myShowOptionsRB" default-binding="true">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="&amp;Show options before applying coverage to the editor"/>
+ </properties>
+ </component>
+ <component id="f4cb4" class="javax.swing.JRadioButton" binding="myReplaceRB" default-binding="true">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="&amp;Replace active suites with the new one"/>
+ </properties>
+ </component>
+ <component id="61030" class="javax.swing.JRadioButton" binding="myAddRB" default-binding="true">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="A&amp;dd to the active suites"/>
+ </properties>
+ </component>
+ <component id="20e67" class="javax.swing.JRadioButton" binding="myDoNotApplyRB" default-binding="true">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Do &amp;not apply collected coverage"/>
+ </properties>
+ </component>
+ <component id="a9b9e" class="javax.swing.JCheckBox" binding="myActivateCoverageViewCB">
+ <constraints>
+ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <margin top="8" left="3" bottom="2" right="3"/>
+ <text value="Activate Coverage &amp;View "/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <vspacer id="f9751">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ </children>
+ </grid>
+ <buttonGroups>
+ <group name="myButtonGroup1">
+ <member id="752a8"/>
+ <member id="f4cb4"/>
+ <member id="61030"/>
+ <member id="20e67"/>
+ </group>
+ </buttonGroups>
+</form>
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.java
new file mode 100644
index 000000000000..4257791d25cf
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsConfigurable.java
@@ -0,0 +1,179 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 12/16/10
+ */
+public class CoverageOptionsConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+ private CoverageOptionsPanel myPanel;
+ private final CoverageOptionsProvider myManager;
+ private Project myProject;
+
+ public CoverageOptionsConfigurable(CoverageOptionsProvider manager, Project project) {
+ myManager = manager;
+ myProject = project;
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return "coverage";
+ }
+
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
+ @Nls
+ @Override
+ public String getDisplayName() {
+ return "Coverage";
+ }
+
+ @Override
+ public String getHelpTopic() {
+ return "reference.project.settings.coverage";
+ }
+
+ @Override
+ public JComponent createComponent() {
+ myPanel = new CoverageOptionsPanel();
+
+ List<JComponent> extensionPanels = collectExtensionOptionsComponents();
+
+ if (extensionPanels.size() > 0) {
+ return createCompositePanel(extensionPanels);
+ }
+ else {
+ return myPanel.myWholePanel;
+ }
+ }
+
+ private List<JComponent> collectExtensionOptionsComponents() {
+ List<JComponent> additionalPanels = ContainerUtil.newArrayList();
+ for (CoverageOptions coverageOptions : getExtensions()) {
+ additionalPanels.add(coverageOptions.getComponent());
+ }
+ return additionalPanels;
+ }
+
+ private JComponent createCompositePanel(List<JComponent> additionalPanels) {
+ final JPanel panel = new JPanel(new GridBagLayout());
+ final GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.gridx = 0;
+ c.gridy = GridBagConstraints.RELATIVE;
+ c.weightx = 1;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ panel.add(myPanel.myWholePanel, c);
+ for (JComponent p : additionalPanels) {
+ panel.add(p, c);
+ }
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ c.weighty = 1;
+ panel.add(Box.createVerticalBox(), c);
+ return panel;
+ }
+
+ private CoverageOptions[] getExtensions() {
+ return Extensions.getExtensions(CoverageOptions.EP_NAME, myProject);
+ }
+
+ @Override
+ public boolean isModified() {
+ if (myManager.getOptionToReplace() != getSelectedValue()) {
+ return true;
+ }
+
+ if (myManager.activateViewOnRun() != myPanel.myActivateCoverageViewCB.isSelected()) {
+ return true;
+ }
+
+ for (CoverageOptions coverageOptions : getExtensions()) {
+ if (coverageOptions.isModified()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ myManager.setOptionsToReplace(getSelectedValue());
+ myManager.setActivateViewOnRun(myPanel.myActivateCoverageViewCB.isSelected());
+ for (CoverageOptions coverageOptions : getExtensions()) {
+ coverageOptions.apply();
+ }
+ }
+
+ private int getSelectedValue() {
+ if (myPanel.myReplaceRB.isSelected()) {
+ return 0;
+ }
+ else if (myPanel.myAddRB.isSelected()) {
+ return 1;
+ }
+ else if (myPanel.myDoNotApplyRB.isSelected()) {
+ return 2;
+ }
+ return 3;
+ }
+
+ @Override
+ public void reset() {
+ final int addOrReplace = myManager.getOptionToReplace();
+ switch (addOrReplace) {
+ case 0:
+ myPanel.myReplaceRB.setSelected(true);
+ break;
+ case 1:
+ myPanel.myAddRB.setSelected(true);
+ break;
+ case 2:
+ myPanel.myDoNotApplyRB.setSelected(true);
+ break;
+ default:
+ myPanel.myShowOptionsRB.setSelected(true);
+ }
+
+ myPanel.myActivateCoverageViewCB.setSelected(myManager.activateViewOnRun());
+ for (CoverageOptions coverageOptions : getExtensions()) {
+ coverageOptions.reset();
+ }
+ }
+
+ @Override
+ public void disposeUIResources() {
+ myPanel = null;
+
+ for (CoverageOptions coverageOptions : getExtensions()) {
+ coverageOptions.disposeUIResources();
+ }
+ }
+
+ private static class CoverageOptionsPanel {
+ private JRadioButton myShowOptionsRB;
+ private JRadioButton myReplaceRB;
+ private JRadioButton myAddRB;
+ private JRadioButton myDoNotApplyRB;
+
+ private JPanel myWholePanel;
+ private JCheckBox myActivateCoverageViewCB;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsProvider.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsProvider.java
new file mode 100644
index 000000000000..137d71719b6f
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageOptionsProvider.java
@@ -0,0 +1,55 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.project.Project;
+
+/**
+ * User: anna
+ * Date: 4/28/11
+ */
+@State(
+ name = "CoverageOptionsProvider",
+ storages = {
+ @Storage( file = StoragePathMacros.WORKSPACE_FILE)
+ }
+)
+public class CoverageOptionsProvider implements PersistentStateComponent<CoverageOptionsProvider.State> {
+ private State myState = new State();
+
+ public static CoverageOptionsProvider getInstance(Project project) {
+ return ServiceManager.getService(project, CoverageOptionsProvider.class);
+ }
+
+ public int getOptionToReplace() {
+ return myState.myAddOrReplace;
+ }
+
+ public void setOptionsToReplace(int addOrReplace) {
+ myState.myAddOrReplace = addOrReplace;
+ }
+
+ public boolean activateViewOnRun() {
+ return myState.myActivateViewOnRun;
+ }
+
+ public void setActivateViewOnRun(boolean state) {
+ myState.myActivateViewOnRun = state;
+ }
+
+ @Override
+ public State getState() {
+ return myState;
+ }
+
+ @Override
+ public void loadState(State state) {
+ myState.myAddOrReplace = state.myAddOrReplace;
+ myState.myActivateViewOnRun = state.myActivateViewOnRun;
+ }
+
+ public static class State {
+ public int myAddOrReplace = 3;
+ public boolean myActivateViewOnRun = true;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageProjectViewDirectoryNodeDecorator.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageProjectViewDirectoryNodeDecorator.java
new file mode 100644
index 000000000000..27c1961e25b0
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageProjectViewDirectoryNodeDecorator.java
@@ -0,0 +1,73 @@
+package com.intellij.coverage;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ProjectViewNode;
+import com.intellij.packageDependencies.ui.PackageDependenciesNode;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.SmartPsiElementPointer;
+import com.intellij.ui.ColoredTreeCellRenderer;
+
+/**
+ * @author yole
+ */
+public class CoverageProjectViewDirectoryNodeDecorator extends AbstractCoverageProvejctViewNodeDecorator {
+ public CoverageProjectViewDirectoryNodeDecorator(final CoverageDataManager coverageDataManager) {
+ super(coverageDataManager);
+ }
+
+ public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) {
+ final PsiElement element = node.getPsiElement();
+ if (element == null || !element.isValid()) {
+ return;
+ }
+
+ final CoverageDataManager manager = getCoverageDataManager();
+ final CoverageSuitesBundle currentSuite = manager.getCurrentSuitesBundle();
+ final CoverageAnnotator coverageAnnotator = currentSuite != null ? currentSuite.getAnnotator(element.getProject()) : null;
+ if (coverageAnnotator == null) {
+ // N/A
+ return;
+ }
+
+ if (element instanceof PsiDirectory) {
+ final String informationString = coverageAnnotator.getDirCoverageInformationString((PsiDirectory) element, currentSuite, manager);
+ if (informationString != null) {
+ appendCoverageInfo(cellRenderer, informationString);
+ }
+ }
+ }
+
+ public void decorate(ProjectViewNode node, PresentationData data) {
+ final CoverageDataManager manager = getCoverageDataManager();
+ final CoverageSuitesBundle currentSuite = manager.getCurrentSuitesBundle();
+ final CoverageAnnotator coverageAnnotator = currentSuite != null ? currentSuite.getAnnotator(node.getProject())
+ : null;
+ if (coverageAnnotator == null) {
+ // N/A
+ return;
+ }
+
+ final Object value = node.getValue();
+ PsiElement element = null;
+ if (value instanceof PsiElement) {
+ element = (PsiElement)value;
+ }
+ else if (value instanceof SmartPsiElementPointer) {
+ element = ((SmartPsiElementPointer)value).getElement();
+ }
+
+ String informationString = null;
+ if (element instanceof PsiDirectory) {
+ informationString = coverageAnnotator.getDirCoverageInformationString((PsiDirectory)element, currentSuite, manager);
+ } else if (element instanceof PsiFile) {
+ informationString = coverageAnnotator.getFileCoverageInformationString((PsiFile)element, currentSuite, manager);
+ }
+
+ if (informationString != null) {
+ data.setLocationString(informationString);
+ }
+ }
+
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageRunner.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageRunner.java
new file mode 100644
index 000000000000..11c3b6db4278
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageRunner.java
@@ -0,0 +1,44 @@
+/*
+ * User: anna
+ * Date: 13-Feb-2008
+ */
+package com.intellij.coverage;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.rt.coverage.data.ProjectData;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public abstract class CoverageRunner {
+ public static final ExtensionPointName<CoverageRunner> EP_NAME = ExtensionPointName.create("com.intellij.coverageRunner");
+
+ public abstract ProjectData loadCoverageData(@NotNull final File sessionDataFile, @Nullable final CoverageSuite baseCoverageSuite);
+
+ public abstract String getPresentableName();
+
+ @NonNls
+ public abstract String getId();
+
+ @NonNls
+ public abstract String getDataFileExtension();
+
+ public abstract boolean acceptsCoverageEngine(@NotNull final CoverageEngine engine);
+
+ public static <T extends CoverageRunner> T getInstance(@NotNull Class<T> coverageRunnerClass) {
+ for (CoverageRunner coverageRunner : Extensions.getExtensions(EP_NAME)) {
+ if (coverageRunnerClass.isInstance(coverageRunner)) {
+ return coverageRunnerClass.cast(coverageRunner);
+ }
+ }
+ assert false;
+ return null;
+ }
+
+ public boolean isCoverageByTestApplicable() {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageRunnerData.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageRunnerData.java
new file mode 100644
index 000000000000..c859c04cdc1d
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageRunnerData.java
@@ -0,0 +1,18 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+/**
+ * User: anna
+ * Date: 9/30/11
+ */
+public class CoverageRunnerData implements RunnerSettings{
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {}
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {}
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageSuite.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuite.java
new file mode 100644
index 000000000000..5b618ae78594
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuite.java
@@ -0,0 +1,46 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.rt.coverage.data.ProjectData;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public interface CoverageSuite extends JDOMExternalizable {
+ boolean isValid();
+
+ @NotNull
+ String getCoverageDataFileName();
+
+ String getPresentableName();
+
+ long getLastCoverageTimeStamp();
+
+ @NotNull
+ CoverageFileProvider getCoverageDataFileProvider();
+
+ boolean isCoverageByTestApplicable();
+
+ boolean isCoverageByTestEnabled();
+
+ @Nullable
+ ProjectData getCoverageData(CoverageDataManager coverageDataManager);
+
+ void setCoverageData(final ProjectData projectData);
+
+ void restoreCoverageData();
+
+ boolean isTrackTestFolders();
+
+ boolean isTracingEnabled();
+
+ CoverageRunner getRunner();
+
+ @NotNull
+ CoverageEngine getCoverageEngine();
+
+ Project getProject();
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageSuiteListener.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuiteListener.java
new file mode 100644
index 000000000000..60c8fd2540de
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuiteListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 06-May-2009
+ */
+package com.intellij.coverage;
+
+public interface CoverageSuiteListener {
+ void beforeSuiteChosen();
+ void afterSuiteChosen();
+} \ No newline at end of file
diff --git a/plugins/coverage-common/src/com/intellij/coverage/CoverageSuitesBundle.java b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuitesBundle.java
new file mode 100644
index 000000000000..ad48a4272e64
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/CoverageSuitesBundle.java
@@ -0,0 +1,197 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.ModuleBasedConfiguration;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootModificationTracker;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScopesCore;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.reference.SoftReference;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.ArrayUtilRt;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 12/14/10
+ */
+public class CoverageSuitesBundle {
+ private CoverageSuite[] mySuites;
+ private CoverageEngine myEngine;
+
+ private Set<Module> myProcessedModules;
+
+ private CachedValue<GlobalSearchScope> myCachedValue;
+
+ private SoftReference<ProjectData> myData = new SoftReference<ProjectData>(null);
+ private static final Logger LOG = Logger.getInstance("#" + CoverageSuitesBundle.class.getName());
+
+ public CoverageSuitesBundle(CoverageSuite suite) {
+ this(new CoverageSuite[]{suite});
+ }
+
+ public CoverageSuitesBundle(CoverageSuite[] suites) {
+ mySuites = suites;
+ LOG.assertTrue(mySuites.length > 0);
+ myEngine = mySuites[0].getCoverageEngine();
+ for (CoverageSuite suite : suites) {
+ final CoverageEngine engine = suite.getCoverageEngine();
+ LOG.assertTrue(Comparing.equal(engine, myEngine));
+ }
+ }
+
+
+ public boolean isValid() {
+ for (CoverageSuite suite : mySuites) {
+ if (!suite.isValid()) return false;
+ }
+ return true;
+ }
+
+
+ public long getLastCoverageTimeStamp() {
+ long max = 0;
+ for (CoverageSuite suite : mySuites) {
+ max = Math.max(max, suite.getLastCoverageTimeStamp());
+ }
+ return max;
+ }
+
+ public boolean isCoverageByTestApplicable() {
+ for (CoverageSuite suite : mySuites) {
+ if (suite.isCoverageByTestApplicable()) return true;
+ }
+ return false;
+ }
+
+ public boolean isCoverageByTestEnabled() {
+ for (CoverageSuite suite : mySuites) {
+ if (suite.isCoverageByTestEnabled()) return true;
+ }
+ return false;
+ }
+
+ @Nullable
+ public ProjectData getCoverageData() {
+ final ProjectData projectData = myData.get();
+ if (projectData != null) return projectData;
+ ProjectData data = new ProjectData();
+ for (CoverageSuite suite : mySuites) {
+ final ProjectData coverageData = suite.getCoverageData(null);
+ if (coverageData != null) {
+ data.merge(coverageData);
+ }
+ }
+ myData = new SoftReference<ProjectData>(data);
+ return data;
+ }
+
+ public boolean isTrackTestFolders() {
+ for (CoverageSuite suite : mySuites) {
+ if (suite.isTrackTestFolders()) return true;
+ }
+ return false;
+ }
+
+ public boolean isTracingEnabled() {
+ for (CoverageSuite suite : mySuites) {
+ if (suite.isTracingEnabled()) return true;
+ }
+ return false;
+ }
+
+ @NotNull
+ public CoverageEngine getCoverageEngine() {
+ return myEngine;
+ }
+
+ public CoverageAnnotator getAnnotator(Project project) {
+ return myEngine.getCoverageAnnotator(project);
+ }
+
+ public CoverageSuite[] getSuites() {
+ return mySuites;
+ }
+
+ public boolean contains(CoverageSuite suite) {
+ return ArrayUtilRt.find(mySuites, suite) > -1;
+ }
+
+ public void setCoverageData(ProjectData projectData) {
+ myData = new SoftReference<ProjectData>(projectData);
+ }
+
+ public void restoreCoverageData() {
+ myData = new SoftReference<ProjectData>(null);
+ }
+
+ public String getPresentableName() {
+ return StringUtil.join(mySuites, new Function<CoverageSuite, String>() {
+ @Override
+ public String fun(CoverageSuite coverageSuite) {
+ return coverageSuite.getPresentableName();
+ }
+ }, ", ");
+ }
+
+ public boolean isModuleChecked(final Module module) {
+ return myProcessedModules != null && myProcessedModules.contains(module);
+ }
+
+ public void checkModule(final Module module) {
+ if (myProcessedModules == null) {
+ myProcessedModules = new HashSet<Module>();
+ }
+ myProcessedModules.add(module);
+ }
+
+ @Nullable
+ public RunConfigurationBase getRunConfiguration() {
+ for (CoverageSuite suite : mySuites) {
+ if (suite instanceof BaseCoverageSuite) {
+ final RunConfigurationBase configuration = ((BaseCoverageSuite)suite).getConfiguration();
+ if (configuration != null) {
+ return configuration;
+ }
+ }
+ }
+ return null;
+ }
+
+ public GlobalSearchScope getSearchScope(final Project project) {
+ if (myCachedValue == null) {
+ myCachedValue = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<GlobalSearchScope>() {
+ @Nullable
+ @Override
+ public Result<GlobalSearchScope> compute() {
+ return new Result<GlobalSearchScope>(getSearchScopeInner(project), ProjectRootModificationTracker.getInstance(project));
+ }
+ }, false);
+ }
+ return myCachedValue.getValue();
+
+ }
+
+ private GlobalSearchScope getSearchScopeInner(Project project) {
+ final RunConfigurationBase configuration = getRunConfiguration();
+ if (configuration instanceof ModuleBasedConfiguration) {
+ final Module module = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule();
+ if (module != null) {
+ return GlobalSearchScope.moduleRuntimeScope(module, isTrackTestFolders());
+ }
+ }
+ return isTrackTestFolders() ? GlobalSearchScope.projectScope(project) : GlobalSearchScopesCore.projectProductionScope(project);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/DefaultCoverageFileProvider.java b/plugins/coverage-common/src/com/intellij/coverage/DefaultCoverageFileProvider.java
new file mode 100644
index 000000000000..fff2ddd93c08
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/DefaultCoverageFileProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.coverage;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Jul 8, 2006
+ */
+public final class DefaultCoverageFileProvider implements CoverageFileProvider{
+ private final File myFile;
+ private final String mySourceProvider;
+
+ public DefaultCoverageFileProvider(String path) {
+ this(new File(path), DefaultCoverageFileProvider.class.getName());
+ }
+
+ public DefaultCoverageFileProvider(File file) {
+ this(file, DefaultCoverageFileProvider.class.getName());
+ }
+
+ public DefaultCoverageFileProvider(File file, String sourceProvider) {
+ myFile = file;
+ mySourceProvider = sourceProvider;
+ }
+
+ public String getCoverageDataFilePath() {
+ return myFile.getPath();
+ }
+
+ public boolean ensureFileExists() {
+ return myFile.exists();
+ }
+
+ public String getSourceProvider() {
+ return mySourceProvider;
+ }
+
+ public boolean isValid() {
+ return ensureFileExists();
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/SimpleCoverageAnnotator.java b/plugins/coverage-common/src/com/intellij/coverage/SimpleCoverageAnnotator.java
new file mode 100644
index 000000000000..82c4e717ba22
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/SimpleCoverageAnnotator.java
@@ -0,0 +1,434 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author traff
+ */
+public abstract class SimpleCoverageAnnotator extends BaseCoverageAnnotator {
+
+ private final Map<String, FileCoverageInfo> myFileCoverageInfos = new HashMap<String, FileCoverageInfo>();
+ private final Map<String, DirCoverageInfo> myTestDirCoverageInfos = new HashMap<String, DirCoverageInfo>();
+ private final Map<String, DirCoverageInfo> myDirCoverageInfos = new HashMap<String, DirCoverageInfo>();
+
+ public SimpleCoverageAnnotator(Project project) {
+ super(project);
+ }
+
+ @Override
+ public void onSuiteChosen(CoverageSuitesBundle newSuite) {
+ super.onSuiteChosen(newSuite);
+
+ myFileCoverageInfos.clear();
+ myTestDirCoverageInfos.clear();
+ myDirCoverageInfos.clear();
+ }
+
+ @Nullable
+ protected DirCoverageInfo getDirCoverageInfo(@NotNull final PsiDirectory directory,
+ @NotNull final CoverageSuitesBundle currentSuite) {
+ final VirtualFile dir = directory.getVirtualFile();
+
+ final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex();
+ //final Module module = projectFileIndex.getModuleForFile(dir);
+
+ final boolean isInTestContent = projectFileIndex.isInTestSourceContent(dir);
+ if (!currentSuite.isTrackTestFolders() && isInTestContent) {
+ return null;
+ }
+
+ final String path = normalizeFilePath(dir.getPath());
+
+ return isInTestContent ? myTestDirCoverageInfos.get(path) : myDirCoverageInfos.get(path);
+ }
+
+ @Nullable
+ public String getDirCoverageInformationString(@NotNull final PsiDirectory directory,
+ @NotNull final CoverageSuitesBundle currentSuite,
+ @NotNull final CoverageDataManager manager) {
+ DirCoverageInfo coverageInfo = getDirCoverageInfo(directory, currentSuite);
+ if (coverageInfo == null) {
+ return null;
+ }
+
+ if (manager.isSubCoverageActive()) {
+ return coverageInfo.coveredLineCount > 0 ? "covered" : null;
+ }
+
+ final String filesCoverageInfo = getFilesCoverageInformationString(coverageInfo);
+ if (filesCoverageInfo != null) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(filesCoverageInfo);
+ final String linesCoverageInfo = getLinesCoverageInformationString(coverageInfo);
+ if (linesCoverageInfo != null) {
+ builder.append(", ").append(linesCoverageInfo);
+ }
+ return builder.toString();
+ }
+ return null;
+ }
+
+ // SimpleCoverageAnnotator doesn't require normalized file paths any more
+ // so now coverage report should work w/o usage of this method
+ @Deprecated
+ public static String getFilePath(final String filePath) {
+ return normalizeFilePath(filePath);
+ }
+
+ private static @NotNull String normalizeFilePath(@NotNull String filePath) {
+ if (SystemInfo.isWindows) {
+ filePath = filePath.toLowerCase();
+ }
+ return FileUtil.toSystemIndependentName(filePath);
+ }
+
+ @Nullable
+ public String getFileCoverageInformationString(@NotNull final PsiFile psiFile,
+ @NotNull final CoverageSuitesBundle currentSuite,
+ @NotNull final CoverageDataManager manager) {
+ final VirtualFile file = psiFile.getVirtualFile();
+ assert file != null;
+ final String path = normalizeFilePath(file.getPath());
+
+ final FileCoverageInfo coverageInfo = myFileCoverageInfos.get(path);
+ if (coverageInfo == null) {
+ return null;
+ }
+
+ if (manager.isSubCoverageActive()) {
+ return coverageInfo.coveredLineCount > 0 ? "covered" : null;
+ }
+
+ return getLinesCoverageInformationString(coverageInfo);
+ }
+
+ @Nullable
+ protected FileCoverageInfo collectBaseFileCoverage(@NotNull final VirtualFile file,
+ @NotNull final Annotator annotator,
+ @NotNull final ProjectData projectData,
+ @NotNull final Map<String, String> normalizedFiles2Files)
+ {
+ final String filePath = normalizeFilePath(file.getPath());
+
+ // process file
+ final FileCoverageInfo info;
+
+ final ClassData classData = getClassData(filePath, projectData, normalizedFiles2Files);
+ if (classData != null) {
+ // fill info from coverage data
+ info = fileInfoForCoveredFile(classData);
+ }
+ else {
+ // file wasn't mentioned in coverage information
+ info = fillInfoForUncoveredFile(VfsUtilCore.virtualToIoFile(file));
+ }
+
+ if (info != null) {
+ annotator.annotateFile(filePath, info);
+ }
+ return info;
+ }
+
+ private static @Nullable ClassData getClassData(
+ final @NotNull String filePath,
+ final @NotNull ProjectData data,
+ final @NotNull Map<String, String> normalizedFiles2Files)
+ {
+ final String originalFileName = normalizedFiles2Files.get(filePath);
+ if (originalFileName == null) {
+ return null;
+ }
+ return data.getClassData(originalFileName);
+ }
+
+ @Nullable
+ protected DirCoverageInfo collectFolderCoverage(@NotNull final VirtualFile dir,
+ final @NotNull CoverageDataManager dataManager,
+ final Annotator annotator,
+ final ProjectData projectInfo, boolean trackTestFolders,
+ @NotNull final ProjectFileIndex index,
+ @NotNull final CoverageEngine coverageEngine,
+ Set<VirtualFile> visitedDirs,
+ @NotNull final Map<String, String> normalizedFiles2Files)
+ {
+ if (!index.isInContent(dir)) {
+ return null;
+ }
+
+ if (visitedDirs.contains(dir)) {
+ return null;
+ }
+
+ visitedDirs.add(dir);
+
+ final boolean isInTestSrcContent = index.isInTestSourceContent(dir);
+
+ // Don't count coverage for tests folders if track test folders is switched off
+ if (!trackTestFolders && isInTestSrcContent) {
+ return null;
+ }
+
+ final VirtualFile[] children = dataManager.doInReadActionIfProjectOpen(new Computable<VirtualFile[]>() {
+ public VirtualFile[] compute() {
+ return dir.getChildren();
+ }
+ });
+
+ if (children == null) {
+ return null;
+ }
+
+ final DirCoverageInfo dirCoverageInfo = new DirCoverageInfo();
+
+ for (VirtualFile fileOrDir : children) {
+ if (fileOrDir.isDirectory()) {
+ final DirCoverageInfo childCoverageInfo =
+ collectFolderCoverage(fileOrDir, dataManager, annotator, projectInfo, trackTestFolders, index,
+ coverageEngine, visitedDirs, normalizedFiles2Files);
+
+ if (childCoverageInfo != null) {
+ dirCoverageInfo.totalFilesCount += childCoverageInfo.totalFilesCount;
+ dirCoverageInfo.coveredFilesCount += childCoverageInfo.coveredFilesCount;
+ dirCoverageInfo.totalLineCount += childCoverageInfo.totalLineCount;
+ dirCoverageInfo.coveredLineCount += childCoverageInfo.coveredLineCount;
+ }
+ }
+ else if (coverageEngine.coverageProjectViewStatisticsApplicableTo(fileOrDir)) {
+ // let's count statistics only for ruby-based files
+
+ final FileCoverageInfo fileInfo =
+ collectBaseFileCoverage(fileOrDir, annotator, projectInfo, normalizedFiles2Files);
+
+ if (fileInfo != null) {
+ dirCoverageInfo.totalLineCount += fileInfo.totalLineCount;
+ dirCoverageInfo.totalFilesCount++;
+
+ if (fileInfo.coveredLineCount > 0) {
+ dirCoverageInfo.coveredFilesCount++;
+ dirCoverageInfo.coveredLineCount += fileInfo.coveredLineCount;
+ }
+ }
+ }
+ }
+
+
+ //TODO - toplevelFilesCoverage - is unused variable!
+
+ // no sense to include directories without ruby files
+ if (dirCoverageInfo.totalFilesCount == 0) {
+ return null;
+ }
+
+ final String dirPath = normalizeFilePath(dir.getPath());
+ if (isInTestSrcContent) {
+ annotator.annotateTestDirectory(dirPath, dirCoverageInfo);
+ }
+ else {
+ annotator.annotateSourceDirectory(dirPath, dirCoverageInfo);
+ }
+
+ return dirCoverageInfo;
+ }
+
+ public void annotate(@NotNull final VirtualFile contentRoot,
+ @NotNull final CoverageSuitesBundle suite,
+ final @NotNull CoverageDataManager dataManager, @NotNull final ProjectData data,
+ final Project project,
+ final Annotator annotator)
+ {
+ if (!contentRoot.isValid()) {
+ return;
+ }
+
+ // TODO: check name filter!!!!!
+
+ final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
+
+ @SuppressWarnings("unchecked") final Set<String> files = data.getClasses().keySet();
+ final Map<String, String> normalizedFiles2Files = ContainerUtil.newHashMap();
+ for (final String file : files) {
+ normalizedFiles2Files.put(normalizeFilePath(file), file);
+ }
+ collectFolderCoverage(contentRoot, dataManager, annotator, data,
+ suite.isTrackTestFolders(),
+ index,
+ suite.getCoverageEngine(),
+ ContainerUtil.<VirtualFile>newHashSet(),
+ Collections.unmodifiableMap(normalizedFiles2Files));
+ }
+
+ @Override
+ @Nullable
+ protected Runnable createRenewRequest(@NotNull final CoverageSuitesBundle suite, final @NotNull CoverageDataManager dataManager) {
+ final ProjectData data = suite.getCoverageData();
+ if (data == null) {
+ return null;
+ }
+
+ return new Runnable() {
+ public void run() {
+ final Project project = getProject();
+
+ final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
+
+ // find all modules content roots
+ final VirtualFile[] modulesContentRoots = dataManager.doInReadActionIfProjectOpen(new Computable<VirtualFile[]>() {
+ public VirtualFile[] compute() {
+ return rootManager.getContentRoots();
+ }
+ });
+
+ if (modulesContentRoots == null) {
+ return;
+ }
+
+ // gather coverage from all content roots
+ for (VirtualFile root : modulesContentRoots) {
+ annotate(root, suite, dataManager, data, project, new Annotator() {
+ public void annotateSourceDirectory(final String dirPath, final DirCoverageInfo info) {
+ myDirCoverageInfos.put(dirPath, info);
+ }
+
+ public void annotateTestDirectory(final String dirPath, final DirCoverageInfo info) {
+ myTestDirCoverageInfos.put(dirPath, info);
+ }
+
+ public void annotateFile(@NotNull final String filePath, @NotNull final FileCoverageInfo info) {
+ myFileCoverageInfos.put(filePath, info);
+ }
+ });
+ }
+
+ //final VirtualFile[] roots = ProjectRootManagerEx.getInstanceEx(project).getContentRootsFromAllModules();
+ //index.iterateContentUnderDirectory(roots[0], new ContentIterator() {
+ // public boolean processFile(final VirtualFile fileOrDir) {
+ // // TODO support for libraries and sdk
+ // if (index.isInContent(fileOrDir)) {
+ // final String normalizedPath = RubyCoverageEngine.rcovalizePath(fileOrDir.getPath(), (RubyCoverageSuite)suite);
+ //
+ // // TODO - check filters
+ //
+ // if (fileOrDir.isDirectory()) {
+ // //// process dir
+ // //if (index.isInTestSourceContent(fileOrDir)) {
+ // // //myTestDirCoverageInfos.put(RubyCoverageEngine.rcovalizePath(fileOrDir.getPath(), (RubyCoverageSuite)suite), )
+ // //} else {
+ // // myDirCoverageInfos.put(normalizedPath, new FileCoverageInfo());
+ // //}
+ // } else {
+ // // process file
+ // final ClassData classData = data.getOrCreateClassData(normalizedPath);
+ // if (classData != null) {
+ // final int count = classData.getLines().length;
+ // if (count != 0) {
+ // final FileCoverageInfo info = new FileCoverageInfo();
+ // info.totalLineCount = count;
+ // // let's count covered lines
+ // for (int i = 1; i <= count; i++) {
+ // final LineData lineData = classData.getLineData(i);
+ // if (lineData.getStatus() != LineCoverage.NONE){
+ // info.coveredLineCount++;
+ // }
+ // }
+ // myFileCoverageInfos.put(normalizedPath, info);
+ // }
+ // }
+ // }
+ // }
+ // return true;
+ // }
+ //});
+
+ dataManager.triggerPresentationUpdate();
+ }
+ };
+ }
+
+ @Nullable
+ protected String getLinesCoverageInformationString(@NotNull final FileCoverageInfo info) {
+ return calcCoveragePercentage(info) + "% lines covered";
+ }
+
+ protected static int calcCoveragePercentage(FileCoverageInfo info) {
+ return calcPercent(info.coveredLineCount, info.totalLineCount);
+ }
+
+ private static int calcPercent(final int covered, final int total) {
+ return total != 0 ? (int)((double)covered / total * 100) : 100;
+ }
+
+ @Nullable
+ protected String getFilesCoverageInformationString(@NotNull final DirCoverageInfo info) {
+ return calcPercent(info.coveredFilesCount, info.totalFilesCount) + "% files";
+ }
+
+ @Nullable
+ private static FileCoverageInfo fileInfoForCoveredFile(@NotNull final ClassData classData) {
+ final Object[] lines = classData.getLines();
+
+ // class data lines = [0, 1, ... count] but first element with index = #0 is fake and isn't
+ // used thus count = length = 1
+ final int count = lines.length - 1;
+
+ if (count == 0) {
+ return null;
+ }
+
+ final FileCoverageInfo info = new FileCoverageInfo();
+
+ int srcLinesCount = 0;
+ int coveredLinesCount = 0;
+ // let's count covered lines
+ for (int i = 1; i <= count; i++) {
+ final LineData lineData = classData.getLineData(i);
+ if (lineData == null) {
+ // Ignore not src code
+ continue;
+ }
+ final int status = lineData.getStatus();
+ // covered - if src code & covered (or inferred covered)
+ if (status != LineCoverage.NONE) {
+ coveredLinesCount++;
+ }
+ srcLinesCount++;
+ }
+ info.totalLineCount = srcLinesCount;
+ info.coveredLineCount = coveredLinesCount;
+ return info;
+ }
+
+ @Nullable
+ protected FileCoverageInfo fillInfoForUncoveredFile(@NotNull File file) {
+ return null;
+ }
+
+ private interface Annotator {
+ void annotateSourceDirectory(final String dirPath, final DirCoverageInfo info);
+
+ void annotateTestDirectory(final String dirPath, final DirCoverageInfo info);
+
+ void annotateFile(@NotNull final String filePath, @NotNull final FileCoverageInfo info);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/SrcFileAnnotator.java b/plugins/coverage-common/src/com/intellij/coverage/SrcFileAnnotator.java
new file mode 100644
index 000000000000..479211ec82f1
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/SrcFileAnnotator.java
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ */
+
+package com.intellij.coverage;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.history.FileRevisionTimestampComparator;
+import com.intellij.history.LocalHistory;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.impl.DocumentMarkupModel;
+import com.intellij.openapi.editor.markup.*;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.LineTokenizer;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.reference.SoftReference;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.util.Alarm;
+import com.intellij.util.Function;
+import com.intellij.util.diff.Diff;
+import com.intellij.util.diff.FilesTooBigForDiffException;
+import gnu.trove.TIntIntHashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author ven
+ */
+public class SrcFileAnnotator implements Disposable {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.coverage.SrcFileAnnotator");
+ public static final Key<List<RangeHighlighter>> COVERAGE_HIGHLIGHTERS = Key.create("COVERAGE_HIGHLIGHTERS");
+ private static final Key<DocumentListener> COVERAGE_DOCUMENT_LISTENER = Key.create("COVERAGE_DOCUMENT_LISTENER");
+ public static final Key<Map<FileEditor, EditorNotificationPanel>> NOTIFICATION_PANELS = Key.create("NOTIFICATION_PANELS");
+
+ private PsiFile myFile;
+ private Editor myEditor;
+ private Document myDocument;
+ private final Project myProject;
+
+ private SoftReference<TIntIntHashMap> myNewToOldLines;
+ private SoftReference<TIntIntHashMap> myOldToNewLines;
+ private SoftReference<byte[]> myOldContent;
+ private final static Object LOCK = new Object();
+
+ private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, this);
+
+ public SrcFileAnnotator(final PsiFile file, final Editor editor) {
+ myFile = file;
+ myEditor = editor;
+ myProject = file.getProject();
+ myDocument = myEditor.getDocument();
+ }
+
+
+ public void hideCoverageData() {
+ if (myEditor == null) return;
+ final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
+ final List<RangeHighlighter> highlighters = myEditor.getUserData(COVERAGE_HIGHLIGHTERS);
+ if (highlighters != null) {
+ for (final RangeHighlighter highlighter : highlighters) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ highlighter.dispose();
+ }
+ });
+ }
+ myEditor.putUserData(COVERAGE_HIGHLIGHTERS, null);
+ }
+
+ final Map<FileEditor, EditorNotificationPanel> map = myFile.getCopyableUserData(NOTIFICATION_PANELS);
+ if (map != null) {
+ final VirtualFile vFile = myFile.getVirtualFile();
+ LOG.assertTrue(vFile != null);
+ boolean freeAll = !fileEditorManager.isFileOpen(vFile);
+ myFile.putCopyableUserData(NOTIFICATION_PANELS, null);
+ for (FileEditor fileEditor : map.keySet()) {
+ if (!freeAll && !isCurrentEditor(fileEditor)) {
+ continue;
+ }
+ fileEditorManager.removeTopComponent(fileEditor, map.get(fileEditor));
+ }
+ }
+
+ final DocumentListener documentListener = myEditor.getUserData(COVERAGE_DOCUMENT_LISTENER);
+ if (documentListener != null) {
+ myDocument.removeDocumentListener(documentListener);
+ myEditor.putUserData(COVERAGE_DOCUMENT_LISTENER, null);
+ }
+ }
+
+ private static
+ @NotNull
+ String[] getCoveredLines(@NotNull byte[] oldContent, VirtualFile vFile) {
+ final String text = LoadTextUtil.getTextByBinaryPresentation(oldContent, vFile, false, false).toString();
+ return LineTokenizer.tokenize(text, false);
+ }
+
+ private
+ @NotNull
+ String[] getUpToDateLines() {
+ final Ref<String[]> linesRef = new Ref<String[]>();
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ final int lineCount = myDocument.getLineCount();
+ final String[] lines = new String[lineCount];
+ final CharSequence chars = myDocument.getCharsSequence();
+ for (int i = 0; i < lineCount; i++) {
+ lines[i] = chars.subSequence(myDocument.getLineStartOffset(i), myDocument.getLineEndOffset(i)).toString();
+ }
+ linesRef.set(lines);
+ }
+ };
+ ApplicationManager.getApplication().runReadAction(runnable);
+
+ return linesRef.get();
+ }
+
+ private static TIntIntHashMap getCoverageVersionToCurrentLineMapping(Diff.Change change, int firstNLines) {
+ TIntIntHashMap result = new TIntIntHashMap();
+ int prevLineInFirst = 0;
+ int prevLineInSecond = 0;
+ while (change != null) {
+
+ for (int l = 0; l < change.line0 - prevLineInFirst; l++) {
+ result.put(prevLineInFirst + l, prevLineInSecond + l);
+ }
+
+ prevLineInFirst = change.line0 + change.deleted;
+ prevLineInSecond = change.line1 + change.inserted;
+
+ change = change.link;
+ }
+
+ for (int i = prevLineInFirst; i < firstNLines; i++) {
+ result.put(i, prevLineInSecond + i - prevLineInFirst);
+ }
+
+ return result;
+ }
+
+ @Nullable
+ private TIntIntHashMap getOldToNewLineMapping(final long date) {
+ if (myOldToNewLines == null) {
+ myOldToNewLines = doGetLineMapping(date, true);
+ if (myOldToNewLines == null) return null;
+ }
+ return myOldToNewLines.get();
+ }
+
+ @Nullable
+ private TIntIntHashMap getNewToOldLineMapping(final long date) {
+ if (myNewToOldLines == null) {
+ myNewToOldLines = doGetLineMapping(date, false);
+ if (myNewToOldLines == null) return null;
+ }
+ return myNewToOldLines.get();
+ }
+
+ @Nullable
+ private SoftReference<TIntIntHashMap> doGetLineMapping(final long date, boolean oldToNew) {
+ final VirtualFile f = getVirtualFile();
+ final byte[] oldContent;
+ synchronized (LOCK) {
+ if (myOldContent == null) {
+ if (ApplicationManager.getApplication().isDispatchThread()) return null;
+ final byte[] byteContent = LocalHistory.getInstance().getByteContent(f, new FileRevisionTimestampComparator() {
+ public boolean isSuitable(long revisionTimestamp) {
+ return revisionTimestamp < date;
+ }
+ });
+ myOldContent = new SoftReference<byte[]>(byteContent);
+ }
+ oldContent = myOldContent.get();
+ }
+
+ if (oldContent == null) return null;
+ String[] coveredLines = getCoveredLines(oldContent, f);
+ String[] currentLines = getUpToDateLines();
+
+ String[] oldLines = oldToNew ? coveredLines : currentLines;
+ String[] newLines = oldToNew ? currentLines : coveredLines;
+
+ Diff.Change change = null;
+ try {
+ change = Diff.buildChanges(oldLines, newLines);
+ }
+ catch (FilesTooBigForDiffException e) {
+ LOG.info(e);
+ return null;
+ }
+ return new SoftReference<TIntIntHashMap>(getCoverageVersionToCurrentLineMapping(change, oldLines.length));
+ }
+
+ public void showCoverageInformation(final CoverageSuitesBundle suite) {
+ if (myEditor == null) return;
+ final MarkupModel markupModel = DocumentMarkupModel.forDocument(myDocument, myProject, true);
+ final List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
+ final ProjectData data = suite.getCoverageData();
+ if (data == null) {
+ coverageDataNotFound(suite);
+ return;
+ }
+ final CoverageEngine engine = suite.getCoverageEngine();
+ final Set<String> qualifiedNames = engine.getQualifiedNames(myFile);
+
+ // let's find old content in local history and build mapping from old lines to new one
+ // local history doesn't index libraries, so let's distinguish libraries content with other one
+ final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+ final VirtualFile file = getVirtualFile();
+
+ final long fileTimeStamp = file.getTimeStamp();
+ final long coverageTimeStamp = suite.getLastCoverageTimeStamp();
+ final TIntIntHashMap oldToNewLineMapping;
+
+ //do not show coverage info over cls
+ if (engine.isInLibraryClasses(myProject, file)) {
+ return;
+ }
+ // if in libraries content
+ if (projectFileIndex.isInLibrarySource(file)) {
+ // compare file and coverage timestamps
+ if (fileTimeStamp > coverageTimeStamp) {
+ showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
+ return;
+ }
+ oldToNewLineMapping = null;
+ }
+ else {
+ // check local history
+ oldToNewLineMapping = getOldToNewLineMapping(coverageTimeStamp);
+ if (oldToNewLineMapping == null) {
+
+ // if history for file isn't available let's check timestamps
+ if (fileTimeStamp > coverageTimeStamp && classesArePresentInCoverageData(data, qualifiedNames)) {
+ showEditorWarningMessage(CodeInsightBundle.message("coverage.data.outdated"));
+ return;
+ }
+ }
+ }
+
+ if (myEditor.getUserData(COVERAGE_HIGHLIGHTERS) != null) {
+ //highlighters already collected - no need to do it twice
+ return;
+ }
+
+ final Module module = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+ @Nullable
+ @Override
+ public Module compute() {
+ return ModuleUtil.findModuleForPsiElement(myFile);
+ }
+ });
+ if (module != null) {
+ if (engine.recompileProjectAndRerunAction(module, suite, new Runnable() {
+ public void run() {
+ CoverageDataManager.getInstance(myProject).chooseSuitesBundle(suite);
+ }
+ })) {
+ return;
+ }
+ }
+
+ // now if oldToNewLineMapping is null we should use f(x)=id(x) mapping
+
+ // E.g. all *.class files for java source file with several classes
+ final Set<File> outputFiles = engine.getCorrespondingOutputFiles(myFile, module, suite);
+
+ final boolean subCoverageActive = CoverageDataManager.getInstance(myProject).isSubCoverageActive();
+ final boolean coverageByTestApplicable = suite.isCoverageByTestApplicable() && !(subCoverageActive && suite.isCoverageByTestEnabled());
+ final TreeMap<Integer, LineData> executableLines = new TreeMap<Integer, LineData>();
+ final TreeMap<Integer, Object[]> classLines = new TreeMap<Integer, Object[]>();
+ final TreeMap<Integer, String> classNames = new TreeMap<Integer, String>();
+ class HighlightersCollector {
+ private void collect(File outputFile, final String qualifiedName) {
+ final ClassData fileData = data.getClassData(qualifiedName);
+ if (fileData != null) {
+ final Object[] lines = fileData.getLines();
+ if (lines != null) {
+ final Object[] postProcessedLines = suite.getCoverageEngine().postProcessExecutableLines(lines, myEditor);
+ for (Object lineData : postProcessedLines) {
+ if (lineData instanceof LineData) {
+ final int line = ((LineData)lineData).getLineNumber() - 1;
+ final int lineNumberInCurrent;
+ if (oldToNewLineMapping != null) {
+ // use mapping based on local history
+ if (!oldToNewLineMapping.contains(line)) {
+ continue;
+ }
+ lineNumberInCurrent = oldToNewLineMapping.get(line);
+ }
+ else {
+ // use id mapping
+ lineNumberInCurrent = line;
+ }
+ LOG.assertTrue(lineNumberInCurrent < myDocument.getLineCount());
+ executableLines.put(line, (LineData)lineData);
+
+ classLines.put(line, postProcessedLines);
+ classNames.put(line, qualifiedName);
+
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myDocument == null || lineNumberInCurrent >= myDocument.getLineCount()) return;
+ final RangeHighlighter highlighter =
+ createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines,
+ qualifiedName, line, lineNumberInCurrent, suite, postProcessedLines);
+ highlighters.add(highlighter);
+ }
+ });
+ }
+ }
+ }
+ }
+ else if (outputFile != null &&
+ !subCoverageActive &&
+ engine.includeUntouchedFileInCoverage(qualifiedName, outputFile, myFile, suite)) {
+ collectNonCoveredFileInfo(outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable);
+ }
+ }
+ }
+
+ final HighlightersCollector collector = new HighlightersCollector();
+ if (!outputFiles.isEmpty()) {
+ for (File outputFile : outputFiles) {
+ final String qualifiedName = engine.getQualifiedName(outputFile, myFile);
+ if (qualifiedName != null) {
+ collector.collect(outputFile, qualifiedName);
+ }
+ }
+ }
+ else { //check non-compilable classes which present in ProjectData
+ for (String qName : qualifiedNames) {
+ collector.collect(null, qName);
+ }
+ }
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myEditor != null && highlighters.size() > 0) {
+ myEditor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters);
+ }
+ }
+ });
+
+ final DocumentListener documentListener = new DocumentAdapter() {
+ @Override
+ public void documentChanged(final DocumentEvent e) {
+ myNewToOldLines = null;
+ myOldToNewLines = null;
+ List<RangeHighlighter> rangeHighlighters = myEditor.getUserData(COVERAGE_HIGHLIGHTERS);
+ if (rangeHighlighters == null) rangeHighlighters = new ArrayList<RangeHighlighter>();
+ int offset = e.getOffset();
+ final int lineNumber = myDocument.getLineNumber(offset);
+ final int lastLineNumber = myDocument.getLineNumber(offset + e.getNewLength());
+ final TextRange changeRange =
+ new TextRange(myDocument.getLineStartOffset(lineNumber), myDocument.getLineEndOffset(lastLineNumber));
+ for (Iterator<RangeHighlighter> it = rangeHighlighters.iterator(); it.hasNext(); ) {
+ final RangeHighlighter highlighter = it.next();
+ if (!highlighter.isValid() || TextRange.create(highlighter).intersects(changeRange)) {
+ highlighter.dispose();
+ it.remove();
+ }
+ }
+ final List<RangeHighlighter> highlighters = rangeHighlighters;
+ myUpdateAlarm.cancelAllRequests();
+ if (!myUpdateAlarm.isDisposed()) {
+ myUpdateAlarm.addRequest(new Runnable() {
+ @Override
+ public void run() {
+ final TIntIntHashMap newToOldLineMapping = getNewToOldLineMapping(suite.getLastCoverageTimeStamp());
+ if (newToOldLineMapping != null) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myEditor == null) return;
+ for (int line = lineNumber; line <= lastLineNumber; line++) {
+ final int oldLineNumber = newToOldLineMapping.get(line);
+ final LineData lineData = executableLines.get(oldLineNumber);
+ if (lineData != null) {
+ RangeHighlighter rangeHighlighter =
+ createRangeHighlighter(suite.getLastCoverageTimeStamp(), markupModel, coverageByTestApplicable, executableLines,
+ classNames.get(oldLineNumber), oldLineNumber, line, suite,
+ classLines.get(oldLineNumber));
+ highlighters.add(rangeHighlighter);
+ }
+ }
+ myEditor.putUserData(COVERAGE_HIGHLIGHTERS, highlighters.size() > 0 ? highlighters : null);
+ }
+ });
+ }
+ }
+ }, 100);
+ }
+ }
+ };
+ myDocument.addDocumentListener(documentListener);
+ myEditor.putUserData(COVERAGE_DOCUMENT_LISTENER, documentListener);
+ }
+
+ private static boolean classesArePresentInCoverageData(ProjectData data, Set<String> qualifiedNames) {
+ for (String qualifiedName : qualifiedNames) {
+ if (data.getClassData(qualifiedName) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private RangeHighlighter createRangeHighlighter(final long date, final MarkupModel markupModel,
+ final boolean coverageByTestApplicable,
+ final TreeMap<Integer, LineData> executableLines, @Nullable final String className,
+ final int line,
+ final int lineNumberInCurrent,
+ @NotNull final CoverageSuitesBundle coverageSuite, Object[] lines) {
+ EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
+ final TextAttributes attributes = scheme.getAttributes(CoverageLineMarkerRenderer.getAttributesKey(line, executableLines));
+ TextAttributes textAttributes = null;
+ if (attributes.getBackgroundColor() != null) {
+ textAttributes = attributes;
+ }
+ final int startOffset = myDocument.getLineStartOffset(lineNumberInCurrent);
+ final int endOffset = myDocument.getLineEndOffset(lineNumberInCurrent);
+ final RangeHighlighter highlighter =
+ markupModel.addRangeHighlighter(startOffset, endOffset, HighlighterLayer.SELECTION - 1, textAttributes, HighlighterTargetArea.LINES_IN_RANGE);
+ final Function<Integer, Integer> newToOldConverter = new Function<Integer, Integer>() {
+ public Integer fun(final Integer newLine) {
+ if (myEditor == null) return -1;
+ final TIntIntHashMap oldLineMapping = getNewToOldLineMapping(date);
+ return oldLineMapping != null ? oldLineMapping.get(newLine.intValue()) : newLine.intValue();
+ }
+ };
+ final Function<Integer, Integer> oldToNewConverter = new Function<Integer, Integer>() {
+ public Integer fun(final Integer newLine) {
+ if (myEditor == null) return -1;
+ final TIntIntHashMap newLineMapping = getOldToNewLineMapping(date);
+ return newLineMapping != null ? newLineMapping.get(newLine.intValue()) : newLine.intValue();
+ }
+ };
+ final CoverageLineMarkerRenderer markerRenderer = coverageSuite.getCoverageEngine()
+ .getLineMarkerRenderer(line, className, executableLines, coverageByTestApplicable, coverageSuite, newToOldConverter,
+ oldToNewConverter, CoverageDataManager.getInstance(myProject).isSubCoverageActive());
+ highlighter.setLineMarkerRenderer(markerRenderer);
+
+ final LineData lineData = className != null ? (LineData)lines[line + 1] : null;
+ if (lineData != null && lineData.getStatus() == LineCoverage.NONE) {
+ highlighter.setErrorStripeMarkColor(markerRenderer.getErrorStripeColor(myEditor));
+ highlighter.setThinErrorStripeMark(true);
+ highlighter.setGreedyToLeft(true);
+ highlighter.setGreedyToRight(true);
+ }
+ return highlighter;
+ }
+
+ private void showEditorWarningMessage(final String message) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myEditor == null) return;
+ final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
+ final VirtualFile vFile = myFile.getVirtualFile();
+ assert vFile != null;
+ Map<FileEditor, EditorNotificationPanel> map = myFile.getCopyableUserData(NOTIFICATION_PANELS);
+ if (map == null) {
+ map = new HashMap<FileEditor, EditorNotificationPanel>();
+ myFile.putCopyableUserData(NOTIFICATION_PANELS, map);
+ }
+
+ final FileEditor[] editors = fileEditorManager.getAllEditors(vFile);
+ for (final FileEditor editor : editors) {
+ if (isCurrentEditor(editor)) {
+ final EditorNotificationPanel panel = new EditorNotificationPanel() {
+ {
+ myLabel.setIcon(AllIcons.General.ExclMark);
+ myLabel.setText(message);
+ }
+ };
+ panel.createActionLabel("Close", new Runnable() {
+ @Override
+ public void run() {
+ fileEditorManager.removeTopComponent(editor, panel);
+ }
+ });
+ map.put(editor, panel);
+ fileEditorManager.addTopComponent(editor, panel);
+ break;
+ }
+ }
+ }
+ });
+ }
+
+ private boolean isCurrentEditor(FileEditor editor) {
+ return editor instanceof TextEditor && ((TextEditor)editor).getEditor() == myEditor;
+ }
+
+ private void collectNonCoveredFileInfo(final File outputFile,
+ final List<RangeHighlighter> highlighters, final MarkupModel markupModel,
+ final TreeMap<Integer, LineData> executableLines,
+ final boolean coverageByTestApplicable) {
+ final CoverageSuitesBundle coverageSuite = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle();
+ if (coverageSuite == null) return;
+ final TIntIntHashMap mapping;
+ if (outputFile.lastModified() < getVirtualFile().getTimeStamp()) {
+ mapping = getOldToNewLineMapping(outputFile.lastModified());
+ if (mapping == null) return;
+ }
+ else {
+ mapping = null;
+ }
+
+
+ final List<Integer> uncoveredLines = coverageSuite.getCoverageEngine().collectSrcLinesForUntouchedFile(outputFile, coverageSuite);
+
+ final int lineCount = myDocument.getLineCount();
+ if (uncoveredLines == null) {
+ for (int lineNumber = 0; lineNumber < lineCount; lineNumber++) {
+ addHighlighter(outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable, coverageSuite,
+ lineNumber, lineNumber);
+ }
+ }
+ else {
+ for (int lineNumber : uncoveredLines) {
+ if (lineNumber >= lineCount) {
+ continue;
+ }
+
+ final int updatedLineNumber = mapping != null ? mapping.get(lineNumber) : lineNumber;
+
+ addHighlighter(outputFile, highlighters, markupModel, executableLines, coverageByTestApplicable, coverageSuite,
+ lineNumber, updatedLineNumber);
+ }
+ }
+ }
+
+ private void addHighlighter(final File outputFile,
+ final List<RangeHighlighter> highlighters,
+ final MarkupModel markupModel,
+ final TreeMap<Integer, LineData> executableLines,
+ final boolean coverageByTestApplicable,
+ final CoverageSuitesBundle coverageSuite,
+ final int lineNumber,
+ final int updatedLineNumber) {
+ executableLines.put(updatedLineNumber, null);
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myEditor == null) return;
+ final RangeHighlighter highlighter =
+ createRangeHighlighter(outputFile.lastModified(), markupModel, coverageByTestApplicable, executableLines, null, lineNumber,
+ updatedLineNumber, coverageSuite, null);
+ highlighters.add(highlighter);
+ }
+ });
+ }
+
+ private VirtualFile getVirtualFile() {
+ final VirtualFile vFile = myFile.getVirtualFile();
+ LOG.assertTrue(vFile != null);
+ return vFile;
+ }
+
+
+ private void coverageDataNotFound(final CoverageSuitesBundle suite) {
+ showEditorWarningMessage(CodeInsightBundle.message("coverage.data.not.found"));
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ CoverageDataManager.getInstance(myProject).removeCoverageSuite(coverageSuite);
+ }
+ }
+
+ public void dispose() {
+ hideCoverageData();
+ myEditor = null;
+ myDocument = null;
+ myFile = null;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java b/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java
new file mode 100644
index 000000000000..eab0ea6bcb36
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java
@@ -0,0 +1,401 @@
+package com.intellij.coverage.actions;
+
+import com.intellij.coverage.*;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.*;
+import com.intellij.util.IconUtil;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.text.DateFormatUtil;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.*;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 11/27/10
+ */
+public class CoverageSuiteChooserDialog extends DialogWrapper {
+ @NonNls private static final String LOCAL = "Local";
+ private final Project myProject;
+ private final CheckboxTree mySuitesTree;
+ private final CoverageDataManager myCoverageManager;
+ private static final Logger LOG = Logger.getInstance("#" + CoverageSuiteChooserDialog.class.getName());
+ private final CheckedTreeNode myRootNode;
+ private CoverageEngine myEngine;
+
+ public CoverageSuiteChooserDialog(Project project) {
+ super(project, true);
+ myProject = project;
+ myCoverageManager = CoverageDataManager.getInstance(project);
+
+ myRootNode = new CheckedTreeNode("");
+ initTree();
+ mySuitesTree = new CheckboxTree(new SuitesRenderer(), myRootNode) {
+ protected void installSpeedSearch() {
+ new TreeSpeedSearch(this, new Convertor<TreePath, String>() {
+ public String convert(TreePath path) {
+ final DefaultMutableTreeNode component = (DefaultMutableTreeNode)path.getLastPathComponent();
+ final Object userObject = component.getUserObject();
+ if (userObject instanceof CoverageSuite) {
+ return ((CoverageSuite)userObject).getPresentableName();
+ }
+ return userObject.toString();
+ }
+ });
+ }
+ };
+ mySuitesTree.getEmptyText().appendText("No coverage suites configured.");
+ mySuitesTree.setRootVisible(false);
+ mySuitesTree.setShowsRootHandles(false);
+ TreeUtil.installActions(mySuitesTree);
+ TreeUtil.expandAll(mySuitesTree);
+ TreeUtil.selectFirstNode(mySuitesTree);
+ mySuitesTree.setMinimumSize(new Dimension(25, -1));
+ setOKButtonText("Show selected");
+ init();
+ setTitle("Choose Coverage Suite to Display");
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ return ScrollPaneFactory.createScrollPane(mySuitesTree);
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return mySuitesTree;
+ }
+
+ @Override
+ protected JComponent createNorthPanel() {
+ final DefaultActionGroup group = new DefaultActionGroup();
+ group.add(new AddExternalSuiteAction());
+ group.add(new DeleteSuiteAction());
+ group.add(new SwitchEngineAction());
+ return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
+ }
+
+ @Override
+ protected void doOKAction() {
+ final List<CoverageSuite> suites = collectSelectedSuites();
+ myCoverageManager.chooseSuitesBundle(suites.isEmpty() ? null : new CoverageSuitesBundle(suites.toArray(new CoverageSuite[suites.size()])));
+ super.doOKAction();
+ }
+
+ @NotNull
+ @Override
+ protected Action[] createActions() {
+ return new Action[]{getOKAction(), new NoCoverageAction(), getCancelAction()};
+ }
+
+ private Set<CoverageEngine> collectEngines() {
+ final Set<CoverageEngine> engines = new HashSet<CoverageEngine>();
+ for (CoverageSuite suite : myCoverageManager.getSuites()) {
+ engines.add(suite.getCoverageEngine());
+ }
+ return engines;
+ }
+
+ private static String getCoverageRunnerTitle(CoverageRunner coverageRunner) {
+ return coverageRunner.getPresentableName() + " Coverage";
+ }
+
+ @Nullable
+ private static CoverageRunner getCoverageRunner(VirtualFile file) {
+ for (CoverageRunner runner : Extensions.getExtensions(CoverageRunner.EP_NAME)) {
+ if (Comparing.strEqual(file.getExtension(), runner.getDataFileExtension())) return runner;
+ }
+ return null;
+ }
+
+ private List<CoverageSuite> collectSelectedSuites() {
+ final List<CoverageSuite> suites = new ArrayList<CoverageSuite>();
+ TreeUtil.traverse(myRootNode, new TreeUtil.Traverse() {
+ @Override
+ public boolean accept(Object treeNode) {
+ if (treeNode instanceof CheckedTreeNode && ((CheckedTreeNode)treeNode).isChecked()) {
+ final Object userObject = ((CheckedTreeNode)treeNode).getUserObject();
+ if (userObject instanceof CoverageSuite) {
+ suites.add((CoverageSuite)userObject);
+ }
+ }
+ return true;
+ }
+ });
+ return suites;
+ }
+
+ private void initTree() {
+ myRootNode.removeAllChildren();
+ final HashMap<CoverageRunner, Map<String, List<CoverageSuite>>> grouped =
+ new HashMap<CoverageRunner, Map<String, List<CoverageSuite>>>();
+ groupSuites(grouped, myCoverageManager.getSuites(), myEngine);
+ final CoverageSuitesBundle currentSuite = myCoverageManager.getCurrentSuitesBundle();
+ final List<CoverageRunner> runners = new ArrayList<CoverageRunner>(grouped.keySet());
+ Collections.sort(runners, new Comparator<CoverageRunner>() {
+ @Override
+ public int compare(CoverageRunner o1, CoverageRunner o2) {
+ return o1.getPresentableName().compareToIgnoreCase(o2.getPresentableName());
+ }
+ });
+ for (CoverageRunner runner : runners) {
+ final DefaultMutableTreeNode runnerNode = new DefaultMutableTreeNode(getCoverageRunnerTitle(runner));
+ final Map<String, List<CoverageSuite>> providers = grouped.get(runner);
+ final DefaultMutableTreeNode remoteNode = new DefaultMutableTreeNode("Remote");
+ if (providers.size() == 1) {
+ final String providersKey = providers.keySet().iterator().next();
+ DefaultMutableTreeNode suitesNode = runnerNode;
+ if (!Comparing.strEqual(providersKey, DefaultCoverageFileProvider.class.getName())) {
+ suitesNode = remoteNode;
+ runnerNode.add(remoteNode);
+ }
+ final List<CoverageSuite> suites = providers.get(providersKey);
+ Collections.sort(suites, new Comparator<CoverageSuite>() {
+ @Override
+ public int compare(CoverageSuite o1, CoverageSuite o2) {
+ return o1.getPresentableName().compareToIgnoreCase(o2.getPresentableName());
+ }
+ });
+ for (CoverageSuite suite : suites) {
+ final CheckedTreeNode treeNode = new CheckedTreeNode(suite);
+ treeNode.setChecked(currentSuite != null && currentSuite.contains(suite) ? Boolean.TRUE : Boolean.FALSE);
+ suitesNode.add(treeNode);
+ }
+ }
+ else {
+ final DefaultMutableTreeNode localNode = new DefaultMutableTreeNode(LOCAL);
+ runnerNode.add(localNode);
+ runnerNode.add(remoteNode);
+ for (String aClass : providers.keySet()) {
+ DefaultMutableTreeNode node = Comparing.strEqual(aClass, DefaultCoverageFileProvider.class.getName()) ? localNode : remoteNode;
+ for (CoverageSuite suite : providers.get(aClass)) {
+ final CheckedTreeNode treeNode = new CheckedTreeNode(suite);
+ treeNode.setChecked(currentSuite != null && currentSuite.contains(suite) ? Boolean.TRUE : Boolean.FALSE);
+ node.add(treeNode);
+ }
+ }
+ }
+ myRootNode.add(runnerNode);
+ }
+ }
+
+ private static void groupSuites(final HashMap<CoverageRunner, Map<String, List<CoverageSuite>>> grouped,
+ final CoverageSuite[] suites,
+ final CoverageEngine engine) {
+ for (CoverageSuite suite : suites) {
+ if (engine != null && suite.getCoverageEngine() != engine) continue;
+ final CoverageFileProvider provider = suite.getCoverageDataFileProvider();
+ if (provider instanceof DefaultCoverageFileProvider &&
+ Comparing.strEqual(((DefaultCoverageFileProvider)provider).getSourceProvider(), DefaultCoverageFileProvider.class.getName())) {
+ if (!provider.ensureFileExists()) continue;
+ }
+ final CoverageRunner runner = suite.getRunner();
+ Map<String, List<CoverageSuite>> byProviders = grouped.get(runner);
+ if (byProviders == null) {
+ byProviders = new HashMap<String, List<CoverageSuite>>();
+ grouped.put(runner, byProviders);
+ }
+ final String sourceProvider = provider instanceof DefaultCoverageFileProvider
+ ? ((DefaultCoverageFileProvider)provider).getSourceProvider()
+ : provider.getClass().getName();
+ List<CoverageSuite> list = byProviders.get(sourceProvider);
+ if (list == null) {
+ list = new ArrayList<CoverageSuite>();
+ byProviders.put(sourceProvider, list);
+ }
+ list.add(suite);
+ }
+ }
+
+ private void updateTree() {
+ ((DefaultTreeModel)mySuitesTree.getModel()).reload();
+ TreeUtil.expandAll(mySuitesTree);
+ }
+
+ private static class SuitesRenderer extends CheckboxTree.CheckboxTreeCellRenderer {
+ @Override
+ public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ if (value instanceof CheckedTreeNode) {
+ final Object userObject = ((CheckedTreeNode)value).getUserObject();
+ if (userObject instanceof CoverageSuite) {
+ CoverageSuite suite = (CoverageSuite)userObject;
+ getTextRenderer().append(suite.getPresentableName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ final String date = " (" + DateFormatUtil.formatPrettyDateTime(suite.getLastCoverageTimeStamp()) + ")";
+ getTextRenderer().append(date, SimpleTextAttributes.GRAY_ATTRIBUTES);
+ }
+ }
+ else if (value instanceof DefaultMutableTreeNode) {
+ final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
+ if (userObject instanceof String) {
+ getTextRenderer().append((String)userObject);
+ }
+ }
+ }
+ }
+
+ private class NoCoverageAction extends DialogWrapperAction {
+ public NoCoverageAction() {
+ super("&No Coverage");
+ }
+
+ @Override
+ protected void doAction(ActionEvent e) {
+ myCoverageManager.chooseSuitesBundle(null);
+ CoverageSuiteChooserDialog.this.close(DialogWrapper.OK_EXIT_CODE);
+ }
+ }
+
+ private class AddExternalSuiteAction extends AnAction {
+ public AddExternalSuiteAction() {
+ super("Add", "Add", IconUtil.getAddIcon());
+ registerCustomShortcutSet(CommonShortcuts.INSERT, mySuitesTree);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final VirtualFile file =
+ FileChooser.chooseFile(new FileChooserDescriptor(true, false, false, false, false, false) {
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return getCoverageRunner(file) != null;
+ }
+ }, myProject, null);
+ if (file != null) {
+ final CoverageRunner coverageRunner = getCoverageRunner(file);
+ LOG.assertTrue(coverageRunner != null);
+
+ final CoverageSuite coverageSuite = myCoverageManager
+ .addExternalCoverageSuite(file.getName(), file.getTimeStamp(), coverageRunner,
+ new DefaultCoverageFileProvider(file.getPath()));
+
+ final String coverageRunnerTitle = getCoverageRunnerTitle(coverageRunner);
+ DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(myRootNode, coverageRunnerTitle);
+ if (node == null) {
+ node = new DefaultMutableTreeNode(coverageRunnerTitle);
+ myRootNode.add(node);
+ }
+ if (node.getChildCount() > 0) {
+ final TreeNode childNode = node.getChildAt(0);
+ if (!(childNode instanceof CheckedTreeNode)) {
+ if (LOCAL.equals(((DefaultMutableTreeNode)childNode).getUserObject())) {
+ node = (DefaultMutableTreeNode)childNode;
+ } else {
+ final DefaultMutableTreeNode localNode = new DefaultMutableTreeNode(LOCAL);
+ node.add(localNode);
+ node = localNode;
+ }
+ }
+ }
+ final CheckedTreeNode suiteNode = new CheckedTreeNode(coverageSuite);
+ suiteNode.setChecked(true);
+ node.add(suiteNode);
+ TreeUtil.sort(node, new Comparator() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ if (o1 instanceof CheckedTreeNode && o2 instanceof CheckedTreeNode) {
+ final Object userObject1 = ((CheckedTreeNode)o1).getUserObject();
+ final Object userObject2 = ((CheckedTreeNode)o2).getUserObject();
+ if (userObject1 instanceof CoverageSuite && userObject2 instanceof CoverageSuite) {
+ final String presentableName1 = ((CoverageSuite)userObject1).getPresentableName();
+ final String presentableName2 = ((CoverageSuite)userObject2).getPresentableName();
+ return presentableName1.compareToIgnoreCase(presentableName2);
+ }
+ }
+ return 0;
+ }
+ });
+ updateTree();
+ TreeUtil.selectNode(mySuitesTree, suiteNode);
+ }
+ }
+ }
+
+ private class DeleteSuiteAction extends AnAction {
+ public DeleteSuiteAction() {
+ super("Delete", "Delete", PlatformIcons.DELETE_ICON);
+ registerCustomShortcutSet(CommonShortcuts.getDelete(), mySuitesTree);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final CheckedTreeNode[] selectedNodes = mySuitesTree.getSelectedNodes(CheckedTreeNode.class, null);
+ for (CheckedTreeNode selectedNode : selectedNodes) {
+ final Object userObject = selectedNode.getUserObject();
+ if (userObject instanceof CoverageSuite) {
+ final CoverageSuite selectedSuite = (CoverageSuite)userObject;
+ if (selectedSuite.getCoverageDataFileProvider() instanceof DefaultCoverageFileProvider &&
+ Comparing.strEqual(((DefaultCoverageFileProvider)selectedSuite.getCoverageDataFileProvider()).getSourceProvider(),
+ DefaultCoverageFileProvider.class.getName())) {
+ myCoverageManager.removeCoverageSuite(selectedSuite);
+ TreeUtil.removeLastPathComponent(mySuitesTree, new TreePath(selectedNode.getPath()));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ final CheckedTreeNode[] selectedSuites = mySuitesTree.getSelectedNodes(CheckedTreeNode.class, null);
+ final Presentation presentation = e.getPresentation();
+ presentation.setEnabled(false);
+ for (CheckedTreeNode node : selectedSuites) {
+ final Object userObject = node.getUserObject();
+ if (userObject instanceof CoverageSuite) {
+ final CoverageSuite selectedSuite = (CoverageSuite)userObject;
+ if (selectedSuite.getCoverageDataFileProvider() instanceof DefaultCoverageFileProvider &&
+ Comparing.strEqual(((DefaultCoverageFileProvider)selectedSuite.getCoverageDataFileProvider()).getSourceProvider(),
+ DefaultCoverageFileProvider.class.getName())) {
+ presentation.setEnabled(true);
+ }
+ }
+ }
+ }
+ }
+
+ private class SwitchEngineAction extends ComboBoxAction {
+ @NotNull
+ @Override
+ protected DefaultActionGroup createPopupActionGroup(JComponent button) {
+ final DefaultActionGroup engChooser = new DefaultActionGroup();
+ for (final CoverageEngine engine : collectEngines()) {
+ engChooser.add(new AnAction(engine.getPresentableText()) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ myEngine = engine;
+ initTree();
+ updateTree();
+ }
+ });
+ }
+ return engChooser;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setVisible(collectEngines().size() > 1);
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/GenerateCoverageReportAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/GenerateCoverageReportAction.java
new file mode 100644
index 000000000000..b4b7ba15dc3a
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/GenerateCoverageReportAction.java
@@ -0,0 +1,52 @@
+/*
+ * User: anna
+ * Date: 20-Nov-2007
+ */
+package com.intellij.coverage.actions;
+
+import com.intellij.codeInspection.export.ExportToHTMLDialog;
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageEngine;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.project.Project;
+
+public class GenerateCoverageReportAction extends AnAction {
+
+ public void actionPerformed(final AnActionEvent e) {
+ final DataContext dataContext = e.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ assert project != null;
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(project);
+ final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle();
+
+
+ final CoverageEngine coverageEngine = currentSuite.getCoverageEngine();
+ final ExportToHTMLDialog dialog = coverageEngine.createGenerateReportDialog(project, dataContext, currentSuite);
+ dialog.reset();
+ dialog.show();
+ if (!dialog.isOK()) return;
+ dialog.apply();
+
+ coverageEngine.generateReport(project, dataContext, currentSuite);
+ }
+
+ public void update(final AnActionEvent e) {
+ final DataContext dataContext = e.getDataContext();
+ final Presentation presentation = e.getPresentation();
+ presentation.setEnabled(false);
+ presentation.setVisible(false);
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (project != null) {
+ final CoverageSuitesBundle currentSuite = CoverageDataManager.getInstance(project).getCurrentSuitesBundle();
+ if (currentSuite != null) {
+ final CoverageEngine coverageEngine = currentSuite.getCoverageEngine();
+ if (coverageEngine.isReportGenerationAvailable(project, dataContext, currentSuite)) {
+ presentation.setEnabled(true);
+ presentation.setVisible(true);
+ }
+ }
+ }
+ }
+
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/HideCoverageInfoAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/HideCoverageInfoAction.java
new file mode 100644
index 000000000000..84167d277353
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/HideCoverageInfoAction.java
@@ -0,0 +1,34 @@
+package com.intellij.coverage.actions;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.project.Project;
+
+/**
+* User: anna
+* Date: 2/14/12
+*/
+public class HideCoverageInfoAction extends AnAction {
+ public HideCoverageInfoAction() {
+ super("&Hide Coverage Data", "Hide coverage data", AllIcons.Actions.Cancel);
+ }
+
+ public void actionPerformed(final AnActionEvent e) {
+ CoverageDataManager.getInstance(e.getData(CommonDataKeys.PROJECT)).chooseSuitesBundle(null);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ final Presentation presentation = e.getPresentation();
+ presentation.setEnabled(false);
+ presentation.setVisible(ActionPlaces.isToolbarPlace(e.getPlace()));
+ final Project project = e.getData(CommonDataKeys.PROJECT);
+ if (project != null) {
+ final CoverageSuitesBundle suitesBundle = CoverageDataManager.getInstance(project).getCurrentSuitesBundle();
+ presentation.setEnabled(suitesBundle != null);
+ presentation.setVisible(suitesBundle != null);
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java
new file mode 100644
index 000000000000..82ed52031cb1
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/ShowCoveringTestsAction.java
@@ -0,0 +1,184 @@
+/*
+ * User: anna
+ * Date: 29-May-2008
+ */
+package com.intellij.coverage.actions;
+
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.ImplementationViewComponent;
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageSuite;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.PanelWithText;
+import com.intellij.openapi.ui.popup.ComponentPopupBuilder;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.ui.popup.NotLookupOrSearchCondition;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.*;
+
+public class ShowCoveringTestsAction extends AnAction {
+ private static final Logger LOG = Logger.getInstance("#" + ShowCoveringTestsAction.class.getName());
+
+ private final String myClassFQName;
+ private final LineData myLineData;
+
+ public ShowCoveringTestsAction(final String classFQName, LineData lineData) {
+ super("Show tests covering line", "Show tests covering line", PlatformIcons.TEST_SOURCE_FOLDER);
+ myClassFQName = classFQName;
+ myLineData = lineData;
+ }
+
+ public void actionPerformed(final AnActionEvent e) {
+ final DataContext context = e.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(context);
+ LOG.assertTrue(project != null);
+ final Editor editor = CommonDataKeys.EDITOR.getData(context);
+ LOG.assertTrue(editor != null);
+
+ final CoverageSuitesBundle currentSuite = CoverageDataManager.getInstance(project).getCurrentSuitesBundle();
+ LOG.assertTrue(currentSuite != null);
+
+ final File[] traceFiles = getTraceFiles(project);
+
+ final Set<String> tests = new HashSet<String>();
+ Runnable runnable = new Runnable() {
+ public void run() {
+ for (File traceFile : traceFiles) {
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new FileInputStream(traceFile));
+ extractTests(traceFile, in, tests);
+ }
+ catch (Exception ex) {
+ LOG.error(traceFile.getName(), ex);
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch (IOException ex) {
+ LOG.error(ex);
+ }
+ }
+ }
+ }
+ };
+
+ if (ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, "Extract information about tests", false, project)) { //todo cache them? show nothing found message
+ final String[] testNames = ArrayUtil.toStringArray(tests);
+ Arrays.sort(testNames);
+ if (testNames.length == 0) {
+ HintManager.getInstance().showErrorHint(editor, "Failed to load covered tests");
+ return;
+ }
+ final List<PsiElement> elements = currentSuite.getCoverageEngine().findTestsByNames(testNames, project);
+ final ImplementationViewComponent component;
+ final String title = "Tests covering line " + myClassFQName + ":" + myLineData.getLineNumber();
+ final ComponentPopupBuilder popupBuilder;
+ if (!elements.isEmpty()) {
+ component = new ImplementationViewComponent(PsiUtilCore.toPsiElementArray(elements), 0);
+ popupBuilder = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component.getPreferredFocusableComponent())
+ .setDimensionServiceKey(project, "ShowTestsPopup", false)
+ .setCouldPin(new Processor<JBPopup>() {
+ @Override
+ public boolean process(JBPopup popup) {
+ component.showInUsageView();
+ popup.cancel();
+ return false;
+ }
+ });
+ } else {
+ component = null;
+ final JPanel panel = new PanelWithText("Following test" + (testNames.length > 1 ? "s" : "") + " could not be found: " + StringUtil.join(testNames, ",").replace("_", "."));
+ popupBuilder = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null);
+ }
+ final JBPopup popup = popupBuilder.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
+ .setProject(project)
+ .setResizable(true)
+ .setMovable(true)
+ .setTitle(title)
+ .createPopup();
+ popup.showInBestPositionFor(editor);
+
+ if (component != null) {
+ component.setHint(popup, title);
+ }
+ }
+ }
+
+ private void extractTests(final File traceFile, final DataInputStream in, final Set<String> tests) throws IOException {
+ long traceSize = in.readInt();
+ for (int i = 0; i < traceSize; i++) {
+ final String className = in.readUTF();
+ final int linesSize = in.readInt();
+ for(int l = 0; l < linesSize; l++) {
+ final int line = in.readInt();
+ if (Comparing.strEqual(className, myClassFQName)) {
+ if (myLineData.getLineNumber() == line) {
+ tests.add(FileUtil.getNameWithoutExtension(traceFile));
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ final Presentation presentation = e.getPresentation();
+ presentation.setEnabled(false);
+ if (myLineData != null && myLineData.getStatus() != LineCoverage.NONE) {
+ final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ if (project != null) {
+ final File[] files = getTraceFiles(project);
+ if (files != null && files.length > 0) {
+ presentation.setEnabled(CoverageDataManager.getInstance(project).getCurrentSuitesBundle().isCoverageByTestEnabled());
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private static File[] getTraceFiles(Project project) {
+ final CoverageSuitesBundle currentSuite = CoverageDataManager.getInstance(project).getCurrentSuitesBundle();
+ if (currentSuite == null) return null;
+ final List<File> files = new ArrayList<File>();
+ for (CoverageSuite coverageSuite : currentSuite.getSuites()) {
+
+ final String filePath = coverageSuite.getCoverageDataFileName();
+ final String dirName = FileUtil.getNameWithoutExtension(new File(filePath).getName());
+
+ final File parentDir = new File(filePath).getParentFile();
+ final File tracesDir = new File(parentDir, dirName);
+ final File[] suiteFiles = tracesDir.listFiles();
+ if (suiteFiles != null) {
+ Collections.addAll(files, suiteFiles);
+ }
+ }
+
+ return files.isEmpty() ? null : files.toArray(new File[files.size()]);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/SwitchCoverageSuiteAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/SwitchCoverageSuiteAction.java
new file mode 100644
index 000000000000..c046c94f1d5c
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/SwitchCoverageSuiteAction.java
@@ -0,0 +1,25 @@
+package com.intellij.coverage.actions;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author ven
+ */
+public class SwitchCoverageSuiteAction extends AnAction {
+
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ new CoverageSuiteChooserDialog(project).show();
+ }
+
+ public void update(AnActionEvent e) {
+ super.update(e);
+ Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ e.getPresentation().setEnabled(project != null);
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageAction.java b/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageAction.java
new file mode 100644
index 000000000000..e8ea5e1211dd
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageAction.java
@@ -0,0 +1,167 @@
+/*
+ * User: anna
+ * Date: 19-Nov-2007
+ */
+package com.intellij.coverage.actions;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageExecutor;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.execution.Executor;
+import com.intellij.execution.Location;
+import com.intellij.execution.configurations.ModuleBasedConfiguration;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.execution.testframework.TestConsoleProperties;
+import com.intellij.execution.testframework.TestFrameworkRunningModel;
+import com.intellij.execution.testframework.ToggleModelAction;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.Alarm;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TrackCoverageAction extends ToggleModelAction {
+ private final TestConsoleProperties myProperties;
+ private TestFrameworkRunningModel myModel;
+ private TreeSelectionListener myTreeSelectionListener;
+
+ public TrackCoverageAction(TestConsoleProperties properties) {
+ super("Show coverage per test", "Show coverage per test", AllIcons.RunConfigurations.TrackCoverage, properties,
+ TestConsoleProperties.TRACK_CODE_COVERAGE);
+ myProperties = properties;
+
+ }
+
+ public void setSelected(final AnActionEvent e, final boolean state) {
+ super.setSelected(e, state);
+ if (!TestConsoleProperties.TRACK_CODE_COVERAGE.value(myProperties)) {
+ restoreMergedCoverage();
+ } else {
+ selectSubCoverage();
+ }
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return super.isSelected(e) && CoverageDataManager.getInstance(myProperties.getProject()).isSubCoverageActive();
+ }
+
+ private void restoreMergedCoverage() {
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(myProperties.getProject());
+ if (coverageDataManager.isSubCoverageActive()) {
+ final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle();
+ if (currentSuite != null) {
+ coverageDataManager.restoreMergedCoverage(currentSuite);
+ }
+ }
+ }
+
+ public void setModel(final TestFrameworkRunningModel model) {
+ if (myModel != null) myModel.getTreeView().removeTreeSelectionListener(myTreeSelectionListener);
+ myModel = model;
+ if (model != null) {
+ myTreeSelectionListener = new MyTreeSelectionListener();
+ model.getTreeView().addTreeSelectionListener(myTreeSelectionListener);
+ Disposer.register(model, new Disposable() {
+ public void dispose() {
+ restoreMergedCoverage();
+ }
+ });
+ }
+ }
+
+ protected boolean isEnabled() {
+ final CoverageSuitesBundle suite = getCurrentCoverageSuite();
+ return suite != null && suite.isCoverageByTestApplicable() && suite.isCoverageByTestEnabled();
+ }
+
+ @Override
+ protected boolean isVisible() {
+ final CoverageSuitesBundle suite = getCurrentCoverageSuite();
+ return suite != null && suite.isCoverageByTestApplicable();
+ }
+
+ @Nullable
+ private CoverageSuitesBundle getCurrentCoverageSuite() {
+ if (myModel == null) {
+ return null;
+ }
+
+ final RunConfiguration runConf = myModel.getProperties().getConfiguration();
+ if (runConf instanceof ModuleBasedConfiguration) {
+
+ // if coverage supported for run configuration
+ if (CoverageEnabledConfiguration.isApplicableTo((ModuleBasedConfiguration) runConf)) {
+
+ // Get coverage settings
+ Executor executor = myProperties.getExecutor();
+ if (executor != null && executor.getId().equals(CoverageExecutor.EXECUTOR_ID)) {
+ return CoverageDataManager.getInstance(myProperties.getProject()).getCurrentSuitesBundle();
+ }
+ }
+ }
+ return null;
+ }
+
+ private void selectSubCoverage() {
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(myProperties.getProject());
+ final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle();
+ if (currentSuite != null) {
+ final AbstractTestProxy test = myModel.getTreeView().getSelectedTest();
+ List<String> testMethods = new ArrayList<String>();
+ if (test != null && !test.isInProgress()) {
+ final List<? extends AbstractTestProxy> list = test.getAllTests();
+ for (AbstractTestProxy proxy : list) {
+ final Location location = proxy.getLocation(myProperties.getProject(), myProperties.getScope());
+ if (location != null) {
+ final PsiElement element = location.getPsiElement();
+ final String name = currentSuite.getCoverageEngine().getTestMethodName(element, proxy);
+ if (name != null) {
+ testMethods.add(name);
+ }
+ }
+ }
+ }
+ coverageDataManager.selectSubCoverage(currentSuite, testMethods);
+ }
+ }
+
+ private class MyTreeSelectionListener implements TreeSelectionListener {
+ private final Alarm myUpdateCoverageAlarm;
+
+ public MyTreeSelectionListener() {
+ myUpdateCoverageAlarm = new Alarm(myModel);
+ }
+
+ public void valueChanged(final TreeSelectionEvent e) {
+ if (myUpdateCoverageAlarm.isDisposed()) return;
+ if (!TestConsoleProperties.TRACK_CODE_COVERAGE.value(myModel.getProperties()) || !isEnabled()) return;
+ myUpdateCoverageAlarm.cancelAllRequests();
+ final Project project = myModel.getProperties().getProject();
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(project);
+ final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle();
+ if (currentSuite != null) {
+ if (ApplicationManager.getApplication().isDispatchThread()) {
+ myUpdateCoverageAlarm.addRequest(new Runnable() {
+ public void run() {
+ selectSubCoverage();
+ }
+ }, 300);
+ } else {
+ if (coverageDataManager.isSubCoverageActive()) coverageDataManager.restoreMergedCoverage(currentSuite);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageActionProvider.java b/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageActionProvider.java
new file mode 100644
index 000000000000..aed5a84f7178
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/actions/TrackCoverageActionProvider.java
@@ -0,0 +1,15 @@
+/*
+ * User: anna
+ * Date: 28-Aug-2009
+ */
+package com.intellij.coverage.actions;
+
+import com.intellij.execution.testframework.ToggleModelActionProvider;
+import com.intellij.execution.testframework.ToggleModelAction;
+import com.intellij.execution.testframework.TestConsoleProperties;
+
+public class TrackCoverageActionProvider implements ToggleModelActionProvider{
+ public ToggleModelAction createToggleModelAction(TestConsoleProperties properties) {
+ return new TrackCoverageAction(properties);
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListNode.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListNode.java
new file mode 100644
index 000000000000..feecdc8aeb14
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListNode.java
@@ -0,0 +1,159 @@
+package com.intellij.coverage.view;
+
+import com.intellij.codeInsight.navigation.NavigationUtil;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.navigation.NavigationItem;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vcs.FileStatus;
+import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtilCore;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+* User: anna
+* Date: 1/2/12
+*/
+public class CoverageListNode extends AbstractTreeNode {
+ protected CoverageSuitesBundle myBundle;
+ protected CoverageViewManager.StateBean myStateBean;
+ private final FileStatusManager myFileStatusManager;
+
+ public CoverageListNode(Project project,
+ final PsiNamedElement classOrPackage,
+ CoverageSuitesBundle bundle,
+ CoverageViewManager.StateBean stateBean) {
+ super(project, classOrPackage);
+ myName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Override
+ public String compute() {
+ return classOrPackage.getName();
+ }
+ });
+ myBundle = bundle;
+ myStateBean = stateBean;
+ myFileStatusManager = FileStatusManager.getInstance(myProject);
+ }
+
+ @NotNull
+ @Override
+ public Collection<? extends AbstractTreeNode> getChildren() {
+ final Object[] children = CoverageViewTreeStructure.getChildren(this, myBundle, myStateBean);
+ return (Collection<CoverageListNode>)Arrays.asList((CoverageListNode[])children);
+ }
+
+ @Override
+ protected void update(final PresentationData presentation) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final Object value = getValue();
+ if (value instanceof PsiNamedElement) {
+
+ if (value instanceof PsiQualifiedNamedElement &&
+ (myStateBean.myFlattenPackages && ((PsiNamedElement)value).getContainingFile() == null ||
+ getParent() instanceof CoverageListRootNode)) {
+ presentation.setPresentableText(((PsiQualifiedNamedElement)value).getQualifiedName());
+ }
+ else {
+ presentation.setPresentableText(((PsiNamedElement)value).getName());
+ }
+ presentation.setIcon(((PsiElement)value).getIcon(0));
+ }
+ }
+ });
+ }
+
+ @Override
+ public FileStatus getFileStatus() {
+ final PsiFile containingFile = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ @Nullable
+ @Override
+ public PsiFile compute() {
+ Object value = getValue();
+ if (value instanceof PsiElement && ((PsiElement)value).isValid()) {
+ return ((PsiElement)value).getContainingFile();
+ }
+ return null;
+ }
+ });
+ return containingFile != null ? myFileStatusManager.getStatus(containingFile.getVirtualFile()) : super.getFileStatus();
+ }
+
+ @Override
+ public boolean canNavigate() {
+ final Object value = getValue();
+ return value instanceof PsiElement && ((PsiElement)value).isValid() && ((PsiElement)value).getContainingFile() != null;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return canNavigate();
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ if (canNavigate()) {
+ final PsiNamedElement value = (PsiNamedElement)getValue();
+ if (requestFocus) {
+ NavigationUtil.activateFileWithPsiElement(value, true);
+ }
+ else if (value instanceof NavigationItem) {
+ ((NavigationItem)value).navigate(requestFocus);
+ }
+ }
+ }
+
+ @Override
+ public int getWeight() {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
+ @Override
+ public Integer compute() {
+ //todo weighted
+ final Object value = getValue();
+ if (value instanceof PsiElement && ((PsiElement)value).getContainingFile() != null) return 40;
+ return 30;
+ }
+ });
+ }
+
+ public boolean contains(VirtualFile file) {
+ final Object value = getValue();
+ if (value instanceof PsiElement) {
+ final boolean equalContainingFile = Comparing.equal(PsiUtilCore.getVirtualFile((PsiElement)value), file);
+ if (equalContainingFile) return true;
+ }
+ if (value instanceof PsiDirectory) {
+ return contains(file, (PsiDirectory)value);
+ }
+ else if (value instanceof PsiDirectoryContainer) {
+ final PsiDirectory[] directories = ((PsiDirectoryContainer)value).getDirectories();
+ for (PsiDirectory directory : directories) {
+ if (contains(file, directory)) return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean contains(VirtualFile file, PsiDirectory value) {
+ if (myStateBean.myFlattenPackages) {
+ return Comparing.equal(((PsiDirectory)value).getVirtualFile(), file.getParent());
+ }
+
+ if (VfsUtilCore.isAncestor(((PsiDirectory)value).getVirtualFile(), file, false)) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListRootNode.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListRootNode.java
new file mode 100644
index 000000000000..b7191407435f
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageListRootNode.java
@@ -0,0 +1,45 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiNamedElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 1/5/12
+ */
+public class CoverageListRootNode extends CoverageListNode {
+ private List<AbstractTreeNode> myTopLevelPackages;
+ private final Project myProject;
+
+ public CoverageListRootNode(Project project, PsiNamedElement classOrPackage,
+ CoverageSuitesBundle bundle,
+ CoverageViewManager.StateBean stateBean) {
+ super(project, classOrPackage, bundle, stateBean);
+ myProject = classOrPackage.getProject();
+ }
+
+ private List<AbstractTreeNode> getTopLevelPackages(CoverageSuitesBundle bundle, CoverageViewManager.StateBean stateBean, Project project) {
+ if (myTopLevelPackages == null) {
+ myTopLevelPackages = bundle.getCoverageEngine().createCoverageViewExtension(project, bundle, stateBean).createTopLevelNodes();
+ for (AbstractTreeNode abstractTreeNode : myTopLevelPackages) {
+ abstractTreeNode.setParent(this);
+ }
+ }
+ return myTopLevelPackages;
+ }
+
+ @NotNull
+ @Override
+ public Collection<? extends AbstractTreeNode> getChildren() {
+ if (myStateBean.myFlattenPackages) {
+ return getTopLevelPackages(myBundle, myStateBean, myProject);
+ }
+ return super.getChildren();
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageTableModel.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageTableModel.java
new file mode 100644
index 000000000000..fa0fe0739a60
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageTableModel.java
@@ -0,0 +1,105 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageEngine;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.commander.AbstractListBuilder;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.ui.ColumnInfo;
+import com.intellij.util.ui.SortableColumnModel;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 1/3/12
+ */
+class CoverageTableModel extends AbstractTableModel implements AbstractListBuilder.Model, SortableColumnModel {
+ private final ColumnInfo[] COLUMN_INFOS;
+
+ final List myElements = new ArrayList();
+
+ public CoverageTableModel(@NotNull CoverageSuitesBundle suitesBundle, CoverageViewManager.StateBean stateBean, Project project) {
+ final CoverageEngine coverageEngine = suitesBundle.getCoverageEngine();
+ COLUMN_INFOS = coverageEngine.createCoverageViewExtension(project, suitesBundle, stateBean).createColumnInfos();
+ }
+
+ public void removeAllElements() {
+ myElements.clear();
+ fireTableDataChanged();
+ }
+
+ public void addElement(final Object obj) {
+ myElements.add(obj);
+ fireTableDataChanged();
+ }
+
+ public void replaceElements(final List newElements) {
+ removeAllElements();
+ myElements.addAll(newElements);
+ fireTableDataChanged();
+ }
+
+ public Object[] toArray() {
+ return ArrayUtil.toObjectArray(myElements);
+ }
+
+ public int indexOf(final Object o) {
+ return myElements.indexOf(o);
+ }
+
+ public int getSize() {
+ return myElements.size();
+ }
+
+ public Object getElementAt(final int index) {
+ return myElements.get(index);
+ }
+
+ public int getRowCount() {
+ return myElements.size();
+ }
+
+ public int getColumnCount() {
+ return COLUMN_INFOS.length;
+ }
+
+ @Override
+ public String getColumnName(int column) {
+ return COLUMN_INFOS[column].getName();
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ final Object element = getElementAt(rowIndex);
+ if (columnIndex == 0) {
+ return element;
+ }
+ else if (element instanceof CoverageListNode) {
+ return COLUMN_INFOS[columnIndex].valueOf(element);
+ }
+ return element;
+ }
+
+ public ColumnInfo[] getColumnInfos() {
+ return COLUMN_INFOS;
+ }
+
+ public void setSortable(boolean aBoolean) {
+ }
+
+ public boolean isSortable() {
+ return true;
+ }
+
+ public Object getRowValue(int row) {
+ return getElementAt(row);
+ }
+
+ public RowSorter.SortKey getDefaultSortKey() {
+ return null;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageView.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageView.java
new file mode 100644
index 000000000000..c616e76f7dad
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageView.java
@@ -0,0 +1,345 @@
+package com.intellij.coverage.view;
+
+import com.intellij.CommonBundle;
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.impl.RunDialog;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.actions.CloseTabToolbarAction;
+import com.intellij.ide.actions.ContextHelpAction;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.ui.StatusText;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * User: anna
+ * Date: 1/2/12
+ */
+public class CoverageView extends JPanel implements DataProvider, Disposable {
+ @NonNls private static final String ACTION_DRILL_DOWN = "DrillDown";
+ @NonNls private static final String ACTION_GO_UP = "GoUp";
+ @NonNls private static final String HELP_ID = "reference.toolWindows.Coverage";
+
+ private CoverageTableModel myModel;
+ private JBTable myTable;
+ private CoverageViewBuilder myBuilder;
+ private final Project myProject;
+ private final CoverageViewManager.StateBean myStateBean;
+
+
+ public CoverageView(final Project project, final CoverageDataManager dataManager, CoverageViewManager.StateBean stateBean) {
+ super(new BorderLayout());
+ myProject = project;
+ myStateBean = stateBean;
+ final JLabel titleLabel = new JLabel();
+ final CoverageSuitesBundle suitesBundle = dataManager.getCurrentSuitesBundle();
+ myModel = new CoverageTableModel(suitesBundle, stateBean, project);
+
+ myTable = new JBTable(myModel);
+ final StatusText emptyText = myTable.getEmptyText();
+ emptyText.setText("No coverage results.");
+ final RunConfigurationBase configuration = suitesBundle.getRunConfiguration();
+ if (configuration != null) {
+ emptyText.appendText(" Click ");
+ emptyText.appendText("Edit", SimpleTextAttributes.LINK_ATTRIBUTES, new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ final String configurationName = configuration.getName();
+ final RunnerAndConfigurationSettings configurationSettings = RunManagerEx.getInstanceEx(project).findConfigurationByName(configurationName);
+ if (configurationSettings != null) {
+ RunDialog.editConfiguration(project, configurationSettings, "Edit Run Configuration");
+ } else {
+ Messages.showErrorDialog(project, "Configuration \'" + configurationName + "\' was not found", CommonBundle.getErrorTitle());
+ }
+ }
+ });
+ emptyText.appendText(" to fix configuration settings.");
+ }
+ myTable.getColumnModel().getColumn(0).setCellRenderer(new NodeDescriptorTableCellRenderer());
+ myTable.getTableHeader().setReorderingAllowed(false);
+ JPanel centerPanel = new JPanel(new BorderLayout());
+ centerPanel.add(ScrollPaneFactory.createScrollPane(myTable), BorderLayout.CENTER);
+ centerPanel.add(titleLabel, BorderLayout.NORTH);
+ add(centerPanel, BorderLayout.CENTER);
+ final CoverageViewTreeStructure structure = new CoverageViewTreeStructure(project, suitesBundle, stateBean);
+ myBuilder = new CoverageViewBuilder(project, new JBList(), myModel, structure, myTable);
+ myBuilder.setParentTitle(titleLabel);
+ new DoubleClickListener() {
+ @Override
+ protected boolean onDoubleClick(MouseEvent e) {
+ drillDown(structure);
+ return true;
+ }
+ }.installOn(myTable);
+ final TableSpeedSearch speedSearch = new TableSpeedSearch(myTable);
+ speedSearch.setClearSearchOnNavigateNoMatch(true);
+ PopupHandler.installUnknownPopupHandler(myTable, createPopupGroup(), ActionManager.getInstance());
+ TableScrollingUtil.installActions(myTable);
+
+ myTable.registerKeyboardAction(new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ if (myBuilder == null) return;
+ myBuilder.buildRoot();
+ }
+ }, KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SLASH, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
+
+ myTable.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ACTION_DRILL_DOWN);
+ myTable.getInputMap(WHEN_FOCUSED).put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK), ACTION_DRILL_DOWN);
+ myTable.getActionMap().put(ACTION_DRILL_DOWN, new AbstractAction() {
+ public void actionPerformed(final ActionEvent e) {
+ drillDown(structure);
+ }
+ });
+ myTable.getInputMap(WHEN_FOCUSED).put(
+ KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK), ACTION_GO_UP);
+ myTable.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), ACTION_GO_UP);
+ myTable.getActionMap().put(ACTION_GO_UP, new AbstractAction() {
+ public void actionPerformed(final ActionEvent e) {
+ goUp();
+ }
+ });
+
+ final JComponent component =
+ ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, createToolbarActions(structure), false).getComponent();
+ add(component, BorderLayout.WEST);
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ private static ActionGroup createPopupGroup() {
+ final DefaultActionGroup actionGroup = new DefaultActionGroup();
+ actionGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE));
+ return actionGroup;
+ }
+
+ private ActionGroup createToolbarActions(final CoverageViewTreeStructure treeStructure) {
+ final DefaultActionGroup actionGroup = new DefaultActionGroup();
+ actionGroup.add(new GoUpAction(treeStructure));
+ if (treeStructure.supportFlattenPackages()) {
+ actionGroup.add(new FlattenPackagesAction());
+ }
+
+ installAutoScrollToSource(actionGroup);
+ installAutoScrollFromSource(actionGroup);
+
+ actionGroup.add(ActionManager.getInstance().getAction("GenerateCoverageReport"));
+ actionGroup.add(new CloseTabToolbarAction() {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ CoverageDataManager.getInstance(myProject).chooseSuitesBundle(null);
+ }
+ });
+ actionGroup.add(new ContextHelpAction(HELP_ID));
+ return actionGroup;
+ }
+
+ private void installAutoScrollFromSource(DefaultActionGroup actionGroup) {
+ final MyAutoScrollFromSourceHandler handler = new MyAutoScrollFromSourceHandler();
+ handler.install();
+ actionGroup.add(handler.createToggleAction());
+ }
+
+ private void installAutoScrollToSource(DefaultActionGroup actionGroup) {
+ AutoScrollToSourceHandler autoScrollToSourceHandler = new AutoScrollToSourceHandler(){
+ @Override
+ protected boolean isAutoScrollMode() {
+ return myStateBean.myAutoScrollToSource;
+ }
+
+ @Override
+ protected void setAutoScrollMode(boolean state) {
+ myStateBean.myAutoScrollToSource = state;
+ }
+ };
+ autoScrollToSourceHandler.install(myTable);
+ actionGroup.add(autoScrollToSourceHandler.createToggleAction());
+ }
+
+ public void goUp() {
+ if (myBuilder == null) {
+ return;
+ }
+ myBuilder.goUp();
+ }
+
+ private void drillDown(CoverageViewTreeStructure treeStructure) {
+ final AbstractTreeNode element = getSelectedValue();
+ if (element == null) return;
+ if (treeStructure.getChildElements(element).length == 0) {
+ if (element.canNavigate()) {
+ element.navigate(true);
+ }
+ return;
+ }
+ myBuilder.drillDown();
+ }
+
+ public void updateParentTitle() {
+ myBuilder.updateParentTitle();
+ }
+
+ private AbstractTreeNode getSelectedValue() {
+ return (AbstractTreeNode)myBuilder.getSelectedValue();
+ }
+
+ private boolean topElementIsSelected(final CoverageViewTreeStructure treeStructure) {
+ if (myTable == null) return false;
+ if (myModel.getSize() >= 1) {
+ final AbstractTreeNode rootElement = (AbstractTreeNode)treeStructure.getRootElement();
+ final AbstractTreeNode node = (AbstractTreeNode)myModel.getElementAt(0);
+ if (node.getParent() == rootElement) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean canSelect(VirtualFile file) {
+ return myBuilder.canSelect(file);
+ }
+
+ public void select(VirtualFile file) {
+ myBuilder.select(file);
+ }
+
+ public Object getData(@NonNls String dataId) {
+ if (CommonDataKeys.NAVIGATABLE.is(dataId)) {
+ return getSelectedValue();
+ }
+ if (PlatformDataKeys.HELP_ID.is(dataId)) {
+ return HELP_ID;
+ }
+ return null;
+ }
+
+ private static class NodeDescriptorTableCellRenderer extends DefaultTableCellRenderer {
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
+ final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ if (value instanceof NodeDescriptor) {
+ NodeDescriptor descriptor = (NodeDescriptor)value;
+ setIcon(descriptor.getIcon());
+ setText(descriptor.toString());
+ if (!isSelected) setForeground(((CoverageListNode)descriptor).getFileStatus().getColor());
+ }
+ return component;
+ }
+ }
+
+ private class FlattenPackagesAction extends ToggleAction {
+
+ private FlattenPackagesAction() {
+ super("Flatten Packages", "Flatten Packages", AllIcons.ObjectBrowser.FlattenPackages);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return myStateBean.myFlattenPackages;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ myStateBean.myFlattenPackages = state;
+ final Object selectedValue = myBuilder.getSelectedValue();
+ myBuilder.buildRoot();
+
+ if (selectedValue != null) {
+ myBuilder.select(((CoverageListNode)selectedValue).getValue());
+ }
+ myBuilder.ensureSelectionExist();
+ myBuilder.updateParentTitle();
+ }
+ }
+
+ private class GoUpAction extends AnAction {
+
+ private final CoverageViewTreeStructure myTreeStructure;
+
+ public GoUpAction(CoverageViewTreeStructure treeStructure) {
+ super("Go Up", "Go to Upper Level", AllIcons.Nodes.UpLevel);
+ myTreeStructure = treeStructure;
+ registerCustomShortcutSet(KeyEvent.VK_BACK_SPACE, 0, myTable);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ goUp();
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ e.getPresentation().setEnabled(!topElementIsSelected(myTreeStructure));
+ }
+ }
+
+ private class MyAutoScrollFromSourceHandler extends AutoScrollFromSourceHandler {
+ public MyAutoScrollFromSourceHandler() {
+ super(CoverageView.this.myProject, CoverageView.this, CoverageView.this);
+ }
+
+ @Override
+ protected boolean isAutoScrollEnabled() {
+ return myStateBean.myAutoScrollFromSource;
+ }
+
+ @Override
+ protected void setAutoScrollEnabled(boolean state) {
+ myStateBean.myAutoScrollFromSource = state;
+ }
+
+ @Override
+ protected void selectElementFromEditor(@NotNull FileEditor editor) {
+ if (myProject.isDisposed() || !CoverageView.this.isShowing()) return;
+ if (myStateBean.myAutoScrollFromSource) {
+ final VirtualFile file = FileEditorManagerEx.getInstanceEx(myProject).getFile(editor);
+ if (file != null) {
+ if (canSelect(file)) {
+ PsiElement e = null;
+ if (editor instanceof TextEditor) {
+ final int offset = ((TextEditor)editor).getEditor().getCaretModel().getOffset();
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+ final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
+ if (psiFile != null) {
+ e = psiFile.findElementAt(offset);
+ }
+ }
+ myBuilder.select(e != null ? e : file);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewBuilder.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewBuilder.java
new file mode 100644
index 000000000000..91bc7e363987
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewBuilder.java
@@ -0,0 +1,143 @@
+package com.intellij.coverage.view;
+
+import com.intellij.ide.commander.AbstractListBuilder;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.ide.util.treeView.AbstractTreeStructure;
+import com.intellij.ide.util.treeView.AlphaComparator;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.vcs.FileStatusListener;
+import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.TableUtil;
+import com.intellij.ui.table.JBTable;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 1/2/12
+ */
+public class CoverageViewBuilder extends AbstractListBuilder {
+ private final JBTable myTable;
+ private final FileStatusListener myFileStatusListener;
+ private CoverageViewExtension myCoverageViewExtension;
+
+ CoverageViewBuilder(final Project project,
+ final JList list,
+ final Model model,
+ final AbstractTreeStructure treeStructure, final JBTable table) {
+ super(project, list, model, treeStructure, AlphaComparator.INSTANCE, false);
+ myTable = table;
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, "Building coverage report...") {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ buildRoot();
+ }
+
+ @Override
+ public void onSuccess() {
+ ensureSelectionExist();
+ updateParentTitle();
+ }
+ });
+ myFileStatusListener = new FileStatusListener() {
+ @Override
+ public void fileStatusesChanged() {
+ table.repaint();
+ }
+
+ @Override
+ public void fileStatusChanged(@NotNull VirtualFile virtualFile) {
+ table.repaint();
+ }
+ };
+ myCoverageViewExtension = ((CoverageViewTreeStructure)myTreeStructure).myData
+ .getCoverageEngine().createCoverageViewExtension(myProject, ((CoverageViewTreeStructure)myTreeStructure).myData,
+ ((CoverageViewTreeStructure)myTreeStructure).myStateBean);
+ FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener);
+ }
+
+ @Override
+ public void dispose() {
+ FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener);
+ super.dispose();
+ }
+
+ @Override
+ protected boolean shouldEnterSingleTopLevelElement(Object rootChild) {
+ return false;
+ }
+
+ @Override
+ protected boolean shouldAddTopElement() {
+ return false;
+ }
+
+ @Override
+ protected boolean nodeIsAcceptableForElement(AbstractTreeNode node, Object element) {
+ return Comparing.equal(node.getValue(), element);
+ }
+
+ @Override
+ protected List<AbstractTreeNode> getAllAcceptableNodes(Object[] childElements, VirtualFile file) {
+ ArrayList<AbstractTreeNode> result = new ArrayList<AbstractTreeNode>();
+
+ for (Object childElement1 : childElements) {
+ CoverageListNode childElement = (CoverageListNode)childElement1;
+ if (childElement.contains(file)) result.add(childElement);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void updateParentTitle() {
+ if (myParentTitle == null) return;
+
+ final Object rootElement = myTreeStructure.getRootElement();
+ AbstractTreeNode node = getParentNode();
+ if (node == null) {
+ node = (AbstractTreeNode)rootElement;
+ }
+
+ if (node instanceof CoverageListRootNode) {
+ myParentTitle.setText(myCoverageViewExtension.getSummaryForRootNode(node));
+ }
+ else {
+ myParentTitle.setText(myCoverageViewExtension.getSummaryForNode(node));
+ }
+ }
+
+ @Override
+ public Object getSelectedValue() {
+ final int row = myTable.getSelectedRow();
+ if (row == -1) return null;
+ return myModel.getElementAt(myTable.convertRowIndexToModel(row));
+ }
+
+ @Override
+ protected void ensureSelectionExist() {
+ TableUtil.ensureSelectionExists(myTable);
+ }
+
+ @Override
+ protected void selectItem(int i) {
+ TableUtil.selectRows(myTable, new int[]{myTable.convertRowIndexToView(i)});
+ TableUtil.scrollSelectionToVisible(myTable);
+ }
+
+ public boolean canSelect(VirtualFile file) {
+ return myCoverageViewExtension.canSelectInCoverageView(file);
+ }
+
+ public void select(Object object) {
+ selectElement(myCoverageViewExtension.getElementToSelect(object), myCoverageViewExtension.getVirtualFile(object));
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewDescriptor.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewDescriptor.java
new file mode 100644
index 000000000000..c54561d08704
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewDescriptor.java
@@ -0,0 +1,28 @@
+package com.intellij.coverage.view;
+
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiNamedElement;
+
+/**
+ * User: anna
+ * Date: 1/2/12
+ */
+public class CoverageViewDescriptor extends NodeDescriptor {
+ private final Object myClassOrPackage;
+
+ public CoverageViewDescriptor(final Project project, final NodeDescriptor parentDescriptor, final Object classOrPackage) {
+ super(project, parentDescriptor);
+ myClassOrPackage = classOrPackage;
+ myName = classOrPackage instanceof PsiNamedElement ? ((PsiNamedElement)classOrPackage).getName() : classOrPackage.toString();
+ }
+
+ public boolean update() {
+ return false;
+ }
+
+ public Object getElement() {
+ return myClassOrPackage;
+ }
+}
+ \ No newline at end of file
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewExtension.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewExtension.java
new file mode 100644
index 000000000000..eb69b6104a0a
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewExtension.java
@@ -0,0 +1,82 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.ui.ColumnInfo;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+public abstract class CoverageViewExtension {
+
+ protected final Project myProject;
+ protected final CoverageSuitesBundle mySuitesBundle;
+ protected final CoverageViewManager.StateBean myStateBean;
+ protected final CoverageDataManager myCoverageDataManager;
+ protected final CoverageViewManager myCoverageViewManager;
+
+ public CoverageViewExtension(Project project, CoverageSuitesBundle suitesBundle, CoverageViewManager.StateBean stateBean) {
+ myProject = project;
+ mySuitesBundle = suitesBundle;
+ myStateBean = stateBean;
+ myCoverageDataManager = CoverageDataManager.getInstance(myProject);
+ myCoverageViewManager = CoverageViewManager.getInstance(myProject);
+ }
+
+ @Nullable
+ public abstract String getSummaryForNode(AbstractTreeNode node);
+
+ @Nullable
+ public abstract String getSummaryForRootNode(AbstractTreeNode childNode);
+
+ @Nullable
+ public abstract String getPercentage(int columnIdx, AbstractTreeNode node);
+
+ public abstract List<AbstractTreeNode> getChildrenNodes(AbstractTreeNode node);
+
+ public abstract ColumnInfo[] createColumnInfos();
+
+ @Nullable
+ public abstract PsiElement getParentElement(PsiElement element);
+
+ public abstract AbstractTreeNode createRootNode();
+
+ public boolean canSelectInCoverageView(Object object) {
+ return object instanceof VirtualFile && PsiManager.getInstance(myProject).findFile((VirtualFile)object) != null;
+ }
+
+ @Nullable
+ public PsiElement getElementToSelect(Object object) {
+ if (object instanceof PsiElement) return (PsiElement)object;
+ return object instanceof VirtualFile ? PsiManager.getInstance(myProject).findFile((VirtualFile)object) : null;
+ }
+
+ @Nullable
+ public VirtualFile getVirtualFile(Object object) {
+ if (object instanceof PsiElement) {
+ if (object instanceof PsiDirectory) return ((PsiDirectory)object).getVirtualFile();
+ final PsiFile containingFile = ((PsiElement)object).getContainingFile();
+ if (containingFile != null) {
+ return containingFile.getVirtualFile();
+ }
+ return null;
+ }
+ return object instanceof VirtualFile ? (VirtualFile)object : null;
+ }
+
+ public List<AbstractTreeNode> createTopLevelNodes() {
+ return Collections.emptyList();
+ }
+
+ public boolean supportFlattenPackages() {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewManager.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewManager.java
new file mode 100644
index 000000000000..517d6b1b61f9
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewManager.java
@@ -0,0 +1,128 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageOptionsProvider;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.impl.ContentManagerWatcher;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowAnchor;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentManager;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * User: anna
+ * Date: 1/2/12
+ */
+@State(
+ name = "CoverageViewManager",
+ storages = {@Storage( file = StoragePathMacros.WORKSPACE_FILE)}
+)
+public class CoverageViewManager implements PersistentStateComponent<CoverageViewManager.StateBean> {
+ private static final Logger LOG = Logger.getInstance("#" + CoverageViewManager.class.getName());
+ public static final String TOOLWINDOW_ID = "Coverage";
+ private Project myProject;
+ private final CoverageDataManager myDataManager;
+ private ContentManager myContentManager;
+ private StateBean myStateBean = new StateBean();
+ private Map<String, CoverageView> myViews = new HashMap<String, CoverageView>();
+ private boolean myReady;
+
+ public CoverageViewManager(Project project, ToolWindowManager toolWindowManager, CoverageDataManager dataManager) {
+ myProject = project;
+ myDataManager = dataManager;
+
+ ToolWindow toolWindow = toolWindowManager.registerToolWindow(TOOLWINDOW_ID, true, ToolWindowAnchor.RIGHT, myProject);
+ toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowCoverage);
+ toolWindow.setSplitMode(true, null);
+ myContentManager = toolWindow.getContentManager();
+ new ContentManagerWatcher(toolWindow, myContentManager);
+ }
+
+ public StateBean getState() {
+ return myStateBean;
+ }
+
+ public void loadState(StateBean state) {
+ myStateBean = state;
+ }
+
+ public CoverageView getToolwindow(CoverageSuitesBundle suitesBundle) {
+ return myViews.get(getDisplayName(suitesBundle));
+ }
+
+ public void activateToolwindow(CoverageView view, boolean requestFocus) {
+ ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(TOOLWINDOW_ID);
+ if (requestFocus) {
+ myContentManager.setSelectedContent(myContentManager.getContent(view));
+ LOG.assertTrue(toolWindow != null);
+ toolWindow.activate(null, false);
+ }
+ }
+
+ public static CoverageViewManager getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, CoverageViewManager.class);
+ }
+
+ public void createToolWindow(String displayName, boolean defaultFileProvider) {
+ closeView(displayName);
+
+ final CoverageView coverageView = new CoverageView(myProject, myDataManager, myStateBean);
+ myViews.put(displayName, coverageView);
+ Content content = myContentManager.getFactory().createContent(coverageView, displayName, true);
+ myContentManager.addContent(content);
+ myContentManager.setSelectedContent(content);
+
+ if (CoverageOptionsProvider.getInstance(myProject).activateViewOnRun() && defaultFileProvider) {
+ activateToolwindow(coverageView, true);
+ }
+ }
+
+ void closeView(String displayName) {
+ final CoverageView oldView = myViews.get(displayName);
+ if (oldView != null) {
+ final Content content = myContentManager.getContent(oldView);
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ if (content != null) {
+ myContentManager.removeContent(content, true);
+ }
+ Disposer.dispose(oldView);
+ }
+ };
+ ApplicationManager.getApplication().invokeLater(runnable);
+ }
+ setReady(false);
+ }
+
+ public boolean isReady() {
+ return myReady;
+ }
+
+ public void setReady(boolean ready) {
+ myReady = ready;
+ }
+
+ public static String getDisplayName(CoverageSuitesBundle suitesBundle) {
+ final RunConfigurationBase configuration = suitesBundle.getRunConfiguration();
+ return configuration != null ? configuration.getName() : suitesBundle.getPresentableName();
+ }
+
+ public static class StateBean {
+ public boolean myFlattenPackages = false;
+ public boolean myAutoScrollToSource = false;
+ public boolean myAutoScrollFromSource = false;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewSuiteListener.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewSuiteListener.java
new file mode 100644
index 000000000000..3534589fc7bd
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewSuiteListener.java
@@ -0,0 +1,42 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.*;
+import com.intellij.openapi.project.Project;
+
+/**
+* User: anna
+* Date: 1/5/12
+*/
+public class CoverageViewSuiteListener implements CoverageSuiteListener {
+ private final CoverageDataManager myDataManager;
+ private final Project myProject;
+
+ public CoverageViewSuiteListener(CoverageDataManager dataManager, Project project) {
+ myDataManager = dataManager;
+ myProject = project;
+ }
+
+ public void beforeSuiteChosen() {
+ final CoverageSuitesBundle suitesBundle = myDataManager.getCurrentSuitesBundle();
+ if (suitesBundle != null) {
+ CoverageViewManager.getInstance(myProject).closeView(CoverageViewManager.getDisplayName(suitesBundle));
+ }
+ }
+
+ public void afterSuiteChosen() {
+ final CoverageSuitesBundle suitesBundle = myDataManager.getCurrentSuitesBundle();
+ if (suitesBundle == null) return;
+ final CoverageViewManager viewManager = CoverageViewManager.getInstance(myProject);
+ if (suitesBundle.getCoverageEngine().createCoverageViewExtension(myProject, suitesBundle, viewManager.getState()) != null) {
+ viewManager.createToolWindow(CoverageViewManager.getDisplayName(suitesBundle), shouldActivate(suitesBundle));
+ }
+ }
+
+ private static boolean shouldActivate(CoverageSuitesBundle suitesBundle) {
+ final CoverageSuite[] suites = suitesBundle.getSuites();
+ for (CoverageSuite suite : suites) {
+ if (!(suite.getCoverageDataFileProvider() instanceof DefaultCoverageFileProvider)) return false;
+ }
+ return true;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewTreeStructure.java b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewTreeStructure.java
new file mode 100644
index 000000000000..a1c8423f586f
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/CoverageViewTreeStructure.java
@@ -0,0 +1,80 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.ide.util.treeView.AbstractTreeStructure;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 1/2/12
+ */
+public class CoverageViewTreeStructure extends AbstractTreeStructure {
+ private final Project myProject;
+ final CoverageSuitesBundle myData;
+ final CoverageViewManager.StateBean myStateBean;
+ private final CoverageListRootNode myRootNode;
+ private final CoverageViewExtension myCoverageViewExtension;
+
+ public CoverageViewTreeStructure(Project project, CoverageSuitesBundle bundle, CoverageViewManager.StateBean stateBean) {
+ myProject = project;
+ myData = bundle;
+ myStateBean = stateBean;
+ myCoverageViewExtension = myData.getCoverageEngine().createCoverageViewExtension(project, bundle, stateBean);
+ myRootNode = (CoverageListRootNode)myCoverageViewExtension.createRootNode();
+ }
+
+
+ public Object getRootElement() {
+ return myRootNode;
+ }
+
+ public Object[] getChildElements(final Object element) {
+ return getChildren(element, myData, myStateBean);
+ }
+
+ static Object[] getChildren(Object element,
+ final CoverageSuitesBundle bundle,
+ CoverageViewManager.StateBean stateBean) {
+ if (element instanceof CoverageListRootNode && stateBean.myFlattenPackages) {
+ final Collection<? extends AbstractTreeNode> children = ((CoverageListRootNode)element).getChildren();
+ return children.toArray(new Object[children.size()]);
+ }
+ if (element instanceof CoverageListNode) {
+ List<AbstractTreeNode> children = bundle.getCoverageEngine().createCoverageViewExtension(((CoverageListNode)element).getProject(),
+ bundle, stateBean)
+ .getChildrenNodes((CoverageListNode)element);
+ return children.toArray(new CoverageListNode[children.size()]);
+ }
+ return null;
+ }
+
+
+ public Object getParentElement(final Object element) {
+ final PsiElement psiElement = (PsiElement)element;
+ return myCoverageViewExtension.getParentElement(psiElement);
+ }
+
+ @NotNull
+ public CoverageViewDescriptor createDescriptor(final Object element, final NodeDescriptor parentDescriptor) {
+ return new CoverageViewDescriptor(myProject, parentDescriptor, element);
+ }
+
+ public void commit() {
+ }
+
+ public boolean hasSomethingToCommit() {
+ return false;
+ }
+
+ public boolean supportFlattenPackages() {
+ return myCoverageViewExtension.supportFlattenPackages();
+ }
+}
+
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/DirectoryCoverageViewExtension.java b/plugins/coverage-common/src/com/intellij/coverage/view/DirectoryCoverageViewExtension.java
new file mode 100644
index 000000000000..a04d33c4b1c2
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/DirectoryCoverageViewExtension.java
@@ -0,0 +1,113 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageAnnotator;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.ui.ColumnInfo;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 1/9/12
+ */
+public class DirectoryCoverageViewExtension extends CoverageViewExtension {
+ private final CoverageAnnotator myAnnotator;
+
+ public DirectoryCoverageViewExtension(Project project,
+ CoverageAnnotator annotator,
+ CoverageSuitesBundle suitesBundle,
+ CoverageViewManager.StateBean stateBean) {
+ super(project, suitesBundle, stateBean);
+ myAnnotator = annotator;
+ }
+
+ @Override
+ public ColumnInfo[] createColumnInfos() {
+ return new ColumnInfo[]{new ElementColumnInfo(), new PercentageCoverageColumnInfo(1, "Statistics, %", mySuitesBundle, myStateBean)};
+ }
+
+ @Override
+ public String getSummaryForNode(AbstractTreeNode node) {
+ return "Coverage Summary for \'" + node.toString() + "\': " +
+ myAnnotator.getDirCoverageInformationString((PsiDirectory)node.getValue(), mySuitesBundle,
+ myCoverageDataManager);
+ }
+
+ @Override
+ public String getSummaryForRootNode(AbstractTreeNode childNode) {
+ final Object value = childNode.getValue();
+ String coverageInformationString = myAnnotator.getDirCoverageInformationString(((PsiDirectory)value), mySuitesBundle,
+ myCoverageDataManager);
+
+ return "Coverage Summary: " + coverageInformationString;
+ }
+
+ @Override
+ public String getPercentage(int columnIdx, AbstractTreeNode node) {
+ final Object value = node.getValue();
+ if (value instanceof PsiFile) {
+ return myAnnotator.getFileCoverageInformationString((PsiFile)value, mySuitesBundle, myCoverageDataManager);
+ }
+ return value != null ? myAnnotator.getDirCoverageInformationString((PsiDirectory)value, mySuitesBundle, myCoverageDataManager) : null;
+ }
+
+
+ @Override
+ public PsiElement getParentElement(PsiElement element) {
+ final PsiFile containingFile = element.getContainingFile();
+ if (containingFile != null) {
+ return containingFile.getContainingDirectory();
+ }
+ return null;
+ }
+
+ @Override
+ public AbstractTreeNode createRootNode() {
+ final VirtualFile baseDir = myProject.getBaseDir();
+ return new CoverageListRootNode(myProject, PsiManager.getInstance(myProject).findDirectory(baseDir), mySuitesBundle, myStateBean);
+ }
+
+ @Override
+ public List<AbstractTreeNode> getChildrenNodes(AbstractTreeNode node) {
+ List<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>();
+ if (node instanceof CoverageListNode) {
+ final Object val = node.getValue();
+ if (val instanceof PsiFile) return Collections.emptyList();
+ final PsiDirectory psiDirectory = (PsiDirectory)val;
+ final PsiDirectory[] subdirectories = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory[]>() {
+ @Override
+ public PsiDirectory[] compute() {
+ return psiDirectory.getSubdirectories();
+ }
+ });
+ for (PsiDirectory subdirectory : subdirectories) {
+ children.add(new CoverageListNode(myProject, subdirectory, mySuitesBundle, myStateBean));
+ }
+ final PsiFile[] psiFiles = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile[]>() {
+ @Override
+ public PsiFile[] compute() {
+ return psiDirectory.getFiles();
+ }
+ });
+ for (PsiFile psiFile : psiFiles) {
+ children.add(new CoverageListNode(myProject, psiFile, mySuitesBundle, myStateBean));
+ }
+
+ for (AbstractTreeNode childNode : children) {
+ childNode.setParent(node);
+ }
+ }
+ return children;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/ElementColumnInfo.java b/plugins/coverage-common/src/com/intellij/coverage/view/ElementColumnInfo.java
new file mode 100644
index 000000000000..39daa7fa4881
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/ElementColumnInfo.java
@@ -0,0 +1,27 @@
+package com.intellij.coverage.view;
+
+import com.intellij.ide.util.treeView.AlphaComparator;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.util.ui.ColumnInfo;
+
+import java.util.Comparator;
+
+/**
+* User: anna
+* Date: 1/9/12
+*/
+class ElementColumnInfo extends ColumnInfo<NodeDescriptor, String> {
+ public ElementColumnInfo() {
+ super("Element");
+ }
+
+ @Override
+ public Comparator<NodeDescriptor> getComparator() {
+ return AlphaComparator.INSTANCE;
+ }
+
+ @Override
+ public String valueOf(NodeDescriptor node) {
+ return node.toString();
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/PercentageCoverageColumnInfo.java b/plugins/coverage-common/src/com/intellij/coverage/view/PercentageCoverageColumnInfo.java
new file mode 100644
index 000000000000..52de0da33d10
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/PercentageCoverageColumnInfo.java
@@ -0,0 +1,75 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageEngine;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.util.ui.ColumnInfo;
+
+import java.util.Comparator;
+
+/**
+* User: anna
+* Date: 1/9/12
+*/
+class PercentageCoverageColumnInfo extends ColumnInfo<NodeDescriptor, String> {
+ private final int myColumnIdx;
+ private final Comparator<NodeDescriptor> myComparator;
+ private final CoverageSuitesBundle mySuitesBundle;
+ private final CoverageViewManager.StateBean myStateBean;
+
+ PercentageCoverageColumnInfo(int columnIdx,
+ String name,
+ final CoverageSuitesBundle suitesBundle,
+ CoverageViewManager.StateBean stateBean) {
+ super(name);
+ this.myColumnIdx = columnIdx;
+ myComparator = new Comparator<NodeDescriptor>() {
+ @Override
+ public int compare(NodeDescriptor o1, NodeDescriptor o2) {
+ final String val1 = valueOf(o1);
+ final String val2 = valueOf(o2);
+ if (val1 != null && val2 != null) {
+ final int percentageIndex1 = val1.indexOf('%');
+ final int percentageIndex2 = val2.indexOf('%');
+ if (percentageIndex1 > -1 && percentageIndex2 >-1) {
+ final String percentage1 = val1.substring(0, percentageIndex1);
+ final String percentage2 = val2.substring(0, percentageIndex2);
+ final int compare = Comparing.compare(Integer.parseInt(percentage1), Integer.parseInt(percentage2));
+ if (compare == 0) {
+ final int total1 = val1.indexOf('/');
+ final int total2 = val2.indexOf('/');
+ if (total1 > -1 && total2 > -1) {
+ final int r1 = val1.indexOf(')', total1);
+ final int r2 = val2.indexOf(')', total2);
+ if (r1 > -1 && r2 > -1) {
+ return Integer.parseInt(val2.substring(total2 + 1, r2)) - Integer.parseInt(val1.substring(total1 + 1, r1)) ;
+ }
+ }
+ }
+ return compare;
+ }
+ if (percentageIndex1 > -1) return 1;
+ if (percentageIndex2 > -1) return -1;
+ }
+ return Comparing.compare(val1, val2);
+ }
+ };
+ mySuitesBundle = suitesBundle;
+ myStateBean = stateBean;
+ }
+
+ @Override
+ public String valueOf(NodeDescriptor node) {
+ final CoverageEngine coverageEngine = mySuitesBundle.getCoverageEngine();
+ final Project project = node.getProject();
+ return coverageEngine.createCoverageViewExtension(project, mySuitesBundle, myStateBean).getPercentage(myColumnIdx, (AbstractTreeNode)node);
+ }
+
+ @Override
+ public Comparator<NodeDescriptor> getComparator() {
+ return myComparator;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/coverage/view/SelectInCoverageView.java b/plugins/coverage-common/src/com/intellij/coverage/view/SelectInCoverageView.java
new file mode 100644
index 000000000000..9d0aa09c21d1
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/coverage/view/SelectInCoverageView.java
@@ -0,0 +1,59 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.CoverageDataManager;
+import com.intellij.coverage.CoverageSuitesBundle;
+import com.intellij.ide.SelectInContext;
+import com.intellij.ide.SelectInTarget;
+import com.intellij.ide.StandardTargetWeights;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * User: anna
+ * Date: 1/3/12
+ */
+public class SelectInCoverageView implements SelectInTarget {
+ private final Project myProject;
+
+ public SelectInCoverageView(Project project) {
+ myProject = project;
+ }
+
+ public String toString() {
+ return CoverageViewManager.TOOLWINDOW_ID;
+ }
+
+ public boolean canSelect(final SelectInContext context) {
+ final CoverageSuitesBundle suitesBundle = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle();
+ if (suitesBundle != null) {
+ final CoverageView coverageView = CoverageViewManager.getInstance(myProject).getToolwindow(suitesBundle);
+ if (coverageView != null) {
+ final VirtualFile file = context.getVirtualFile();
+ return !file.isDirectory() && coverageView.canSelect(file);
+ }
+ }
+ return false;
+ }
+
+ public void selectIn(final SelectInContext context, final boolean requestFocus) {
+ final CoverageSuitesBundle suitesBundle = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle();
+ if (suitesBundle != null) {
+ final CoverageViewManager coverageViewManager = CoverageViewManager.getInstance(myProject);
+ final CoverageView coverageView = coverageViewManager.getToolwindow(suitesBundle);
+ coverageView.select(context.getVirtualFile());
+ coverageViewManager.activateToolwindow(coverageView, requestFocus);
+ }
+ }
+
+ public String getToolWindowId() {
+ return CoverageViewManager.TOOLWINDOW_ID;
+ }
+
+ public String getMinorViewId() {
+ return null;
+ }
+
+ public float getWeight() {
+ return StandardTargetWeights.STRUCTURE_WEIGHT + 0.5f;
+ }
+}
diff --git a/plugins/coverage-common/src/com/intellij/execution/configurations/coverage/CoverageEnabledConfiguration.java b/plugins/coverage-common/src/com/intellij/execution/configurations/coverage/CoverageEnabledConfiguration.java
new file mode 100644
index 000000000000..1c472114191d
--- /dev/null
+++ b/plugins/coverage-common/src/com/intellij/execution/configurations/coverage/CoverageEnabledConfiguration.java
@@ -0,0 +1,246 @@
+package com.intellij.execution.configurations.coverage;
+
+import com.intellij.coverage.CoverageEngine;
+import com.intellij.coverage.CoverageRunner;
+import com.intellij.coverage.CoverageSuite;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * Base class for run configurations with enabled code coverage
+ *
+ * @author ven
+ */
+public abstract class CoverageEnabledConfiguration implements JDOMExternalizable {
+ private static final Logger LOG = Logger.getInstance(CoverageEnabledConfiguration.class.getName());
+
+ public static final Key<CoverageEnabledConfiguration> COVERAGE_KEY = Key.create("com.intellij.coverage");
+
+ @NonNls protected static final String COVERAGE_ENABLED_ATTRIBUTE_NAME = "enabled";
+ @NonNls protected static final String COVERAGE_RUNNER = "runner";
+ @NonNls protected static final String TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME = "per_test_coverage_enabled";
+ @NonNls protected static final String SAMPLING_COVERAGE_ATTRIBUTE_NAME = "sample_coverage";
+ @NonNls protected static final String TRACK_TEST_FOLDERS = "track_test_folders";
+
+ private final Project myProject;
+ private final RunConfigurationBase myConfiguration;
+
+ private boolean myIsCoverageEnabled = false;
+ private String myRunnerId;
+ private CoverageRunner myCoverageRunner;
+ private boolean myTrackPerTestCoverage = true;
+ private boolean mySampling = true;
+ private boolean myTrackTestFolders = false;
+
+ @NonNls protected String myCoverageFilePath;
+ private CoverageSuite myCurrentCoverageSuite;
+
+ public CoverageEnabledConfiguration(RunConfigurationBase configuration) {
+ myConfiguration = configuration;
+ myProject = configuration.getProject();
+ }
+
+ public RunConfigurationBase getConfiguration() {
+ return myConfiguration;
+ }
+
+ public boolean isCoverageEnabled() {
+ return myIsCoverageEnabled;
+ }
+
+ public void setCoverageEnabled(final boolean isCoverageEnabled) {
+ myIsCoverageEnabled = isCoverageEnabled;
+ }
+
+ public boolean isSampling() {
+ return mySampling;
+ }
+
+ public void setSampling(final boolean sampling) {
+ mySampling = sampling;
+ }
+
+ public String getRunnerId() {
+ return myRunnerId;
+ }
+
+ @Nullable
+ public CoverageRunner getCoverageRunner() {
+ return myCoverageRunner;
+ }
+
+ public void setCoverageRunner(@Nullable final CoverageRunner coverageRunner) {
+ myCoverageRunner = coverageRunner;
+ myRunnerId = coverageRunner != null ? coverageRunner.getId() : null;
+ myCoverageFilePath = null;
+ }
+
+ public boolean isTrackPerTestCoverage() {
+ return myTrackPerTestCoverage;
+ }
+
+ public void setTrackPerTestCoverage(final boolean collectLineInfo) {
+ myTrackPerTestCoverage = collectLineInfo;
+ }
+
+ public boolean isTrackTestFolders() {
+ return myTrackTestFolders;
+ }
+
+ public void setTrackTestFolders(boolean trackTestFolders) {
+ myTrackTestFolders = trackTestFolders;
+ }
+
+ public CoverageSuite getCurrentCoverageSuite() {
+ return myCurrentCoverageSuite;
+ }
+
+ public void setCurrentCoverageSuite(CoverageSuite currentCoverageSuite) {
+ myCurrentCoverageSuite = currentCoverageSuite;
+ }
+
+ public String getName() {
+ return myConfiguration.getName();
+ }
+
+ public boolean canHavePerTestCoverage() {
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (engine.isApplicableTo(myConfiguration)) {
+ return engine.canHavePerTestCoverage(myConfiguration);
+ }
+ }
+ return false;
+ }
+
+
+ public static boolean isApplicableTo(@NotNull final RunConfigurationBase runConfiguration) {
+ final CoverageEnabledConfiguration configuration = runConfiguration.getCopyableUserData(COVERAGE_KEY);
+ if (configuration != null) {
+ return true;
+ }
+
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (engine.isApplicableTo(runConfiguration)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @NotNull
+ public static CoverageEnabledConfiguration getOrCreate(@NotNull final RunConfigurationBase runConfiguration) {
+ CoverageEnabledConfiguration configuration = runConfiguration.getCopyableUserData(COVERAGE_KEY);
+ if (configuration == null) {
+ for (CoverageEngine engine : CoverageEngine.EP_NAME.getExtensions()) {
+ if (engine.isApplicableTo(runConfiguration)) {
+ configuration = engine.createCoverageEnabledConfiguration(runConfiguration);
+ break;
+ }
+ }
+ LOG.assertTrue(configuration != null,
+ "Coverage enabled run configuration wasn't found for run configuration: " + runConfiguration.getName() +
+ ", type = " + runConfiguration.getClass().getName());
+ runConfiguration.putCopyableUserData(COVERAGE_KEY, configuration);
+ }
+ return configuration;
+ }
+
+ @Nullable
+ @NonNls
+ public String getCoverageFilePath() {
+ if (myCoverageFilePath == null) {
+ myCoverageFilePath = createCoverageFile();
+ }
+ return myCoverageFilePath;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ // is enabled
+ final String coverageEnabledValueStr = element.getAttributeValue(COVERAGE_ENABLED_ATTRIBUTE_NAME);
+ myIsCoverageEnabled = Boolean.valueOf(coverageEnabledValueStr).booleanValue();
+
+ // track per test coverage
+ final String collectLineInfoAttribute = element.getAttributeValue(TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME);
+ myTrackPerTestCoverage = collectLineInfoAttribute == null || Boolean.valueOf(collectLineInfoAttribute).booleanValue();
+
+ // sampling
+ final String sampling = element.getAttributeValue(SAMPLING_COVERAGE_ATTRIBUTE_NAME);
+ mySampling = sampling != null && Boolean.valueOf(sampling).booleanValue();
+
+ // track test folders
+ final String trackTestFolders = element.getAttributeValue(TRACK_TEST_FOLDERS);
+ myTrackTestFolders = trackTestFolders != null && Boolean.valueOf(trackTestFolders).booleanValue();
+
+ // coverage runner
+ final String runnerId = element.getAttributeValue(COVERAGE_RUNNER);
+ if (runnerId != null) {
+ myRunnerId = runnerId;
+ myCoverageRunner = null;
+ for (CoverageRunner coverageRunner : Extensions.getExtensions(CoverageRunner.EP_NAME)) {
+ if (Comparing.strEqual(coverageRunner.getId(), myRunnerId)) {
+ myCoverageRunner = coverageRunner;
+ break;
+ }
+ }
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ // enabled
+ element.setAttribute(COVERAGE_ENABLED_ATTRIBUTE_NAME, String.valueOf(myIsCoverageEnabled));
+
+ // per test
+ if (!myTrackPerTestCoverage) {
+ element.setAttribute(TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME, String.valueOf(myTrackPerTestCoverage));
+ }
+
+ // sampling
+ if (mySampling) {
+ element.setAttribute(SAMPLING_COVERAGE_ATTRIBUTE_NAME, String.valueOf(mySampling));
+ }
+
+ // test folders
+ if (myTrackTestFolders) {
+ element.setAttribute(TRACK_TEST_FOLDERS, String.valueOf(myTrackTestFolders));
+ }
+
+ // runner
+ if (myCoverageRunner != null) {
+ element.setAttribute(COVERAGE_RUNNER, myCoverageRunner.getId());
+ }
+ else if (myRunnerId != null) {
+ element.setAttribute(COVERAGE_RUNNER, myRunnerId);
+ }
+ }
+
+ @Nullable
+ @NonNls
+ protected String createCoverageFile() {
+ if (myCoverageRunner == null) {
+ return null;
+ }
+
+ @NonNls final String coverageRootPath = PathManager.getSystemPath() + File.separator + "coverage";
+ final String path = coverageRootPath + File.separator + myProject.getName() + coverageFileNameSeparator()
+ + FileUtil.sanitizeFileName(myConfiguration.getName()) + ".coverage";
+
+ new File(coverageRootPath).mkdirs();
+ return path;
+ }
+
+ protected String coverageFileNameSeparator() {
+ return "$";
+ }
+}
diff --git a/plugins/coverage/coverage.iml b/plugins/coverage/coverage.iml
new file mode 100644
index 000000000000..79aabd8b9788
--- /dev/null
+++ b/plugins/coverage/coverage.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="coverage-common" exported="" />
+ <orderEntry type="module" module-name="execution-openapi" exported="" />
+ <orderEntry type="module" module-name="openapi" exported="" />
+ <orderEntry type="module" module-name="execution-impl" />
+ <orderEntry type="module" module-name="testRunner" />
+ <orderEntry type="module-library" exported="">
+ <library name="CoverageReport">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/coverage-report.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/coverage-report-idea.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="module" module-name="testng_rt" />
+ <orderEntry type="module" module-name="junit_rt" />
+ <orderEntry type="module" module-name="compiler-openapi" />
+ <orderEntry type="library" name="TestNG" level="project" />
+ <orderEntry type="library" name="JaCoCo" level="project" />
+ <orderEntry type="module" module-name="coverage_rt" />
+ <orderEntry type="module" module-name="java-psi-impl" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="java-impl" />
+ </component>
+</module>
+
diff --git a/plugins/coverage/covergae_rt/coverage_rt.iml b/plugins/coverage/covergae_rt/coverage_rt.iml
new file mode 100644
index 000000000000..0766e89e7956
--- /dev/null
+++ b/plugins/coverage/covergae_rt/coverage_rt.iml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij.coverage" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="testng_rt" />
+ <orderEntry type="module" module-name="junit_rt" />
+ <orderEntry type="library" name="TestNG" level="project" />
+ <orderEntry type="module-library">
+ <library name="Coverage">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../coverage-common/lib/coverage-agent.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ </component>
+</module>
+
diff --git a/plugins/coverage/covergae_rt/src/listeners/CoverageListener.java b/plugins/coverage/covergae_rt/src/listeners/CoverageListener.java
new file mode 100644
index 000000000000..f4bf0d902590
--- /dev/null
+++ b/plugins/coverage/covergae_rt/src/listeners/CoverageListener.java
@@ -0,0 +1,41 @@
+/*
+ * User: anna
+ * Date: 19-Feb-2010
+ */
+package com.intellij.coverage.listeners;
+
+public abstract class CoverageListener {
+ private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ private Object myProjectData;
+
+ protected static String sanitize(String className, String methodName) {
+ final StringBuilder result = new StringBuilder();
+ final String fileName = className + "." + methodName;
+ for (int i = 0; i < fileName.length(); i++) {
+ final char ch = fileName.charAt(i);
+
+ if (ch > 0 && ch < 255) {
+ if (Character.isLetterOrDigit(ch)) {
+ result.append(ch);
+ }
+ else {
+ result.append("_");
+ }
+ }
+
+ }
+
+ return result.toString();
+ }
+
+ protected Object getData() {
+ try {
+
+ return Class.forName("com.intellij.rt.coverage.data.ProjectData").getMethod("getProjectData", EMPTY_CLASS_ARRAY).invoke(null);
+
+ }
+ catch (Exception e) {
+ return null; //should not happen
+ }
+ }
+}
diff --git a/plugins/coverage/covergae_rt/src/listeners/IDEAJUnitCoverageListener.java b/plugins/coverage/covergae_rt/src/listeners/IDEAJUnitCoverageListener.java
new file mode 100644
index 000000000000..1e8d46c62b26
--- /dev/null
+++ b/plugins/coverage/covergae_rt/src/listeners/IDEAJUnitCoverageListener.java
@@ -0,0 +1,21 @@
+/*
+ * User: anna
+ * Date: 28-Aug-2009
+ */
+package com.intellij.coverage.listeners;
+
+import com.intellij.rt.execution.junit.IDEAJUnitListener;
+
+@SuppressWarnings({"UnnecessaryFullyQualifiedName"})
+public class IDEAJUnitCoverageListener extends CoverageListener implements IDEAJUnitListener {
+
+ public void testStarted(String className, String methodName) {
+ final Object data = getData();
+ ((com.intellij.rt.coverage.data.ProjectData)data).testStarted(sanitize(className, methodName));
+ }
+
+ public void testFinished(String className, String methodName) {
+ final Object data = getData();
+ ((com.intellij.rt.coverage.data.ProjectData)data).testEnded(sanitize(className, methodName));
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage/covergae_rt/src/listeners/IDEATestNGCoverageListener.java b/plugins/coverage/covergae_rt/src/listeners/IDEATestNGCoverageListener.java
new file mode 100644
index 000000000000..bd5bd14b5935
--- /dev/null
+++ b/plugins/coverage/covergae_rt/src/listeners/IDEATestNGCoverageListener.java
@@ -0,0 +1,55 @@
+/*
+ * User: anna
+ * Date: 29-May-2008
+ */
+package com.intellij.coverage.listeners;
+
+import org.testng.IDEATestNGListener;
+import org.testng.ITestContext;
+import org.testng.ITestResult;
+
+public class IDEATestNGCoverageListener extends CoverageListener implements IDEATestNGListener {
+
+ public void onTestStart(final ITestResult iTestResult) {
+ final Object data = getData();
+ if (data != null) {
+ ((com.intellij.rt.coverage.data.ProjectData)data).testStarted(getSanitizeTestName(iTestResult));
+ }
+ }
+
+ private static String getSanitizeTestName(ITestResult iTestResult) {
+ return sanitize(iTestResult.getTestClass().getName(), iTestResult.getName());
+ }
+
+ public void onTestSuccess(final ITestResult iTestResult) {
+ final Object data = getData();
+ if (data != null) {
+ ((com.intellij.rt.coverage.data.ProjectData)data).testEnded(getSanitizeTestName(iTestResult));
+ }
+ }
+
+ public void onTestFailure(final ITestResult iTestResult) {
+ final Object data = getData();
+ if (data != null) {
+ ((com.intellij.rt.coverage.data.ProjectData)data).testEnded(getSanitizeTestName(iTestResult));
+ }
+ }
+
+ public void onTestSkipped(final ITestResult iTestResult) {
+ final Object data = getData();
+ if (data != null) {
+ ((com.intellij.rt.coverage.data.ProjectData)data).testEnded(getSanitizeTestName(iTestResult));
+ }
+ }
+
+ public void onTestFailedButWithinSuccessPercentage(final ITestResult iTestResult) {
+
+ }
+
+ public void onStart(final ITestContext iTestContext) {
+ }
+
+ public void onFinish(final ITestContext iTestContext) {
+ }
+
+}
diff --git a/plugins/coverage/lib/asm-all.jar b/plugins/coverage/lib/asm-all.jar
new file mode 100644
index 000000000000..800313398c81
--- /dev/null
+++ b/plugins/coverage/lib/asm-all.jar
Binary files differ
diff --git a/plugins/coverage/lib/coverage-report-idea.jar b/plugins/coverage/lib/coverage-report-idea.jar
new file mode 100644
index 000000000000..341a201c82e7
--- /dev/null
+++ b/plugins/coverage/lib/coverage-report-idea.jar
Binary files differ
diff --git a/plugins/coverage/lib/coverage-report.jar b/plugins/coverage/lib/coverage-report.jar
new file mode 100644
index 000000000000..f5cb65eb5339
--- /dev/null
+++ b/plugins/coverage/lib/coverage-report.jar
Binary files differ
diff --git a/plugins/coverage/lib/finder.jar b/plugins/coverage/lib/finder.jar
new file mode 100644
index 000000000000..a97a2836d0bb
--- /dev/null
+++ b/plugins/coverage/lib/finder.jar
Binary files differ
diff --git a/plugins/coverage/lib/jacoco_src.zip b/plugins/coverage/lib/jacoco_src.zip
new file mode 100644
index 000000000000..7615d40086f2
--- /dev/null
+++ b/plugins/coverage/lib/jacoco_src.zip
Binary files differ
diff --git a/plugins/coverage/lib/jacocoagent.jar b/plugins/coverage/lib/jacocoagent.jar
new file mode 100644
index 000000000000..f934c847aa43
--- /dev/null
+++ b/plugins/coverage/lib/jacocoagent.jar
Binary files differ
diff --git a/plugins/coverage/lib/jacocoant.jar b/plugins/coverage/lib/jacocoant.jar
new file mode 100644
index 000000000000..a4fa857fd557
--- /dev/null
+++ b/plugins/coverage/lib/jacocoant.jar
Binary files differ
diff --git a/plugins/coverage/lib/trove4j.jar b/plugins/coverage/lib/trove4j.jar
new file mode 100644
index 000000000000..71a04028f785
--- /dev/null
+++ b/plugins/coverage/lib/trove4j.jar
Binary files differ
diff --git a/plugins/coverage/src/META-INF/junit-integration.xml b/plugins/coverage/src/META-INF/junit-integration.xml
new file mode 100644
index 000000000000..123592f647be
--- /dev/null
+++ b/plugins/coverage/src/META-INF/junit-integration.xml
@@ -0,0 +1,5 @@
+<idea-plugin url="http://www.jetbrains.com/idea">
+ <extensions defaultExtensionNs="com.intellij">
+ <junitListener implementation="com.intellij.coverage.listeners.IDEAJUnitCoverageListener"/>
+ </extensions>
+</idea-plugin>
diff --git a/plugins/coverage/src/META-INF/plugin.xml b/plugins/coverage/src/META-INF/plugin.xml
new file mode 100644
index 000000000000..17c130559866
--- /dev/null
+++ b/plugins/coverage/src/META-INF/plugin.xml
@@ -0,0 +1,52 @@
+<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <name>Coverage</name>
+ <depends optional="true" config-file="testng-integration.xml">TestNG-J</depends>
+ <depends optional="true" config-file="junit-integration.xml">JUnit</depends>
+ <depends>com.intellij.modules.java</depends>
+ <description>
+ <![CDATA[
+ This plugin supports gathering coverage information and presenting it right in
+ the editor and in the Project view.
+ The following features are available:
+ <ul>
+ <li>Coverage tab in the run/debug configurations.</li>
+ <li>Run with coverage command.</li>
+ <li>Ability to generate standalone HTML reports for external use.</li>
+ </ul>
+ ]]>
+ </description>
+ <vendor>JetBrains</vendor>
+
+ <xi:include href="/META-INF/coverage-common-plugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
+ <extensions defaultExtensionNs="com.intellij">
+ <runConfigurationExtension implementation="com.intellij.execution.coverage.CoverageJavaRunConfigurationExtension"/>
+ <!--<coverageRunner implementation="com.intellij.coverage.CoberturaCoverageRunner"/>-->
+ <coverageRunner implementation="com.intellij.coverage.IDEACoverageRunner"/>
+ <coverageRunner implementation="com.intellij.coverage.JaCoCoCoverageRunner"/>
+ <coverageEngine implementation="com.intellij.coverage.JavaCoverageEngine" order = "last"/>
+ <projectViewNodeDecorator implementation="com.intellij.coverage.CoverageProjectViewClassNodeDecorator"/>
+
+ <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+ <projectService serviceInterface="com.intellij.coverage.JavaCoverageAnnotator"
+ serviceImplementation="com.intellij.coverage.JavaCoverageAnnotator"/>
+ <programRunner implementation="com.intellij.coverage.DefaultJavaCoverageRunner"/>
+ <selectInTarget implementation="com.intellij.coverage.view.SelectInCoverageView"/>
+ </extensions>
+
+ <extensionPoints>
+ <extensionPoint qualifiedName="com.intellij.javaCoverageEngineExtension" interface="com.intellij.coverage.JavaCoverageEngineExtension"/>
+ </extensionPoints>
+ <project-components>
+ <component>
+ <interface-class>com.intellij.coverage.CoverageDataManager</interface-class>
+ <implementation-class>com.intellij.coverage.CoveragePluginDataManagerImpl</implementation-class>
+ <option name="workspace" value="true"/>
+ </component>
+ </project-components>
+ <actions>
+ <group id="IDEACoverageMenu" popup="false">
+ <reference ref="CoverageMenu"/>
+ <add-to-group group-id="AnalyzeMenu" anchor="before" relative-to-action="AnalyzeActions"/>
+ </group>
+ </actions>
+</idea-plugin>
diff --git a/plugins/coverage/src/META-INF/testng-integration.xml b/plugins/coverage/src/META-INF/testng-integration.xml
new file mode 100644
index 000000000000..c2d3ffd98ed3
--- /dev/null
+++ b/plugins/coverage/src/META-INF/testng-integration.xml
@@ -0,0 +1,5 @@
+<idea-plugin url="http://www.jetbrains.com/idea">
+ <extensions defaultExtensionNs="com.theoryinpractice.testng">
+ <listener implementation="com.intellij.coverage.listeners.IDEATestNGCoverageListener"/>
+ </extensions>
+</idea-plugin>
diff --git a/plugins/coverage/src/com/intellij/coverage/CoberturaCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/CoberturaCoverageRunner.java
new file mode 100644
index 000000000000..10482f05f18e
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/CoberturaCoverageRunner.java
@@ -0,0 +1,63 @@
+/*
+ * User: anna
+ * Date: 13-Feb-2008
+ */
+package com.intellij.coverage;
+
+import com.intellij.coverage.info.CoberturaLoaderUtil;
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.rt.coverage.data.ProjectData;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public class CoberturaCoverageRunner extends JavaCoverageRunner {
+
+ public ProjectData loadCoverageData(@NotNull final File sessionDataFile, @Nullable final CoverageSuite coverageSuite) {
+ return CoberturaLoaderUtil.load(sessionDataFile);
+ }
+
+ public void appendCoverageArgument(final String sessionDataFilePath, final String[] patterns, final SimpleJavaParameters javaParameters,
+ final boolean collectLineInfo, final boolean isSampling) {
+ @NonNls StringBuffer argument = new StringBuffer("-javaagent:");
+ argument.append(PathManager.getLibPath()).append(File.separator);
+ argument.append("cobertura.jar=");
+
+ if (patterns != null && patterns.length > 0) {
+ for (String coveragePattern : patterns) {
+ coveragePattern = coveragePattern.replace("$", "\\$").replace(".", "\\.").replaceAll("\\*", ".*");
+ if (!coveragePattern.endsWith(".*")) { //include inner classes
+ coveragePattern += "(\\$.*)*";
+ }
+ argument.append("--includeClasses ").append(coveragePattern).append(" ");
+ }
+ }
+ if (SystemInfo.isWindows) {
+ argument.append("--datafile ").append("\\\"").append(sessionDataFilePath).append("\\\"");
+ }
+ else {
+ argument.append("--datafile ").append(sessionDataFilePath);
+ }
+ javaParameters.getVMParametersList().add(argument.toString());
+ javaParameters.getVMParametersList().defineProperty("net.sourceforge.cobertura.datafile", sessionDataFilePath);
+ javaParameters.getClassPath().add(PathManager.getLibPath() + File.separator + "cobertura.jar");
+ }
+
+ public String getPresentableName() {
+ return "Cobertura";
+ }
+
+ @NonNls
+ public String getId() {
+ return "cobertura";
+ }
+
+ @NonNls
+ public String getDataFileExtension() {
+ return "ser";
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage/src/com/intellij/coverage/CoveragePluginDataManagerImpl.java b/plugins/coverage/src/com/intellij/coverage/CoveragePluginDataManagerImpl.java
new file mode 100644
index 000000000000..64b67162075c
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/CoveragePluginDataManagerImpl.java
@@ -0,0 +1,12 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public class CoveragePluginDataManagerImpl extends CoverageDataManagerImpl {
+ public CoveragePluginDataManagerImpl(final Project project) {
+ super(project);
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/CoverageProjectViewClassNodeDecorator.java b/plugins/coverage/src/com/intellij/coverage/CoverageProjectViewClassNodeDecorator.java
new file mode 100644
index 000000000000..0dbd04ab629f
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/CoverageProjectViewClassNodeDecorator.java
@@ -0,0 +1,99 @@
+package com.intellij.coverage;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ide.projectView.ProjectViewNode;
+import com.intellij.ide.projectView.impl.nodes.PackageElement;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packageDependencies.ui.PackageDependenciesNode;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.SmartPsiElementPointer;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.ui.ColoredTreeCellRenderer;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public class CoverageProjectViewClassNodeDecorator extends AbstractCoverageProvejctViewNodeDecorator {
+ public CoverageProjectViewClassNodeDecorator(final CoverageDataManager coverageDataManager) {
+ super(coverageDataManager);
+ }
+
+
+ public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) {
+ final PsiElement element = node.getPsiElement();
+ if (element == null || !element.isValid()) {
+ return;
+ }
+
+ final CoverageDataManager dataManager = getCoverageDataManager();
+ final CoverageSuitesBundle currentSuite = dataManager.getCurrentSuitesBundle();
+ final Project project = element.getProject();
+
+ final JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project);
+ // This decorator is applicable only to JavaCoverageAnnotator
+ if (javaCovAnnotator == null) {
+ return;
+ }
+
+ if (element instanceof PsiClass) {
+ final String qName = ((PsiClass)element).getQualifiedName();
+ if (qName != null) {
+ appendCoverageInfo(cellRenderer, javaCovAnnotator.getClassCoverageInformationString(qName, dataManager));
+ }
+ }
+ }
+
+ public void decorate(ProjectViewNode node, PresentationData data) {
+ final CoverageDataManager coverageDataManager = getCoverageDataManager();
+ final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle();
+
+ final Project project = node.getProject();
+ final JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project);
+ // This decorator is applicable only to JavaCoverageAnnotator
+ if (javaCovAnnotator == null) {
+ return;
+ }
+
+ final Object value = node.getValue();
+ PsiElement element = null;
+ if (value instanceof PsiElement) {
+ element = (PsiElement)value;
+ }
+ else if (value instanceof SmartPsiElementPointer) {
+ element = ((SmartPsiElementPointer)value).getElement();
+ }
+ else if (value instanceof PackageElement) {
+ PackageElement packageElement = (PackageElement)value;
+ final String coverageString = javaCovAnnotator.getPackageCoverageInformationString(packageElement.getPackage(),
+ packageElement.getModule(),
+ coverageDataManager);
+ data.setLocationString(coverageString);
+ }
+
+ if (element instanceof PsiClass) {
+ final GlobalSearchScope searchScope = currentSuite.getSearchScope(project);
+ final VirtualFile vFile = PsiUtilCore.getVirtualFile(element);
+ if (vFile != null && searchScope.contains(vFile)) {
+ final String qName = ((PsiClass)element).getQualifiedName();
+ if (qName != null) {
+ data.setLocationString(javaCovAnnotator.getClassCoverageInformationString(qName, coverageDataManager));
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private static JavaCoverageAnnotator getCovAnnotator(final CoverageSuitesBundle currentSuite, Project project) {
+ if (currentSuite != null) {
+ final CoverageAnnotator coverageAnnotator = currentSuite.getAnnotator(project);
+ if (coverageAnnotator instanceof JavaCoverageAnnotator) {
+ return (JavaCoverageAnnotator) coverageAnnotator;
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage/src/com/intellij/coverage/DefaultJavaCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/DefaultJavaCoverageRunner.java
new file mode 100644
index 000000000000..feaf8b7871b2
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/DefaultJavaCoverageRunner.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.ConfigurationInfoProvider;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.execution.impl.DefaultJavaProgramRunner;
+import com.intellij.execution.runners.RunConfigurationWithSuppressedDefaultRunAction;
+import com.intellij.openapi.extensions.Extensions;
+import org.jetbrains.annotations.NotNull;
+
+public class DefaultJavaCoverageRunner extends DefaultJavaProgramRunner {
+ public boolean canRun(@NotNull final String executorId, @NotNull final RunProfile profile) {
+ try {
+ return executorId.equals(CoverageExecutor.EXECUTOR_ID) &&
+ //profile instanceof ModuleBasedConfiguration &&
+ !(profile instanceof RunConfigurationWithSuppressedDefaultRunAction) &&
+ profile instanceof RunConfigurationBase &&
+ Extensions.findExtension(CoverageEngine.EP_NAME, JavaCoverageEngine.class).isApplicableTo((RunConfigurationBase)profile);
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ @Override
+ public RunnerSettings createConfigurationData(ConfigurationInfoProvider settingsProvider) {
+ return new CoverageRunnerData();
+ }
+
+ @NotNull
+ @Override
+ public String getRunnerId() {
+ return "Cover";
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java
new file mode 100644
index 000000000000..a39ea67f4b49
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java
@@ -0,0 +1,76 @@
+/*
+ * User: anna
+ * Date: 20-May-2008
+ */
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.rt.coverage.util.ProjectDataLoader;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+public class IDEACoverageRunner extends JavaCoverageRunner {
+ private static final Logger LOG = Logger.getInstance("#" + IDEACoverageRunner.class.getName());
+
+ public ProjectData loadCoverageData(@NotNull final File sessionDataFile, @Nullable final CoverageSuite coverageSuite) {
+ return ProjectDataLoader.load(sessionDataFile);
+ }
+
+ public void appendCoverageArgument(final String sessionDataFilePath, final String[] patterns, final SimpleJavaParameters javaParameters,
+ final boolean collectLineInfo, final boolean isSampling) {
+ StringBuilder argument = new StringBuilder("-javaagent:");
+ final String agentPath = PathUtil.getJarPathForClass(ProjectData.class);
+ final String parentPath = handleSpacesInPath(agentPath);
+ argument.append(parentPath).append(File.separator).append(new File(agentPath).getName());
+ argument.append("=");
+ try {
+ final File tempFile = createTempFile();
+ tempFile.deleteOnExit();
+ write2file(tempFile, sessionDataFilePath);
+ write2file(tempFile, String.valueOf(collectLineInfo));
+ write2file(tempFile, Boolean.FALSE.toString()); //append unloaded
+ write2file(tempFile, Boolean.FALSE.toString());//merge with existing
+ write2file(tempFile, String.valueOf(isSampling));
+ if (patterns != null) {
+ for (String coveragePattern : patterns) {
+ coveragePattern = coveragePattern.replace("$", "\\$").replace(".", "\\.").replaceAll("\\*", ".*");
+ if (!coveragePattern.endsWith(".*")) { //include inner classes
+ coveragePattern += "(\\$.*)*";
+ }
+ write2file(tempFile, coveragePattern);
+ }
+ }
+ argument.append(tempFile.getCanonicalPath());
+ }
+ catch (IOException e) {
+ LOG.info("Coverage was not enabled", e);
+ return;
+ }
+
+ javaParameters.getVMParametersList().add(argument.toString());
+ }
+
+
+ public String getPresentableName() {
+ return "IntelliJ IDEA";
+ }
+
+ public String getId() {
+ return "idea";
+ }
+
+ public String getDataFileExtension() {
+ return "ic";
+ }
+
+ @Override
+ public boolean isCoverageByTestApplicable() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/plugins/coverage/src/com/intellij/coverage/IdeaClassFinder.java b/plugins/coverage/src/com/intellij/coverage/IdeaClassFinder.java
new file mode 100644
index 000000000000..e44dfe46d6f3
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/IdeaClassFinder.java
@@ -0,0 +1,78 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.rt.coverage.util.classFinder.ClassFinder;
+import com.intellij.rt.coverage.util.classFinder.ClassPathEntry;
+import com.intellij.util.lang.UrlClassLoader;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+* @author anna
+*/
+class IdeaClassFinder extends ClassFinder {
+ private static final Logger LOG = Logger.getInstance("#" + IdeaClassFinder.class.getName());
+
+ private final Project myProject;
+ private final CoverageSuitesBundle myCurrentSuite;
+
+ public IdeaClassFinder(Project project, CoverageSuitesBundle currentSuite) {
+ super(obtainPatternsFromSuite(currentSuite), new ArrayList());
+ myProject = project;
+ myCurrentSuite = currentSuite;
+ }
+
+ private static List<Pattern> obtainPatternsFromSuite(CoverageSuitesBundle currentSuiteBundle) {
+ final List<Pattern> includePatterns = new ArrayList<Pattern>();
+ for (CoverageSuite currentSuite : currentSuiteBundle.getSuites()) {
+ for (String pattern : ((JavaCoverageSuite)currentSuite).getFilteredPackageNames()) {
+ includePatterns.add(Pattern.compile(pattern + ".*"));
+ }
+
+ for (String pattern : ((JavaCoverageSuite)currentSuite).getFilteredClassNames()) {
+ includePatterns.add(Pattern.compile(pattern));
+ }
+ }
+ return includePatterns;
+ }
+
+ @Override
+ protected Collection getClassPathEntries() {
+ final Collection entries = super.getClassPathEntries();
+ final Module[] modules = ModuleManager.getInstance(myProject).getModules();
+ for (Module module : modules) {
+ final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+ if (extension != null) {
+ final VirtualFile outputFile = extension.getCompilerOutputPath();
+ try {
+ if (outputFile != null) {
+ final URL outputURL = VfsUtilCore.virtualToIoFile(outputFile).toURI().toURL();
+ entries.add(new ClassPathEntry(outputFile.getPath(), UrlClassLoader.build().urls(outputURL).get()));
+ }
+ if (myCurrentSuite.isTrackTestFolders()) {
+ final VirtualFile testOutput = extension.getCompilerOutputPathForTests();
+ if (testOutput != null) {
+ final URL testOutputURL = VfsUtilCore.virtualToIoFile(testOutput).toURI().toURL();
+ entries.add(new ClassPathEntry(testOutput.getPath(), UrlClassLoader.build().urls(testOutputURL).get()));
+ }
+ }
+ }
+ catch (MalformedURLException e1) {
+ LOG.error(e1);
+ }
+ }
+ }
+ return entries;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java
new file mode 100644
index 000000000000..866fb582aaff
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java
@@ -0,0 +1,152 @@
+/*
+ * User: anna
+ * Date: 20-May-2008
+ */
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.PathUtil;
+import org.jacoco.core.analysis.*;
+import org.jacoco.core.data.ExecutionDataReader;
+import org.jacoco.core.data.ExecutionDataStore;
+import org.jacoco.core.data.ISessionInfoVisitor;
+import org.jacoco.core.data.SessionInfo;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collection;
+
+public class JaCoCoCoverageRunner extends JavaCoverageRunner {
+ private static final Logger LOG = Logger.getInstance("#" + JaCoCoCoverageRunner.class.getName());
+
+ @Override
+ public ProjectData loadCoverageData(@NotNull File sessionDataFile, @Nullable CoverageSuite baseCoverageSuite) {
+ final ProjectData data = new ProjectData();
+ try {
+ final Project project = baseCoverageSuite instanceof BaseCoverageSuite ? ((BaseCoverageSuite)baseCoverageSuite).getProject() : null;
+ if (project != null) {
+ loadExecutionData(sessionDataFile, data, project);
+ }
+ }
+ catch (Exception e) {
+ return data;
+ }
+ return data;
+ }
+
+ private static void loadExecutionData(@NotNull final File sessionDataFile, ProjectData data, @NotNull Project project) throws IOException {
+ final ExecutionDataStore executionDataStore = new ExecutionDataStore();
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(sessionDataFile);
+ final ExecutionDataReader executionDataReader = new ExecutionDataReader(fis);
+
+ executionDataReader.setExecutionDataVisitor(executionDataStore);
+ executionDataReader.setSessionInfoVisitor(new ISessionInfoVisitor() {
+ public void visitSessionInfo(SessionInfo info) {
+ System.out.println(info.toString());
+ }
+ });
+
+ while (executionDataReader.read()) {
+ }
+ }
+ finally {
+ if (fis != null) {
+ fis.close();
+ }
+ }
+
+ final CoverageBuilder coverageBuilder = new CoverageBuilder();
+ final Analyzer analyzer = new Analyzer(executionDataStore, coverageBuilder);
+
+ final Module[] modules = ModuleManager.getInstance(project).getModules();
+ for (Module module : modules) {
+ final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+ if (compilerModuleExtension != null) {
+ final VirtualFile[] roots = compilerModuleExtension.getOutputRoots(true);
+ for (VirtualFile root : roots) {
+ analyzer.analyzeAll(VfsUtil.virtualToIoFile(root));
+ }
+ }
+ }
+
+ for (IClassCoverage classCoverage : coverageBuilder.getClasses()) {
+ String className = classCoverage.getName();
+ className = className.replace('\\', '.').replace('/', '.');
+ final ClassData classData = data.getOrCreateClassData(className);
+ final Collection<IMethodCoverage> methods = classCoverage.getMethods();
+ LineData[] lines = new LineData[classCoverage.getLastLine()];
+ for (IMethodCoverage method : methods) {
+ final String desc = method.getName() + method.getDesc();
+ final int firstLine = method.getFirstLine();
+ final int lastLine = method.getLastLine();
+ for (int i = firstLine; i < lastLine; i++) {
+ final ILine methodLine = method.getLine(i);
+ final int methodLineStatus = methodLine.getStatus();
+ final LineData lineData = new LineData(i , desc) {
+ @Override
+ public int getStatus() {
+ switch (methodLineStatus) {
+ case ICounter.FULLY_COVERED:
+ return LineCoverage.FULL;
+ case ICounter.PARTLY_COVERED:
+ return LineCoverage.PARTIAL;
+ default:
+ return LineCoverage.NONE;
+ }
+ }
+ };
+ lineData.setHits(methodLineStatus == ICounter.FULLY_COVERED || methodLineStatus == ICounter.PARTLY_COVERED ? 1 : 0);
+ lines[i] = lineData;
+ }
+ }
+ classData.setLines(lines);
+ }
+ }
+
+
+ public void appendCoverageArgument(final String sessionDataFilePath, final String[] patterns, final SimpleJavaParameters javaParameters,
+ final boolean collectLineInfo, final boolean isSampling) {
+ StringBuffer argument = new StringBuffer("-javaagent:");
+ final String agentPath = PathUtil.getJarPathForClass(org.jacoco.agent.rt.RT.class);
+ final String parentPath = handleSpacesInPath(agentPath);
+ argument.append(parentPath).append(File.separator).append(new File(agentPath).getName());
+ argument.append("=");
+ argument.append("destfile=").append(sessionDataFilePath);
+ argument.append(",append=false");
+ javaParameters.getVMParametersList().add(argument.toString());
+ }
+
+
+ public String getPresentableName() {
+ return "JaCoCo";
+ }
+
+ public String getId() {
+ return "jacoco";
+ }
+
+ public String getDataFileExtension() {
+ return "exec";
+ }
+
+ @Override
+ public boolean isCoverageByTestApplicable() {
+ return false;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java
new file mode 100644
index 000000000000..6c9be40eb590
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageAnnotator.java
@@ -0,0 +1,283 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public class JavaCoverageAnnotator extends BaseCoverageAnnotator {
+ private final Map<String, PackageAnnotator.PackageCoverageInfo> myPackageCoverageInfos = new HashMap<String, PackageAnnotator.PackageCoverageInfo>();
+ private final Map<String, PackageAnnotator.PackageCoverageInfo> myFlattenPackageCoverageInfos = new HashMap<String, PackageAnnotator.PackageCoverageInfo>();
+ private final Map<VirtualFile, PackageAnnotator.PackageCoverageInfo> myDirCoverageInfos =
+ new HashMap<VirtualFile, PackageAnnotator.PackageCoverageInfo>();
+ private final Map<VirtualFile, PackageAnnotator.PackageCoverageInfo> myTestDirCoverageInfos =
+ new HashMap<VirtualFile, PackageAnnotator.PackageCoverageInfo>();
+ private final Map<String, PackageAnnotator.ClassCoverageInfo> myClassCoverageInfos = new HashMap<String, PackageAnnotator.ClassCoverageInfo>();
+
+ public JavaCoverageAnnotator(final Project project) {
+ super(project);
+ }
+
+ public static JavaCoverageAnnotator getInstance(final Project project) {
+ return ServiceManager.getService(project, JavaCoverageAnnotator.class);
+ }
+
+ @Nullable
+ public String getDirCoverageInformationString(@NotNull final PsiDirectory directory,
+ @NotNull final CoverageSuitesBundle currentSuite,
+ @NotNull final CoverageDataManager coverageDataManager) {
+ final PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(directory);
+ if (psiPackage == null) return null;
+
+ final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex();
+ final VirtualFile virtualFile = directory.getVirtualFile();
+
+ final boolean isInTestContent = projectFileIndex.isInTestSourceContent(virtualFile);
+
+ if (!currentSuite.isTrackTestFolders() && isInTestContent) {
+ return null;
+ }
+ return isInTestContent ? getCoverageInformationString(myTestDirCoverageInfos.get(virtualFile), coverageDataManager.isSubCoverageActive())
+ : getCoverageInformationString(myDirCoverageInfos.get(virtualFile), coverageDataManager.isSubCoverageActive());
+
+ }
+
+ @Nullable
+ public String getFileCoverageInformationString(@NotNull PsiFile file, @NotNull CoverageSuitesBundle currentSuite, @NotNull CoverageDataManager manager) {
+ // N/A here we work with java classes
+ return null;
+ }
+
+ public void onSuiteChosen(CoverageSuitesBundle newSuite) {
+ super.onSuiteChosen(newSuite);
+
+ myPackageCoverageInfos.clear();
+ myFlattenPackageCoverageInfos.clear();
+ myDirCoverageInfos.clear();
+ myTestDirCoverageInfos.clear();
+ myClassCoverageInfos.clear();
+ }
+
+ protected Runnable createRenewRequest(@NotNull final CoverageSuitesBundle suite, @NotNull final CoverageDataManager dataManager) {
+
+
+ final Project project = getProject();
+ final List<PsiPackage> packages = new ArrayList<PsiPackage>();
+ final List<PsiClass> classes = new ArrayList<PsiClass>();
+
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ final JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite;
+ classes.addAll(javaSuite.getCurrentSuiteClasses(project));
+ packages.addAll(javaSuite.getCurrentSuitePackages(project));
+ }
+
+ if (packages.isEmpty() && classes.isEmpty()) {
+ return null;
+ }
+
+ return new Runnable() {
+ public void run() {
+ final PackageAnnotator.Annotator annotator = new PackageAnnotator.Annotator() {
+ public void annotatePackage(String packageQualifiedName, PackageAnnotator.PackageCoverageInfo packageCoverageInfo) {
+ myPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo);
+ }
+
+ public void annotatePackage(String packageQualifiedName,
+ PackageAnnotator.PackageCoverageInfo packageCoverageInfo,
+ boolean flatten) {
+ if (flatten) {
+ myFlattenPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo);
+ }
+ else {
+ annotatePackage(packageQualifiedName, packageCoverageInfo);
+ }
+ }
+
+ public void annotateSourceDirectory(VirtualFile dir,
+ PackageAnnotator.PackageCoverageInfo dirCoverageInfo,
+ Module module) {
+ myDirCoverageInfos.put(dir, dirCoverageInfo);
+ }
+
+ public void annotateTestDirectory(VirtualFile virtualFile,
+ PackageAnnotator.PackageCoverageInfo packageCoverageInfo,
+ Module module) {
+ myTestDirCoverageInfos.put(virtualFile, packageCoverageInfo);
+ }
+
+ public void annotateClass(String classQualifiedName, PackageAnnotator.ClassCoverageInfo classCoverageInfo) {
+ myClassCoverageInfos.put(classQualifiedName, classCoverageInfo);
+ }
+ };
+ for (PsiPackage aPackage : packages) {
+ new PackageAnnotator(aPackage).annotate(suite, annotator);
+ }
+ for (final PsiClass aClass : classes) {
+ Runnable runnable = new Runnable() {
+ public void run() {
+ final String packageName = ((PsiClassOwner)aClass.getContainingFile()).getPackageName();
+ final PsiPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName);
+ if (psiPackage == null) return;
+ new PackageAnnotator(psiPackage).annotateFilteredClass(aClass, suite, annotator);
+ }
+ };
+ ApplicationManager.getApplication().runReadAction(runnable);
+ }
+ dataManager.triggerPresentationUpdate();
+ }
+ };
+ }
+
+ @Nullable
+ public static String getCoverageInformationString(PackageAnnotator.PackageCoverageInfo info, boolean subCoverageActive) {
+ if (info == null) return null;
+ if (info.totalClassCount == 0 || info.totalLineCount == 0) return null;
+ if (subCoverageActive) {
+ return info.coveredClassCount + info.coveredLineCount > 0 ? "covered" : null;
+ }
+ return (int)((double)info.coveredClassCount / info.totalClassCount * 100) + "% classes, " +
+ (int)((double)info.coveredLineCount / info.totalLineCount * 100) + "% lines covered";
+ }
+
+ /**
+ *
+ * @param psiPackage qualified name of a package to obtain coverage information for
+ * @param module optional parameter to restrict coverage to source directories of a certain module
+ * @param coverageDataManager
+ * @return human-readable coverage information
+ */
+ @Nullable
+ public String getPackageCoverageInformationString(final PsiPackage psiPackage,
+ @Nullable final Module module,
+ @NotNull final CoverageDataManager coverageDataManager) {
+ return getPackageCoverageInformationString(psiPackage, module, coverageDataManager, false);
+ }
+
+ /**
+ *
+ *
+ * @param psiPackage qualified name of a package to obtain coverage information for
+ * @param module optional parameter to restrict coverage to source directories of a certain module
+ * @param coverageDataManager
+ * @param flatten
+ * @return human-readable coverage information
+ */
+ @Nullable
+ public String getPackageCoverageInformationString(final PsiPackage psiPackage,
+ @Nullable final Module module,
+ @NotNull final CoverageDataManager coverageDataManager,
+ boolean flatten) {
+ if (psiPackage == null) return null;
+ final boolean subCoverageActive = coverageDataManager.isSubCoverageActive();
+ PackageAnnotator.PackageCoverageInfo info;
+ if (module != null) {
+ final PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module));
+ PackageAnnotator.PackageCoverageInfo result = null;
+ for (PsiDirectory directory : directories) {
+ final VirtualFile virtualFile = directory.getVirtualFile();
+ result = merge(result, myDirCoverageInfos.get(virtualFile));
+ result = merge(result, myTestDirCoverageInfos.get(virtualFile));
+ }
+ return getCoverageInformationString(result, subCoverageActive);
+ }
+ else {
+ info = getPackageCoverageInfo(psiPackage, flatten);
+ }
+ return getCoverageInformationString(info, subCoverageActive);
+ }
+
+ public PackageAnnotator.PackageCoverageInfo getPackageCoverageInfo(@NotNull PsiPackage psiPackage, boolean flattenPackages) {
+ final String qualifiedName = psiPackage.getQualifiedName();
+ return flattenPackages ? myFlattenPackageCoverageInfos.get(qualifiedName) : myPackageCoverageInfos.get(qualifiedName);
+ }
+
+ public String getPackageClassPercentage(@NotNull final PsiPackage psiPackage, boolean flatten) {
+ final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten);
+ if (packageCoverageInfo == null) return null;
+ return getPercentage(packageCoverageInfo.coveredClassCount, packageCoverageInfo.totalClassCount);
+ }
+
+ public String getPackageMethodPercentage(PsiPackage psiPackage, boolean flatten) {
+ final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten);
+ if (packageCoverageInfo == null) return null;
+ return getPercentage(packageCoverageInfo.coveredMethodCount, packageCoverageInfo.totalMethodCount);
+ }
+
+ public String getPackageLinePercentage(final PsiPackage psiPackage, boolean flatten) {
+ final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten);
+ if (packageCoverageInfo == null) return null;
+ return getPercentage(packageCoverageInfo.coveredLineCount, packageCoverageInfo.totalLineCount);
+ }
+
+ public String getClassLinePercentage(String classFQName) {
+ final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName);
+ if (info == null) return null;
+ final int coveredLines = info.fullyCoveredLineCount + info.partiallyCoveredLineCount;
+ return getPercentage(coveredLines, info.totalLineCount);
+ }
+
+ public String getClassMethodPercentage(String classFQName) {
+ final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName);
+ if (info == null) return null;
+ return getPercentage(info.coveredMethodCount, info.totalMethodCount);
+ }
+
+ public String getClassCoveredPercentage(String classFQName) {
+ final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName);
+ if (info == null) return null;
+ return getPercentage(info.coveredClassCount, info.totalClassCount);
+ }
+
+ private static String getPercentage(int covered, int total) {
+ return (int)((double)covered /total * 100) +"% (" + covered + "/" + total + ")";
+ }
+
+ public static PackageAnnotator.PackageCoverageInfo merge(final PackageAnnotator.PackageCoverageInfo info,
+ final PackageAnnotator.PackageCoverageInfo testInfo) {
+ if (info == null) return testInfo;
+ if (testInfo == null) return info;
+ final PackageAnnotator.PackageCoverageInfo coverageInfo = new PackageAnnotator.PackageCoverageInfo();
+ coverageInfo.totalClassCount = info.totalClassCount + testInfo.totalClassCount;
+ coverageInfo.coveredClassCount = info.coveredClassCount + testInfo.coveredClassCount;
+
+ coverageInfo.totalLineCount = info.totalLineCount + testInfo.totalLineCount;
+ coverageInfo.coveredLineCount = info.coveredLineCount + testInfo.coveredLineCount;
+ return coverageInfo;
+ }
+
+ /**
+ * @param classFQName to obtain coverage information for
+ * @return human-readable coverage information
+ */
+ @Nullable
+ public String getClassCoverageInformationString(String classFQName, CoverageDataManager coverageDataManager) {
+ final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName);
+ if (info == null) return null;
+ if (info.totalMethodCount == 0 || info.totalLineCount == 0) return null;
+ if (coverageDataManager.isSubCoverageActive()){
+ return info.coveredMethodCount + info.fullyCoveredLineCount + info.partiallyCoveredLineCount > 0 ? "covered" : null;
+ }
+ return (int)((double)info.coveredMethodCount / info.totalMethodCount * 100) + "% methods, " +
+ (int)((double)(info.fullyCoveredLineCount + info.partiallyCoveredLineCount) / info.totalLineCount * 100) + "% lines covered";
+ }
+
+ @Nullable
+ public PackageAnnotator.ClassCoverageInfo getClassCoverageInfo(String classFQName) {
+ return myClassCoverageInfos.get(classFQName);
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java
new file mode 100644
index 000000000000..0e32f5c3b60a
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngine.java
@@ -0,0 +1,670 @@
+package com.intellij.coverage;
+
+import com.intellij.CommonBundle;
+import com.intellij.codeEditor.printing.ExportToHTMLSettings;
+import com.intellij.coverage.view.CoverageViewExtension;
+import com.intellij.coverage.view.CoverageViewManager;
+import com.intellij.coverage.view.JavaCoverageViewExtension;
+import com.intellij.execution.CommonJavaRunConfigurationParameters;
+import com.intellij.execution.application.ApplicationConfiguration;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.configurations.coverage.JavaCoverageEnabledConfiguration;
+import com.intellij.execution.testframework.AbstractTestProxy;
+import com.intellij.ide.BrowserUtil;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.controlFlow.*;
+import com.intellij.psi.impl.source.tree.java.PsiSwitchStatementImpl;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScopes;
+import com.intellij.psi.util.ClassUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.rt.coverage.data.JumpData;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.rt.coverage.data.SwitchData;
+import com.intellij.rt.coverage.instrumentation.SaveHook;
+import com.intellij.util.containers.HashSet;
+import jetbrains.coverage.report.ClassInfo;
+import jetbrains.coverage.report.ReportBuilderFactory;
+import jetbrains.coverage.report.ReportGenerationFailedException;
+import jetbrains.coverage.report.SourceCodeProvider;
+import jetbrains.coverage.report.html.HTMLReportBuilder;
+import jetbrains.coverage.report.idea.IDEACoverageData;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public class JavaCoverageEngine extends CoverageEngine {
+ private static final Logger LOG = Logger.getInstance(JavaCoverageEngine.class.getName());
+
+ @Override
+ public boolean isApplicableTo(@Nullable final RunConfigurationBase conf) {
+ if (conf instanceof CommonJavaRunConfigurationParameters) {
+ return true;
+ }
+ for (JavaCoverageEngineExtension extension : Extensions.getExtensions(JavaCoverageEngineExtension.EP_NAME)) {
+ if (extension.isApplicableTo(conf)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canHavePerTestCoverage(@Nullable RunConfigurationBase conf) {
+ return !(conf instanceof ApplicationConfiguration) && conf instanceof CommonJavaRunConfigurationParameters;
+ }
+
+ @NotNull
+ @Override
+ public CoverageEnabledConfiguration createCoverageEnabledConfiguration(@Nullable final RunConfigurationBase conf) {
+ return new JavaCoverageEnabledConfiguration(conf, this);
+ }
+
+ @Nullable
+ @Override
+ public CoverageSuite createCoverageSuite(@NotNull final CoverageRunner covRunner,
+ @NotNull final String name,
+ @NotNull final CoverageFileProvider coverageDataFileProvider,
+ String[] filters,
+ long lastCoverageTimeStamp,
+ String suiteToMerge,
+ boolean coverageByTestEnabled,
+ boolean tracingEnabled,
+ boolean trackTestFolders, Project project) {
+
+ return createSuite(covRunner, name, coverageDataFileProvider, filters, lastCoverageTimeStamp, coverageByTestEnabled,
+ tracingEnabled, trackTestFolders, project);
+ }
+
+ @Override
+ public CoverageSuite createCoverageSuite(@NotNull final CoverageRunner covRunner,
+ @NotNull final String name,
+ @NotNull final CoverageFileProvider coverageDataFileProvider,
+ @NotNull final CoverageEnabledConfiguration config) {
+ if (config instanceof JavaCoverageEnabledConfiguration) {
+ final JavaCoverageEnabledConfiguration javaConfig = (JavaCoverageEnabledConfiguration)config;
+ return createSuite(covRunner, name, coverageDataFileProvider,
+ javaConfig.getPatterns(),
+ new Date().getTime(),
+ javaConfig.isTrackPerTestCoverage() && !javaConfig.isSampling(),
+ !javaConfig.isSampling(),
+ javaConfig.isTrackTestFolders(), config.getConfiguration().getProject());
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public CoverageSuite createEmptyCoverageSuite(@NotNull CoverageRunner coverageRunner) {
+ return new JavaCoverageSuite(this);
+ }
+
+ @NotNull
+ @Override
+ public CoverageAnnotator getCoverageAnnotator(Project project) {
+ return JavaCoverageAnnotator.getInstance(project);
+ }
+
+ /**
+ * Determines if coverage information should be displayed for given file
+ * @param psiFile
+ * @return
+ */
+ public boolean coverageEditorHighlightingApplicableTo(@NotNull final PsiFile psiFile) {
+ if (!(psiFile instanceof PsiClassOwner)) {
+ return false;
+ }
+ // let's show coverage only for module files
+ final Module module = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+ @Nullable
+ public Module compute() {
+ return ModuleUtil.findModuleForPsiElement(psiFile);
+ }
+ });
+ return module != null;
+ }
+
+ public boolean acceptedByFilters(@NotNull final PsiFile psiFile, @NotNull final CoverageSuitesBundle suite) {
+ final VirtualFile virtualFile = psiFile.getVirtualFile();
+ if (virtualFile == null) return false;
+ final Project project = psiFile.getProject();
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ if (!suite.isTrackTestFolders() && fileIndex.isInTestSourceContent(virtualFile)) {
+ return false;
+ }
+
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ final JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite;
+
+ final List<PsiPackage> packages = javaSuite.getCurrentSuitePackages(project);
+ if (isUnderFilteredPackages((PsiClassOwner)psiFile, packages)) {
+ return true;
+ } else {
+ final List<PsiClass> classes = javaSuite.getCurrentSuiteClasses(project);
+ for (PsiClass aClass : classes) {
+ final PsiFile containingFile = aClass.getContainingFile();
+ if (psiFile.equals(containingFile)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean recompileProjectAndRerunAction(@NotNull final Module module, @NotNull final CoverageSuitesBundle suite,
+ @NotNull final Runnable chooseSuiteAction) {
+ final VirtualFile outputpath = CompilerModuleExtension.getInstance(module).getCompilerOutputPath();
+ final VirtualFile testOutputpath = CompilerModuleExtension.getInstance(module).getCompilerOutputPathForTests();
+
+ if ((outputpath == null && isModuleOutputNeeded(module, JavaSourceRootType.SOURCE))
+ || (suite.isTrackTestFolders() && testOutputpath == null && isModuleOutputNeeded(module, JavaSourceRootType.TEST_SOURCE))) {
+ final Project project = module.getProject();
+ if (suite.isModuleChecked(module)) return false;
+ suite.checkModule(module);
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ if (Messages.showOkCancelDialog(
+ "Project class files are out of date. Would you like to recompile? The refusal to do it will result in incomplete coverage information",
+ "Project is out of date", Messages.getWarningIcon()) == Messages.OK) {
+ final CompilerManager compilerManager = CompilerManager.getInstance(project);
+ compilerManager.make(compilerManager.createProjectCompileScope(project), new CompileStatusNotification() {
+ public void finished(final boolean aborted, final int errors, final int warnings, final CompileContext compileContext) {
+ if (aborted || errors != 0) return;
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (project.isDisposed()) return;
+ CoverageDataManager.getInstance(project).chooseSuitesBundle(suite);
+ }
+ });
+ }
+ });
+ } else if (!project.isDisposed()) {
+ CoverageDataManager.getInstance(project).chooseSuitesBundle(null);
+ }
+ }
+ };
+ ApplicationManager.getApplication().invokeLater(runnable);
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean isModuleOutputNeeded(Module module, final JavaSourceRootType rootType) {
+ return !ModuleRootManager.getInstance(module).getSourceRoots(rootType).isEmpty();
+ }
+
+ public static boolean isUnderFilteredPackages(final PsiClassOwner javaFile, final List<PsiPackage> packages) {
+ final String hisPackageName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ public String compute() {
+ return javaFile.getPackageName();
+ }
+ });
+ PsiPackage hisPackage = JavaPsiFacade.getInstance(javaFile.getProject()).findPackage(hisPackageName);
+ if (hisPackage == null) return false;
+ for (PsiPackage aPackage : packages) {
+ if (PsiTreeUtil.isAncestor(aPackage, hisPackage, false)) return true;
+ }
+ return false;
+ }
+
+ @Nullable
+ public List<Integer> collectSrcLinesForUntouchedFile(@NotNull final File classFile, @NotNull final CoverageSuitesBundle suite) {
+ final List<Integer> uncoveredLines = new ArrayList<Integer>();
+
+ final byte[] content;
+ try {
+ content = FileUtil.loadFileBytes(classFile);
+ }
+ catch (IOException e) {
+ return null;
+ }
+
+ try {
+ SourceLineCounterUtil.collectSrcLinesForUntouchedFiles(uncoveredLines, content, suite.isTracingEnabled());
+ }
+ catch (Exception e) {
+ LOG.error("Fail to process class from: " + classFile.getPath(), e);
+ }
+ return uncoveredLines;
+ }
+
+ public boolean includeUntouchedFileInCoverage(@NotNull final String qualifiedName,
+ @NotNull final File outputFile,
+ @NotNull final PsiFile sourceFile, @NotNull CoverageSuitesBundle suite) {
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ final JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite;
+ if (javaSuite.isClassFiltered(qualifiedName) || javaSuite.isPackageFiltered(getPackageName(sourceFile))) return true;
+ }
+ return false;
+ }
+
+
+ public String getQualifiedName(@NotNull final File outputFile, @NotNull final PsiFile sourceFile) {
+ final String packageFQName = getPackageName(sourceFile);
+ return StringUtil.getQualifiedName(packageFQName, FileUtil.getNameWithoutExtension(outputFile));
+ }
+
+ @NotNull
+ @Override
+ public Set<String> getQualifiedNames(@NotNull final PsiFile sourceFile) {
+ final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+ public PsiClass[] compute() {
+ return ((PsiClassOwner)sourceFile).getClasses();
+ }
+ });
+ final Set<String> qNames = new HashSet<String>();
+ for (final JavaCoverageEngineExtension nameExtension : Extensions.getExtensions(JavaCoverageEngineExtension.EP_NAME)) {
+ if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return nameExtension.suggestQualifiedName(sourceFile, classes, qNames);
+ }
+ })) {
+ return qNames;
+ }
+ }
+ for (final PsiClass aClass : classes) {
+ final String qName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Nullable
+ public String compute() {
+ return aClass.getQualifiedName();
+ }
+ });
+ if (qName == null) continue;
+ qNames.add(qName);
+ }
+ return qNames;
+ }
+
+ @NotNull
+ public Set<File> getCorrespondingOutputFiles(@NotNull final PsiFile srcFile,
+ @Nullable final Module module,
+ @NotNull final CoverageSuitesBundle suite) {
+ if (module == null) {
+ return Collections.emptySet();
+ }
+ final Set<File> classFiles = new HashSet<File>();
+ final VirtualFile outputpath = CompilerModuleExtension.getInstance(module).getCompilerOutputPath();
+ final VirtualFile testOutputpath = CompilerModuleExtension.getInstance(module).getCompilerOutputPathForTests();
+
+ for (JavaCoverageEngineExtension extension : Extensions.getExtensions(JavaCoverageEngineExtension.EP_NAME)) {
+ if (extension.collectOutputFiles(srcFile, outputpath, testOutputpath, suite, classFiles)) return classFiles;
+ }
+
+ final String packageFQName = getPackageName(srcFile);
+ final String packageVmName = packageFQName.replace('.', '/');
+
+ final List<File> children = new ArrayList<File>();
+ final File vDir =
+ outputpath == null
+ ? null : packageVmName.length() > 0
+ ? new File(outputpath.getPath() + File.separator + packageVmName) : VfsUtilCore.virtualToIoFile(outputpath);
+ if (vDir != null && vDir.exists()) {
+ Collections.addAll(children, vDir.listFiles());
+ }
+
+ if (suite.isTrackTestFolders()) {
+ final File testDir =
+ testOutputpath == null
+ ? null : packageVmName.length() > 0
+ ? new File(testOutputpath.getPath() + File.separator + packageVmName) : VfsUtilCore.virtualToIoFile(testOutputpath);
+ if (testDir != null && testDir.exists()) {
+ Collections.addAll(children, testDir.listFiles());
+ }
+ }
+
+ final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+ public PsiClass[] compute() {
+ return ((PsiClassOwner)srcFile).getClasses();
+ }
+ });
+ for (final PsiClass psiClass : classes) {
+ final String className = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ public String compute() {
+ return psiClass.getName();
+ }
+ });
+ for (File child : children) {
+ if (FileUtilRt.extensionEquals(child.getName(), StdFileTypes.CLASS.getDefaultExtension())) {
+ final String childName = FileUtil.getNameWithoutExtension(child);
+ if (childName.equals(className) || //class or inner
+ childName.startsWith(className) && childName.charAt(className.length()) == '$') {
+ classFiles.add(child);
+ }
+ }
+ }
+ }
+ return classFiles;
+ }
+
+ public String generateBriefReport(@NotNull Editor editor,
+ @NotNull PsiFile psiFile,
+ int lineNumber,
+ int startOffset,
+ int endOffset,
+ @Nullable LineData lineData) {
+
+ final StringBuffer buf = new StringBuffer();
+ buf.append("Hits: ");
+ if (lineData == null) {
+ buf.append(0);
+ return buf.toString();
+ }
+ buf.append(lineData.getHits()).append("\n");
+
+ final List<PsiExpression> expressions = new ArrayList<PsiExpression>();
+
+ final Project project = editor.getProject();
+ for(int offset = startOffset; offset < endOffset; offset++) {
+ PsiElement parent = PsiTreeUtil.getParentOfType(psiFile.findElementAt(offset), PsiStatement.class);
+ PsiElement condition = null;
+ if (parent instanceof PsiIfStatement) {
+ condition = ((PsiIfStatement)parent).getCondition();
+ } else if (parent instanceof PsiSwitchStatement) {
+ condition = ((PsiSwitchStatement)parent).getExpression();
+ } else if (parent instanceof PsiDoWhileStatement) {
+ condition = ((PsiDoWhileStatement)parent).getCondition();
+ } else if (parent instanceof PsiForStatement) {
+ condition = ((PsiForStatement)parent).getCondition();
+ } else if (parent instanceof PsiWhileStatement) {
+ condition = ((PsiWhileStatement)parent).getCondition();
+ } else if (parent instanceof PsiForeachStatement) {
+ condition = ((PsiForeachStatement)parent).getIteratedValue();
+ } else if (parent instanceof PsiAssertStatement) {
+ condition = ((PsiAssertStatement)parent).getAssertCondition();
+ }
+ if (condition != null && PsiTreeUtil.isAncestor(condition, psiFile.findElementAt(offset), false)) {
+ try {
+ final ControlFlow controlFlow = ControlFlowFactory.getInstance(project).getControlFlow(
+ parent, AllVariablesControlFlowPolicy.getInstance());
+ for (Instruction instruction : controlFlow.getInstructions()) {
+ if (instruction instanceof ConditionalBranchingInstruction) {
+ final PsiExpression expression = ((ConditionalBranchingInstruction)instruction).expression;
+ if (!expressions.contains(expression)) {
+ expressions.add(expression);
+ }
+ }
+ }
+ }
+ catch (AnalysisCanceledException e) {
+ return buf.toString();
+ }
+ }
+ }
+
+ final String indent = " ";
+ try {
+ int idx = 0;
+ int hits = 0;
+ if (lineData.getJumps() != null) {
+ for (Object o : lineData.getJumps()) {
+ final JumpData jumpData = (JumpData)o;
+ if (jumpData.getTrueHits() + jumpData.getFalseHits() > 0) {
+ final PsiExpression expression = expressions.get(idx++);
+ final PsiElement parentExpression = expression.getParent();
+ boolean reverse = parentExpression instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)parentExpression).getOperationTokenType() == JavaTokenType.OROR
+ || parentExpression instanceof PsiDoWhileStatement || parentExpression instanceof PsiAssertStatement;
+ buf.append(indent).append(expression.getText()).append("\n");
+ buf.append(indent).append(indent).append("true hits: ").append(reverse ? jumpData.getFalseHits() : jumpData.getTrueHits()).append("\n");
+ buf.append(indent).append(indent).append("false hits: ").append(reverse ? jumpData.getTrueHits() : jumpData.getFalseHits()).append("\n");
+ hits += jumpData.getTrueHits() + jumpData.getFalseHits();
+ }
+ }
+ }
+
+ if (lineData.getSwitches() != null) {
+ for (Object o : lineData.getSwitches()) {
+ final SwitchData switchData = (SwitchData)o;
+ final PsiExpression conditionExpression = expressions.get(idx++);
+ buf.append(indent).append(conditionExpression.getText()).append("\n");
+ int i = 0;
+ for (int key : switchData.getKeys()) {
+ final int switchHits = switchData.getHits()[i++];
+ buf.append(indent).append(indent).append("case ").append(key).append(": ").append(switchHits).append("\n");
+ hits += switchHits;
+ }
+ int defaultHits = switchData.getDefaultHits();
+ final boolean hasDefaultLabel = hasDefaultLabel(conditionExpression);
+ if (hasDefaultLabel || defaultHits > 0) {
+ if (!hasDefaultLabel) {
+ defaultHits -= hits;
+ }
+
+ if (hasDefaultLabel || defaultHits > 0) {
+ buf.append(indent).append(indent).append("default: ").append(defaultHits).append("\n");
+ hits += defaultHits;
+ }
+ }
+ }
+ }
+ if (lineData.getHits() > hits && hits > 0) {
+ buf.append("Unknown outcome: ").append(lineData.getHits() - hits);
+ }
+ }
+ catch (Exception e) {
+ LOG.info(e);
+ return "Hits: " + lineData.getHits();
+ }
+ return buf.toString();
+ }
+
+ @Nullable
+ public String getTestMethodName(@NotNull final PsiElement element,
+ @NotNull final AbstractTestProxy testProxy) {
+ return testProxy.toString();
+ }
+
+
+ @NotNull
+ public List<PsiElement> findTestsByNames(@NotNull String[] testNames, @NotNull Project project) {
+ final List<PsiElement> elements = new ArrayList<PsiElement>();
+ final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
+ final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(project);
+ for (String testName : testNames) {
+ PsiClass psiClass =
+ facade.findClass(StringUtil.getPackageName(testName, '_').replaceAll("\\_", "\\."), projectScope);
+ int lastIdx = testName.lastIndexOf("_");
+ if (psiClass != null) {
+ collectTestsByName(elements, testName, psiClass, lastIdx);
+ } else {
+ String className = testName;
+ while (lastIdx > 0) {
+ className = className.substring(0, lastIdx - 1);
+ psiClass = facade.findClass(StringUtil.getPackageName(className, '_').replaceAll("\\_", "\\."), projectScope);
+ lastIdx = className.lastIndexOf("_");
+ if (psiClass != null) {
+ collectTestsByName(elements, testName, psiClass, lastIdx);
+ break;
+ }
+ }
+ }
+ }
+ return elements;
+ }
+
+ private static void collectTestsByName(List<PsiElement> elements, String testName, PsiClass psiClass, int lastIdx) {
+ final PsiMethod[] testsByName = psiClass.findMethodsByName(testName.substring(lastIdx + 1), true);
+ if (testsByName.length == 1) {
+ elements.add(testsByName[0]);
+ }
+ }
+
+
+ private static boolean hasDefaultLabel(final PsiElement conditionExpression) {
+ boolean hasDefault = false;
+ final PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(conditionExpression, PsiSwitchStatement.class);
+ final PsiCodeBlock body = ((PsiSwitchStatementImpl)conditionExpression.getParent()).getBody();
+ if (body != null) {
+ final PsiElement bodyElement = body.getFirstBodyElement();
+ if (bodyElement != null) {
+ PsiSwitchLabelStatement label = PsiTreeUtil.getNextSiblingOfType(bodyElement, PsiSwitchLabelStatement.class);
+ while (label != null) {
+ if (label.getEnclosingSwitchStatement() == switchStatement) {
+ hasDefault |= label.isDefaultCase();
+ }
+ label = PsiTreeUtil.getNextSiblingOfType(label, PsiSwitchLabelStatement.class);
+ }
+ }
+ }
+ return hasDefault;
+ }
+
+ protected JavaCoverageSuite createSuite(CoverageRunner acceptedCovRunner,
+ String name, CoverageFileProvider coverageDataFileProvider,
+ String[] filters,
+ long lastCoverageTimeStamp,
+ boolean coverageByTestEnabled,
+ boolean tracingEnabled,
+ boolean trackTestFolders, Project project) {
+ return new JavaCoverageSuite(name, coverageDataFileProvider, filters, lastCoverageTimeStamp, coverageByTestEnabled, tracingEnabled,
+ trackTestFolders, acceptedCovRunner, this, project);
+ }
+
+ @NotNull
+ protected static String getPackageName(final PsiFile sourceFile) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ public String compute() {
+ return ((PsiClassOwner)sourceFile).getPackageName();
+ }
+ });
+ }
+
+ protected static void generateJavaReport(@NotNull final Project project,
+ final File tempFile,
+ final CoverageSuitesBundle currentSuite) {
+ final ExportToHTMLSettings settings = ExportToHTMLSettings.getInstance(project);
+ final ProjectData projectData = currentSuite.getCoverageData();
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, "Generating coverage report ...") {
+ final Exception[] myExceptions = new Exception[1];
+
+ public void run(@NotNull final ProgressIndicator indicator) {
+ try {
+ new SaveHook(tempFile, true, new IdeaClassFinder(project, currentSuite)).save(projectData);
+ final HTMLReportBuilder builder = ReportBuilderFactory.createHTMLReportBuilder();
+ builder.setReportDir(new File(settings.OUTPUT_DIRECTORY));
+ final SourceCodeProvider sourceCodeProvider = new SourceCodeProvider() {
+ public String getSourceCode(@NotNull final String classname) throws IOException {
+ return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ public String compute() {
+ final PsiClass psiClass = ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), classname);
+ return psiClass != null ? psiClass.getContainingFile().getText() : "";
+ }
+ });
+ }
+ };
+ builder.generateReport(new IDEACoverageData(projectData, sourceCodeProvider) {
+ @NotNull
+ @Override
+ public Collection<ClassInfo> getClasses() {
+ final Collection<ClassInfo> classes = super.getClasses();
+ if (!currentSuite.isTrackTestFolders()) {
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final GlobalSearchScope productionScope = GlobalSearchScopes.projectProductionScope(project);
+ for (Iterator<ClassInfo> iterator = classes.iterator(); iterator.hasNext();) {
+ final ClassInfo aClass = iterator.next();
+ final PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ return psiFacade.findClass(aClass.getFQName(), productionScope);
+ }
+ });
+ if (psiClass == null) {
+ iterator.remove();
+ }
+ }
+ }
+ return classes;
+ }
+ });
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ catch (ReportGenerationFailedException e) {
+ myExceptions[0] = e;
+ }
+ }
+
+ @Override
+ public void onSuccess() {
+ if (myExceptions[0] != null) {
+ Messages.showErrorDialog(project, myExceptions[0].getMessage(), CommonBundle.getErrorTitle());
+ return;
+ }
+ if (settings.OPEN_IN_BROWSER) {
+ BrowserUtil.browse(new File(settings.OUTPUT_DIRECTORY, "index.html"));
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean isReportGenerationAvailable(@NotNull Project project,
+ @NotNull DataContext dataContext,
+ @NotNull CoverageSuitesBundle currentSuite) {
+ Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
+ return projectSdk != null;
+ }
+
+ @Override
+ public final void generateReport(@NotNull final Project project,
+ @NotNull final DataContext dataContext,
+ @NotNull final CoverageSuitesBundle currentSuite) {
+ try {
+ final File tempFile = FileUtil.createTempFile("temp", "");
+ tempFile.deleteOnExit();
+ generateJavaReport(project, tempFile, currentSuite);
+ }
+ catch (IOException e1) {
+ LOG.error(e1);
+ }
+ }
+
+ @Override
+ public String getPresentableText() {
+ return "Java Coverage";
+ }
+
+ @Override
+ public CoverageViewExtension createCoverageViewExtension(Project project,
+ CoverageSuitesBundle suiteBundle,
+ CoverageViewManager.StateBean stateBean) {
+ return new JavaCoverageViewExtension((JavaCoverageAnnotator)getCoverageAnnotator(project), project, suiteBundle, stateBean);
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngineExtension.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngineExtension.java
new file mode 100644
index 000000000000..ee27aaa2a250
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageEngineExtension.java
@@ -0,0 +1,35 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 2/14/11
+ */
+public abstract class JavaCoverageEngineExtension {
+ public static final ExtensionPointName<JavaCoverageEngineExtension> EP_NAME = ExtensionPointName.create("com.intellij.javaCoverageEngineExtension");
+
+ public abstract boolean isApplicableTo(@Nullable RunConfigurationBase conf);
+
+ public boolean suggestQualifiedName(@NotNull PsiFile sourceFile, PsiClass[] classes, Set<String> names) {
+ return false;
+ }
+
+ public boolean collectOutputFiles(@NotNull final PsiFile srcFile,
+ @Nullable final VirtualFile output,
+ @Nullable final VirtualFile testoutput,
+ @NotNull final CoverageSuitesBundle suite,
+ @NotNull final Set<File> classFiles){
+ return false;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java
new file mode 100644
index 000000000000..314e07c23a8f
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java
@@ -0,0 +1,86 @@
+package com.intellij.coverage;
+
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Roman.Chernyatchik
+ */
+public abstract class JavaCoverageRunner extends CoverageRunner {
+ private static final Logger LOG = Logger.getInstance("#" + JavaCoverageRunner.class.getName());
+ private static final String COVERAGE_AGENT_PATH = "coverage.lib.path";
+
+ public boolean isJdk7Compatible() {
+ return true;
+ }
+
+ @Override
+ public boolean acceptsCoverageEngine(@NotNull CoverageEngine engine) {
+ return engine instanceof JavaCoverageEngine;
+ }
+
+ public abstract void appendCoverageArgument(final String sessionDataFilePath, @Nullable final String[] patterns, final SimpleJavaParameters parameters,
+ final boolean collectLineInfo, final boolean isSampling);
+
+ protected static String handleSpacesInPath(String agentPath) {
+ final String userDefined = System.getProperty(COVERAGE_AGENT_PATH);
+ if (userDefined != null && new File(userDefined).exists()) {
+ agentPath = userDefined;
+ } else {
+ agentPath = new File(agentPath).getParent();
+ }
+ if (!SystemInfo.isWindows && agentPath.contains(" ")) {
+ File dir = new File(PathManager.getSystemPath(), "coverageJars");
+ if (dir.getAbsolutePath().contains(" ")) {
+ try {
+ dir = FileUtil.createTempDirectory("coverage", "jars");
+ if (dir.getAbsolutePath().contains(" ")) {
+ LOG.info("Coverage agent not used since the agent path contains spaces: " + agentPath + "\n" +
+ "One can move the agent libraries to a directory with no spaces in path and specify its path in idea.properties as " + COVERAGE_AGENT_PATH + "=<path>");
+ return agentPath;
+ }
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ return agentPath;
+ }
+ }
+
+ try {
+ LOG.info("Coverage jars were copied to " + dir.getPath());
+ FileUtil.copyDir(new File(agentPath), dir);
+ return dir.getPath();
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ }
+ }
+ return agentPath;
+ }
+
+ protected static void write2file(File tempFile, String arg) throws IOException {
+ FileUtil.writeToFile(tempFile, (arg + "\n").getBytes("UTF-8"), true);
+ }
+
+ protected static File createTempFile() throws IOException {
+ File tempFile = FileUtil.createTempFile("coverage", "args");
+ if (!SystemInfo.isWindows && tempFile.getAbsolutePath().contains(" ")) {
+ tempFile = FileUtil.createTempFile(new File(PathManager.getSystemPath(), "coverage"), "coverage", "args", true);
+ if (tempFile.getAbsolutePath().contains(" ")) {
+ final String userDefined = System.getProperty(COVERAGE_AGENT_PATH);
+ if (userDefined != null && new File(userDefined).isDirectory()) {
+ tempFile = FileUtil.createTempFile(new File(userDefined), "coverage", "args", true);
+ }
+ }
+ }
+ return tempFile;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageSuite.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageSuite.java
new file mode 100644
index 000000000000..a35c9145909a
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageSuite.java
@@ -0,0 +1,244 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.ArrayUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public class JavaCoverageSuite extends BaseCoverageSuite {
+ private static final Logger LOG = Logger.getInstance(JavaCoverageSuite.class.getName());
+
+ private String[] myFilters;
+ private String mySuiteToMerge;
+
+ @NonNls
+ private static final String FILTER = "FILTER";
+ @NonNls
+ private static final String MERGE_SUITE = "MERGE_SUITE";
+ @NonNls
+ private static final String COVERAGE_RUNNER = "RUNNER";
+ private final CoverageEngine myCoverageEngine;
+
+ //read external only
+ public JavaCoverageSuite(@NotNull final JavaCoverageEngine coverageSupportProvider) {
+ super();
+ myCoverageEngine = coverageSupportProvider;
+ }
+
+ public JavaCoverageSuite(final String name,
+ final CoverageFileProvider coverageDataFileProvider,
+ final String[] filters,
+ final long lastCoverageTimeStamp,
+ final boolean coverageByTestEnabled,
+ final boolean tracingEnabled,
+ final boolean trackTestFolders,
+ final CoverageRunner coverageRunner,
+ @NotNull final JavaCoverageEngine coverageSupportProvider,
+ final Project project) {
+ super(name, coverageDataFileProvider, lastCoverageTimeStamp, coverageByTestEnabled,
+ tracingEnabled, trackTestFolders,
+ coverageRunner != null ? coverageRunner : CoverageRunner.getInstance(IDEACoverageRunner.class), project);
+
+ myFilters = filters;
+ myCoverageEngine = coverageSupportProvider;
+ }
+
+ @NotNull
+ public String[] getFilteredPackageNames() {
+ if (myFilters == null || myFilters.length == 0) return ArrayUtil.EMPTY_STRING_ARRAY;
+ List<String> result = new ArrayList<String>();
+ for (String filter : myFilters) {
+ if (filter.equals("*")) {
+ result.add(""); //default package
+ }
+ else if (filter.endsWith(".*")) result.add(filter.substring(0, filter.length() - 2));
+ }
+ return ArrayUtil.toStringArray(result);
+ }
+
+ @NotNull
+ public String[] getFilteredClassNames() {
+ if (myFilters == null) return ArrayUtil.EMPTY_STRING_ARRAY;
+ List<String> result = new ArrayList<String>();
+ for (String filter : myFilters) {
+ if (!filter.equals("*") && !filter.endsWith(".*")) result.add(filter);
+ }
+ return ArrayUtil.toStringArray(result);
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+
+ // filters
+ final List children = element.getChildren(FILTER);
+ List<String> filters = new ArrayList<String>();
+ //noinspection unchecked
+ for (Element child : ((Iterable<Element>)children)) {
+ filters.add(child.getValue());
+ }
+ myFilters = filters.isEmpty() ? null : ArrayUtil.toStringArray(filters);
+
+ // suite to merge
+ mySuiteToMerge = element.getAttributeValue(MERGE_SUITE);
+
+ if (getRunner() == null) {
+ setRunner(CoverageRunner.getInstance(IDEACoverageRunner.class)); //default
+ }
+ }
+
+ public void writeExternal(final Element element) throws WriteExternalException {
+ super.writeExternal(element);
+ if (mySuiteToMerge != null) {
+ element.setAttribute(MERGE_SUITE, mySuiteToMerge);
+ }
+ if (myFilters != null) {
+ for (String filter : myFilters) {
+ final Element filterElement = new Element(FILTER);
+ filterElement.setText(filter);
+ element.addContent(filterElement);
+ }
+ }
+ final CoverageRunner coverageRunner = getRunner();
+ element.setAttribute(COVERAGE_RUNNER, coverageRunner != null ? coverageRunner.getId() : "emma");
+ }
+
+ @Nullable
+ public ProjectData getCoverageData(final CoverageDataManager coverageDataManager) {
+ final ProjectData data = getCoverageData();
+ if (data != null) return data;
+ ProjectData map = loadProjectInfo();
+ if (mySuiteToMerge != null) {
+ JavaCoverageSuite toMerge = null;
+ final CoverageSuite[] suites = coverageDataManager.getSuites();
+ for (CoverageSuite suite : suites) {
+ if (Comparing.strEqual(suite.getPresentableName(), mySuiteToMerge)) {
+ if (!Comparing.strEqual(((JavaCoverageSuite)suite).getSuiteToMerge(), getPresentableName())) {
+ toMerge = (JavaCoverageSuite)suite;
+ }
+ break;
+ }
+ }
+ if (toMerge != null) {
+ final ProjectData projectInfo = toMerge.getCoverageData(coverageDataManager);
+ if (map != null) {
+ map.merge(projectInfo);
+ } else {
+ map = projectInfo;
+ }
+ }
+ }
+ setCoverageData(map);
+ return map;
+ }
+
+ @NotNull
+ public CoverageEngine getCoverageEngine() {
+ return myCoverageEngine;
+ }
+
+ @Nullable
+ public String getSuiteToMerge() {
+ return mySuiteToMerge;
+ }
+
+ public boolean isClassFiltered(final String classFQName) {
+ for (final String className : getFilteredClassNames()) {
+ if (className.equals(classFQName) || classFQName.startsWith(className) && classFQName.charAt(className.length()) == '$') {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isPackageFiltered(final String packageFQName) {
+ final String[] filteredPackageNames = getFilteredPackageNames();
+ for (final String packName : filteredPackageNames) {
+ if (packName.equals(packageFQName) || packageFQName.startsWith(packName) && packageFQName.charAt(packName.length()) == '.') {
+ return true;
+ }
+ }
+ return filteredPackageNames.length == 0 && getFilteredClassNames().length == 0;
+ }
+
+ public @NotNull List<PsiPackage> getCurrentSuitePackages(Project project) {
+ List<PsiPackage> packages = new ArrayList<PsiPackage>();
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final String[] filters = getFilteredPackageNames();
+ if (filters.length == 0) {
+ if (getFilteredClassNames().length > 0) return Collections.emptyList();
+
+ final PsiPackage defaultPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage("");
+ if (defaultPackage != null) {
+ packages.add(defaultPackage);
+ }
+ } else {
+ final List<String> nonInherited = new ArrayList<String>();
+ for (final String filter : filters) {
+ if (!isSubPackage(filters, filter)) {
+ nonInherited.add(filter);
+ }
+ }
+
+ for (String filter : nonInherited) {
+ final PsiPackage psiPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(filter);
+ if (psiPackage != null) {
+ packages.add(psiPackage);
+ }
+ }
+ }
+
+ return packages;
+ }
+
+ private static boolean isSubPackage(String[] filters, String filter) {
+ for (String supPackageFilter : filters) {
+ if (filter.startsWith(supPackageFilter + ".")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public @NotNull List<PsiClass> getCurrentSuiteClasses(final Project project) {
+ final List<PsiClass> classes = new ArrayList<PsiClass>();
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final String[] classNames = getFilteredClassNames();
+ if (classNames.length > 0) {
+ for (final String className : classNames) {
+ final PsiClass aClass =
+ ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Nullable
+ public PsiClass compute() {
+ return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className.replace("$", "."), GlobalSearchScope.allScope(project));
+ }
+ });
+ if (aClass != null) {
+ classes.add(aClass);
+ }
+ }
+ }
+
+ return classes;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java b/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java
new file mode 100644
index 000000000000..9f57a34d2ec9
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/PackageAnnotator.java
@@ -0,0 +1,454 @@
+package com.intellij.coverage;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author ven
+ */
+public class PackageAnnotator {
+
+ private final PsiPackage myPackage;
+ private final Project myProject;
+ private final PsiManager myManager;
+ private final CoverageDataManager myCoverageManager;
+
+ public PackageAnnotator(final PsiPackage aPackage) {
+ myPackage = aPackage;
+ myProject = myPackage.getProject();
+ myManager = PsiManager.getInstance(myProject);
+ myCoverageManager = CoverageDataManager.getInstance(myProject);
+ }
+
+ public interface Annotator {
+ void annotateSourceDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module);
+
+ void annotateTestDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module);
+
+ void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo);
+
+ void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo, boolean flatten);
+
+ void annotateClass(String classQualifiedName, ClassCoverageInfo classCoverageInfo);
+ }
+
+ public static class ClassCoverageInfo {
+ public int totalLineCount;
+ public int fullyCoveredLineCount;
+ public int partiallyCoveredLineCount;
+ public int totalMethodCount;
+ public int coveredMethodCount;
+
+ public int totalClassCount = 1;
+ public int coveredClassCount;
+ }
+
+ public static class PackageCoverageInfo {
+ public int totalClassCount;
+ public int coveredClassCount;
+ public int totalLineCount;
+ public int coveredLineCount;
+
+ public int coveredMethodCount;
+ public int totalMethodCount;
+ }
+
+ public static class DirCoverageInfo extends PackageCoverageInfo {
+ public VirtualFile sourceRoot;
+
+ public DirCoverageInfo(VirtualFile sourceRoot) {
+ this.sourceRoot = sourceRoot;
+ }
+ }
+
+ //get read lock myself when needed
+ public void annotate(final CoverageSuitesBundle suite, Annotator annotator) {
+ final ProjectData data = suite.getCoverageData();
+
+ if (data == null) return;
+
+ final String qualifiedName = myPackage.getQualifiedName();
+ boolean filtered = false;
+ for (CoverageSuite coverageSuite : suite.getSuites()) {
+ if (((JavaCoverageSuite)coverageSuite).isPackageFiltered(qualifiedName)) {
+ filtered = true;
+ break;
+ }
+
+ }
+ if (!filtered) return;
+
+ final GlobalSearchScope scope = suite.getSearchScope(myProject);
+ final Module[] modules = myCoverageManager.doInReadActionIfProjectOpen(new Computable<Module[]>() {
+ public Module[] compute() {
+ return ModuleManager.getInstance(myProject).getModules();
+ }
+ });
+
+ if (modules == null) return;
+
+ Map<String, PackageCoverageInfo> packageCoverageMap = new HashMap<String, PackageCoverageInfo>();
+ Map<String, PackageCoverageInfo> flattenPackageCoverageMap = new HashMap<String, PackageCoverageInfo>();
+ for (final Module module : modules) {
+ if (!scope.isSearchInModuleContent(module)) continue;
+ final String rootPackageVMName = qualifiedName.replaceAll("\\.", "/");
+ final VirtualFile output = myCoverageManager.doInReadActionIfProjectOpen(new Computable<VirtualFile>() {
+ @Nullable
+ public VirtualFile compute() {
+ return CompilerModuleExtension.getInstance(module).getCompilerOutputPath();
+ }
+ });
+
+
+ if (output != null) {
+ File outputRoot = findRelativeFile(rootPackageVMName, output);
+ if (outputRoot.exists()) {
+ collectCoverageInformation(outputRoot, packageCoverageMap, flattenPackageCoverageMap, data, rootPackageVMName, annotator, module,
+ suite.isTrackTestFolders(), false);
+ }
+
+ }
+
+ if (suite.isTrackTestFolders()) {
+ final VirtualFile testPackageRoot = myCoverageManager.doInReadActionIfProjectOpen(new Computable<VirtualFile>() {
+ @Nullable
+ public VirtualFile compute() {
+ return CompilerModuleExtension.getInstance(module).getCompilerOutputPathForTests();
+ }
+ });
+
+ if (testPackageRoot != null) {
+ final File outputRoot = findRelativeFile(rootPackageVMName, testPackageRoot);
+ if (outputRoot.exists()) {
+ collectCoverageInformation(outputRoot, packageCoverageMap, flattenPackageCoverageMap, data, rootPackageVMName, annotator, module,
+ suite.isTrackTestFolders(), true);
+ }
+ }
+ }
+ }
+
+ for (Map.Entry<String, PackageCoverageInfo> entry : packageCoverageMap.entrySet()) {
+ final String packageFQName = entry.getKey().replaceAll("/", ".");
+ final PackageCoverageInfo info = entry.getValue();
+ annotator.annotatePackage(packageFQName, info);
+ }
+
+ for (Map.Entry<String, PackageCoverageInfo> entry : flattenPackageCoverageMap.entrySet()) {
+ final String packageFQName = entry.getKey().replaceAll("/", ".");
+ final PackageCoverageInfo info = entry.getValue();
+ annotator.annotatePackage(packageFQName, info, true);
+ }
+ }
+
+ private static File findRelativeFile(String rootPackageVMName, VirtualFile output) {
+ File outputRoot = VfsUtilCore.virtualToIoFile(output);
+ outputRoot = rootPackageVMName.length() > 0 ? new File(outputRoot, FileUtil.toSystemDependentName(rootPackageVMName)) : outputRoot;
+ return outputRoot;
+ }
+
+ public void annotateFilteredClass(PsiClass psiClass, CoverageSuitesBundle bundle, Annotator annotator) {
+ final ProjectData data = bundle.getCoverageData();
+ if (data == null) return;
+ final Module module = ModuleUtil.findModuleForPsiElement(psiClass);
+ if (module != null) {
+ final boolean isInTests = ProjectRootManager.getInstance(module.getProject()).getFileIndex()
+ .isInTestSourceContent(psiClass.getContainingFile().getVirtualFile());
+ final CompilerModuleExtension moduleExtension = CompilerModuleExtension.getInstance(module);
+ final VirtualFile outputPath = isInTests ? moduleExtension.getCompilerOutputPathForTests() : moduleExtension.getCompilerOutputPath();
+
+ if (outputPath != null) {
+ final String qualifiedName = psiClass.getQualifiedName();
+ if (qualifiedName == null) return;
+ final String packageVMName = StringUtil.getPackageName(qualifiedName).replace('.', '/');
+ final File packageRoot = findRelativeFile(packageVMName, outputPath);
+ if (packageRoot != null && packageRoot.exists()) {
+ Map<String, ClassCoverageInfo> toplevelClassCoverage = new HashMap<String, ClassCoverageInfo>();
+ final File[] files = packageRoot.listFiles();
+ if (files != null) {
+ for (File child : files) {
+ if (isClassFile(child)) {
+ final String childName = getClassName(child);
+ final String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName;
+ final String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName);
+ if (toplevelClassSrcFQName.equals(qualifiedName)) {
+ collectClassCoverageInformation(child, new PackageCoverageInfo(), data, toplevelClassCoverage, classFqVMName.replace("/", "."), toplevelClassSrcFQName);
+ }
+ }
+ }
+ }
+ for (ClassCoverageInfo coverageInfo : toplevelClassCoverage.values()) {
+ annotator.annotateClass(qualifiedName, coverageInfo);
+ }
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private DirCoverageInfo[] collectCoverageInformation(final File packageOutputRoot,
+ final Map<String, PackageCoverageInfo> packageCoverageMap,
+ Map<String, PackageCoverageInfo> flattenPackageCoverageMap,
+ final ProjectData projectInfo,
+ final String packageVMName,
+ final Annotator annotator,
+ final Module module,
+ final boolean trackTestFolders,
+ final boolean isTestHierarchy) {
+ final List<DirCoverageInfo> dirs = new ArrayList<DirCoverageInfo>();
+ final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries();
+ for (ContentEntry contentEntry : contentEntries) {
+ for (SourceFolder folder : contentEntry.getSourceFolders(isTestHierarchy ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE)) {
+ final VirtualFile file = folder.getFile();
+ if (file == null) continue;
+ final String prefix = folder.getPackagePrefix().replaceAll("\\.", "/");
+ final VirtualFile relativeSrcRoot = file.findFileByRelativePath(StringUtil.trimStart(packageVMName, prefix));
+ dirs.add(new DirCoverageInfo(relativeSrcRoot));
+ }
+ }
+
+ final File[] children = packageOutputRoot.listFiles();
+
+ if (children == null) return null;
+
+ Map<String, ClassCoverageInfo> toplevelClassCoverage = new HashMap<String, ClassCoverageInfo>();
+ for (File child : children) {
+ if (child.isDirectory()) {
+ final String childName = child.getName();
+ final String childPackageVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName;
+ final DirCoverageInfo[] childCoverageInfo =
+ collectCoverageInformation(child, packageCoverageMap, flattenPackageCoverageMap, projectInfo, childPackageVMName, annotator, module,
+ trackTestFolders, isTestHierarchy);
+ if (childCoverageInfo != null) {
+ for (int i = 0; i < childCoverageInfo.length; i++) {
+ DirCoverageInfo coverageInfo = childCoverageInfo[i];
+ final DirCoverageInfo parentDir = dirs.get(i);
+ parentDir.totalClassCount += coverageInfo.totalClassCount;
+ parentDir.coveredClassCount += coverageInfo.coveredClassCount;
+ parentDir.totalLineCount += coverageInfo.totalLineCount;
+ parentDir.coveredLineCount += coverageInfo.coveredLineCount;
+ parentDir.totalMethodCount += coverageInfo.totalMethodCount;
+ parentDir.coveredMethodCount += coverageInfo.coveredMethodCount;
+ }
+ }
+ }
+ else {
+ if (isClassFile(child)) {
+ final String childName = getClassName(child);
+ final String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName;
+ final String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName);
+ final VirtualFile[] containingFile = new VirtualFile[1];
+ final Boolean isInSource = myCoverageManager.doInReadActionIfProjectOpen(new Computable<Boolean>() {
+ public Boolean compute() {
+ final PsiClass aClass =
+ JavaPsiFacade.getInstance(myManager.getProject()).findClass(toplevelClassSrcFQName, GlobalSearchScope.moduleScope(module));
+ if (aClass == null || !aClass.isValid()) return Boolean.FALSE;
+ containingFile[0] = aClass.getContainingFile().getVirtualFile();
+ assert containingFile[0] != null : aClass;
+ final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex();
+ return fileIndex.isUnderSourceRootOfType(containingFile[0], JavaModuleSourceRootTypes.SOURCES)
+ && (trackTestFolders || !fileIndex.isInTestSourceContent(containingFile[0]));
+ }
+ });
+ if (isInSource != null && isInSource.booleanValue()) {
+ for (DirCoverageInfo dirCoverageInfo : dirs) {
+ if (dirCoverageInfo.sourceRoot != null && VfsUtil.isAncestor(dirCoverageInfo.sourceRoot, containingFile[0], false)) {
+ collectClassCoverageInformation(child, dirCoverageInfo, projectInfo, toplevelClassCoverage, classFqVMName.replace("/", "."), toplevelClassSrcFQName);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (Map.Entry<String, ClassCoverageInfo> entry : toplevelClassCoverage.entrySet()) {
+ final String toplevelClassName = entry.getKey();
+ final ClassCoverageInfo coverageInfo = entry.getValue();
+ annotator.annotateClass(toplevelClassName, coverageInfo);
+ }
+
+ PackageCoverageInfo flattenPackageCoverageInfo = getOrCreateCoverageInfo(flattenPackageCoverageMap, packageVMName);
+ for (Map.Entry<String, ClassCoverageInfo> entry : toplevelClassCoverage.entrySet()) {
+ final ClassCoverageInfo coverageInfo = entry.getValue();
+ flattenPackageCoverageInfo.coveredClassCount += coverageInfo.coveredClassCount;
+ flattenPackageCoverageInfo.totalClassCount += coverageInfo.totalClassCount;
+
+ flattenPackageCoverageInfo.coveredLineCount += coverageInfo.fullyCoveredLineCount + coverageInfo.partiallyCoveredLineCount;
+ flattenPackageCoverageInfo.totalLineCount += coverageInfo.totalLineCount;
+
+ flattenPackageCoverageInfo.coveredMethodCount += coverageInfo.coveredMethodCount;
+ flattenPackageCoverageInfo.totalMethodCount += coverageInfo.totalMethodCount;
+ }
+
+ PackageCoverageInfo packageCoverageInfo = getOrCreateCoverageInfo(packageCoverageMap, packageVMName);
+ for (DirCoverageInfo dir : dirs) {
+ packageCoverageInfo.totalClassCount += dir.totalClassCount;
+ packageCoverageInfo.totalLineCount += dir.totalLineCount;
+ packageCoverageInfo.coveredClassCount += dir.coveredClassCount;
+ packageCoverageInfo.coveredLineCount += dir.coveredLineCount;
+ packageCoverageInfo.coveredMethodCount += dir.coveredMethodCount;
+ packageCoverageInfo.totalMethodCount += dir.totalMethodCount;
+
+ if (isTestHierarchy) {
+ annotator.annotateTestDirectory(dir.sourceRoot, dir, module);
+ }
+ else {
+ annotator.annotateSourceDirectory(dir.sourceRoot, dir, module);
+ }
+ }
+
+ return dirs.toArray(new DirCoverageInfo[dirs.size()]);
+ }
+
+ private static boolean isClassFile(File classFile) {
+ return classFile.getName().endsWith(".class");
+ }
+
+ private static String getClassName(File classFile) {
+ return StringUtil.trimEnd(classFile.getName(), ".class");
+ }
+
+ private static PackageCoverageInfo getOrCreateCoverageInfo(final Map<String, PackageCoverageInfo> packageCoverageMap,
+ final String packageVMName) {
+ PackageCoverageInfo coverageInfo = packageCoverageMap.get(packageVMName);
+ if (coverageInfo == null) {
+ coverageInfo = new PackageCoverageInfo();
+ packageCoverageMap.put(packageVMName, coverageInfo);
+ }
+ return coverageInfo;
+ }
+
+ private void collectClassCoverageInformation(final File classFile, final PackageCoverageInfo packageCoverageInfo, final ProjectData projectInfo,
+ final Map<String, ClassCoverageInfo> toplevelClassCoverage,
+ final String className,
+ final String toplevelClassSrcFQName) {
+ final ClassCoverageInfo toplevelClassCoverageInfo = new ClassCoverageInfo();
+
+ final ClassData classData = projectInfo.getClassData(className);
+
+ if (classData != null && classData.getLines() != null) {
+ final Object[] lines = classData.getLines();
+ for (Object l : lines) {
+ if (l instanceof LineData) {
+ final LineData lineData = (LineData)l;
+ if (lineData.getStatus() == LineCoverage.FULL) {
+ toplevelClassCoverageInfo.fullyCoveredLineCount++;
+ }
+ else if (lineData.getStatus() == LineCoverage.PARTIAL) {
+ toplevelClassCoverageInfo.partiallyCoveredLineCount++;
+ }
+ toplevelClassCoverageInfo.totalLineCount++;
+ packageCoverageInfo.totalLineCount++;
+ }
+ }
+ boolean touchedClass = false;
+ final Collection methodSigs = classData.getMethodSigs();
+ for (final Object nameAndSig : methodSigs) {
+ final int covered = classData.getStatus((String)nameAndSig);
+ if (covered != LineCoverage.NONE) {
+ toplevelClassCoverageInfo.coveredMethodCount++;
+ touchedClass = true;
+ }
+ }
+ if (!methodSigs.isEmpty()) {
+ if (touchedClass) {
+ packageCoverageInfo.coveredClassCount++;
+ }
+ toplevelClassCoverageInfo.totalMethodCount += methodSigs.size();
+ packageCoverageInfo.totalClassCount++;
+
+ packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount;
+ packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount;
+ packageCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount;
+ packageCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount;
+ } else {
+ return;
+ }
+ } else {
+ if (!collectNonCoveredClassInfo(classFile, toplevelClassCoverageInfo, packageCoverageInfo)) return;
+ }
+
+ ClassCoverageInfo classCoverageInfo = getOrCreateClassCoverageInfo(toplevelClassCoverage, toplevelClassSrcFQName);
+ classCoverageInfo.totalLineCount += toplevelClassCoverageInfo.totalLineCount;
+ classCoverageInfo.fullyCoveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount;
+ classCoverageInfo.partiallyCoveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount;
+
+ classCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount;
+ classCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount;
+ if (toplevelClassCoverageInfo.coveredMethodCount > 0) {
+ classCoverageInfo.coveredClassCount++;
+ }
+ }
+
+ private static ClassCoverageInfo getOrCreateClassCoverageInfo(final Map<String, ClassCoverageInfo> toplevelClassCoverage,
+ final String sourceToplevelFQName) {
+ ClassCoverageInfo toplevelClassCoverageInfo = toplevelClassCoverage.get(sourceToplevelFQName);
+ if (toplevelClassCoverageInfo == null) {
+ toplevelClassCoverageInfo = new ClassCoverageInfo();
+ toplevelClassCoverage.put(sourceToplevelFQName, toplevelClassCoverageInfo);
+ } else {
+ toplevelClassCoverageInfo.totalClassCount++;
+ }
+ return toplevelClassCoverageInfo;
+ }
+
+ private static String getSourceToplevelFQName(String classFQVMName) {
+ final int index = classFQVMName.indexOf('$');
+ if (index > 0) classFQVMName = classFQVMName.substring(0, index);
+ if (classFQVMName.startsWith("/")) classFQVMName = classFQVMName.substring(1);
+ return classFQVMName.replaceAll("/", ".");
+ }
+
+
+
+ /*
+ return true if there is executable code in the class
+ */
+ private boolean collectNonCoveredClassInfo(final File classFile,
+ final ClassCoverageInfo classCoverageInfo,
+ final PackageCoverageInfo packageCoverageInfo) {
+ final byte[] content = myCoverageManager.doInReadActionIfProjectOpen(new Computable<byte[]>() {
+ public byte[] compute() {
+ try {
+ return FileUtil.loadFileBytes(classFile);
+ }
+ catch (IOException e) {
+ return null;
+ }
+ }
+ });
+ final CoverageSuitesBundle coverageSuite = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle();
+ if (coverageSuite == null) return false;
+ return SourceLineCounterUtil
+ .collectNonCoveredClassInfo(classCoverageInfo, packageCoverageInfo, content, coverageSuite.isTracingEnabled());
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java b/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java
new file mode 100644
index 000000000000..f4b572188ea3
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/SourceLineCounterUtil.java
@@ -0,0 +1,48 @@
+package com.intellij.coverage;
+
+import com.intellij.rt.coverage.instrumentation.SourceLineCounter;
+import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TIntProcedure;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 12/30/11
+ */
+public class SourceLineCounterUtil {
+ public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
+ final PackageAnnotator.PackageCoverageInfo packageCoverageInfo,
+ byte[] content,
+ final boolean excludeLines) {
+ if (content == null) return false;
+ ClassReader reader = new ClassReader(content, 0, content.length);
+
+ SourceLineCounter counter = new SourceLineCounter(null, excludeLines, null);
+ reader.accept(counter, 0);
+ classCoverageInfo.totalLineCount += counter.getNSourceLines();
+ classCoverageInfo.totalMethodCount += counter.getNMethodsWithCode();
+ packageCoverageInfo.totalLineCount += counter.getNSourceLines();
+ packageCoverageInfo.totalMethodCount += counter.getNMethodsWithCode();
+ if (!counter.isInterface()) {
+ packageCoverageInfo.totalClassCount++;
+ }
+ return false;
+ }
+
+ public static void collectSrcLinesForUntouchedFiles(final List<Integer> uncoveredLines,
+ byte[] content, final boolean excludeLines) {
+ final ClassReader reader = new ClassReader(content);
+ final SourceLineCounter collector = new SourceLineCounter(null, excludeLines, null);
+ reader.accept(collector, 0);
+ final TIntObjectHashMap lines = collector.getSourceLines();
+ lines.forEachKey(new TIntProcedure() {
+ public boolean execute(int line) {
+ line--;
+ uncoveredLines.add(line);
+ return true;
+ }
+ });
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/coverage/info/CoberturaLoaderUtil.java b/plugins/coverage/src/com/intellij/coverage/info/CoberturaLoaderUtil.java
new file mode 100644
index 000000000000..87935175a4b8
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/info/CoberturaLoaderUtil.java
@@ -0,0 +1,130 @@
+/*
+ * User: anna
+ * Date: 16-Nov-2007
+ */
+package com.intellij.coverage.info;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.rt.coverage.data.ClassData;
+import com.intellij.rt.coverage.data.LineCoverage;
+import com.intellij.rt.coverage.data.LineData;
+import com.intellij.rt.coverage.data.ProjectData;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class CoberturaLoaderUtil {
+ private static final Logger LOG = Logger.getInstance("#" + CoberturaLoaderUtil.class.getName());
+
+ private CoberturaLoaderUtil() {
+ }
+
+ public static ProjectData load(final File sessionDataFile) {
+ ProjectData projectInfo = new ProjectData();
+ DataInputStream dataFile = null;
+ try {
+ dataFile = new DataInputStream(new FileInputStream(sessionDataFile));
+ int classesCount = dataFile.read();
+ for (int i = 0; i < classesCount; i++) {
+ final String classFQName = dataFile.readUTF();
+ dataFile.readUTF(); //sourcefilename
+ final ClassData classData = projectInfo.getOrCreateClassData(classFQName);
+ final int numberOfLines = dataFile.read();
+ for (int l = 0; l < numberOfLines; l++) {
+ final int lineNumber = dataFile.read();
+ final LineData lineData = null; //todo classData.getOrCreateLine(lineNumber, dataFile.readUTF() + dataFile.readUTF());
+ long hits = dataFile.readLong();
+ final int jumpsNumber = dataFile.read();
+ int trueHits = 0;
+ int falseHits = 0;
+ int totalHits = 0;
+ for (int j = 0; j < jumpsNumber; j++) {
+ dataFile.read(); //jump number
+ totalHits++;
+ if (dataFile.readLong() > 0) trueHits++;
+ totalHits++;
+ if (dataFile.readLong() > 0) falseHits++;
+ }
+ int defaultHitsNumber = 0;
+ int branchHitNumber = 0;
+ final int switchNumber = dataFile.read();
+ for (int s = 0; s < switchNumber; s++) {
+ dataFile.read(); //switch number
+ dataFile.read(); //number of keys
+ long defaultHits = dataFile.readLong();
+ if (defaultHits > 0) defaultHitsNumber++;
+ int coveredSwitchBranches = 0;
+ final int switchBranchesNumber = dataFile.read();
+ for (int b = 0; b < switchBranchesNumber; b++) {
+ final long branchHit = dataFile.readLong();
+ if (branchHit > 0) coveredSwitchBranches ++;
+ }
+ if (coveredSwitchBranches == switchBranchesNumber) branchHitNumber++;
+ }
+ if (hits > 0) {
+ if (totalHits == trueHits + falseHits) {
+ if (defaultHitsNumber == switchNumber && branchHitNumber == switchNumber) {
+ lineData.setStatus(LineCoverage.FULL);
+ continue;
+ }
+ }
+ lineData.setStatus(LineCoverage.PARTIAL);
+ } else {
+ lineData.setStatus(LineCoverage.NONE);
+ }
+ }
+ }
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ }
+ finally {
+ if (dataFile != null) {
+ try {
+ dataFile.close();
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ return projectInfo;
+ }
+
+ /*public static List<TraceInfo> loadTestLines(final File testSessionFile, ProjectInfo projectInfo) {
+ final List<TraceInfo> result = new ArrayList<TraceInfo>();
+ DataInputStream dataFile = null;
+ try {
+ dataFile = new DataInputStream(new FileInputStream(testSessionFile));
+ final int count = dataFile.read();
+ for (int t = 0; t < count; t ++) {
+ final String className = dataFile.readUTF();
+ final int lineNumber = dataFile.read();
+ final ClassInfo classInfo = projectInfo.getClassInfo(className);
+ if (classInfo != null) {
+ final LineInfo lineInfo = classInfo.getLineInfo(lineNumber);
+ if (lineInfo != null) {
+ result.add(new TraceInfo(classInfo, lineInfo));
+ }
+ }
+ }
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ }
+ finally {
+ if (dataFile != null) {
+ try {
+ dataFile.close();
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+
+ return result;
+ }*/
+} \ No newline at end of file
diff --git a/plugins/coverage/src/com/intellij/coverage/info/EmmaLoaderUtil.java b/plugins/coverage/src/com/intellij/coverage/info/EmmaLoaderUtil.java
new file mode 100644
index 000000000000..33274d545350
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/info/EmmaLoaderUtil.java
@@ -0,0 +1,13 @@
+/*
+ * User: anna
+ * Date: 13-Feb-2008
+ */
+package com.intellij.coverage.info;
+
+public class EmmaLoaderUtil {
+ private EmmaLoaderUtil() {
+ }
+
+
+
+} \ No newline at end of file
diff --git a/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java
new file mode 100644
index 000000000000..5a7034e1b08e
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/coverage/view/JavaCoverageViewExtension.java
@@ -0,0 +1,319 @@
+package com.intellij.coverage.view;
+
+import com.intellij.coverage.*;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.NullableComputable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ui.ColumnInfo;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * User: anna
+ * Date: 1/5/12
+ */
+public class JavaCoverageViewExtension extends CoverageViewExtension {
+ private final JavaCoverageAnnotator myAnnotator;
+
+ public JavaCoverageViewExtension(JavaCoverageAnnotator annotator,
+ Project project,
+ CoverageSuitesBundle suitesBundle,
+ CoverageViewManager.StateBean stateBean) {
+ super(project, suitesBundle, stateBean);
+ myAnnotator = annotator;
+ }
+
+ @Override
+ public String getSummaryForNode(AbstractTreeNode node) {
+ final String coverageInformationString = myAnnotator
+ .getPackageCoverageInformationString((PsiPackage)node.getValue(), null, myCoverageDataManager, myStateBean.myFlattenPackages);
+ return "Coverage Summary for Package \'" + node.toString() + "\': " + getNotCoveredMessage(coverageInformationString);
+ }
+
+ @Override
+ public String getSummaryForRootNode(AbstractTreeNode childNode) {
+ final Object value = childNode.getValue();
+ String coverageInformationString = myAnnotator.getPackageCoverageInformationString((PsiPackage)value, null,
+ myCoverageDataManager);
+ if (coverageInformationString == null) {
+ if (!myCoverageViewManager.isReady()) return "Loading...";
+ PackageAnnotator.PackageCoverageInfo info = new PackageAnnotator.PackageCoverageInfo();
+ final Collection children = childNode.getChildren();
+ for (Object child : children) {
+ final Object childValue = ((CoverageListNode)child).getValue();
+ if (childValue instanceof PsiPackage) {
+ final PackageAnnotator.PackageCoverageInfo coverageInfo = myAnnotator.getPackageCoverageInfo((PsiPackage)childValue, myStateBean.myFlattenPackages);
+ if (coverageInfo != null) {
+ info = JavaCoverageAnnotator.merge(info, coverageInfo);
+ }
+ } else {
+ final PackageAnnotator.ClassCoverageInfo classCoverageInfo = getClassCoverageInfo(((PsiClass)childValue));
+ if (classCoverageInfo != null) {
+ info.coveredClassCount += classCoverageInfo.coveredMethodCount > 0 ? 1 : 0;
+ info.totalClassCount ++;
+
+ info.coveredMethodCount += classCoverageInfo.coveredMethodCount;
+ info.totalMethodCount += classCoverageInfo.totalMethodCount;
+
+ info.coveredLineCount += classCoverageInfo.partiallyCoveredLineCount + classCoverageInfo.fullyCoveredLineCount;
+ info.totalLineCount += classCoverageInfo.totalLineCount;
+ }
+ }
+ }
+ coverageInformationString = JavaCoverageAnnotator.getCoverageInformationString(info, false);
+ }
+ return "Coverage Summary for \'all classes in scope\': " + getNotCoveredMessage(coverageInformationString);
+ }
+
+ private static String getNotCoveredMessage(String coverageInformationString) {
+ if (coverageInformationString == null) {
+ coverageInformationString = "not covered";
+ }
+ return coverageInformationString;
+ }
+
+ @Override
+ public String getPercentage(int columnIndex, AbstractTreeNode node) {
+ final Object value = node.getValue();
+ if (value instanceof PsiClass) {
+
+ //no coverage gathered
+ if (((PsiClass)value).isInterface()) return null;
+
+ final String qualifiedName = ((PsiClass)value).getQualifiedName();
+ if (columnIndex == 1) {
+ return myAnnotator.getClassCoveredPercentage(qualifiedName);
+ } else if (columnIndex == 2){
+ return myAnnotator.getClassMethodPercentage(qualifiedName);
+ }
+
+ return myAnnotator.getClassLinePercentage(qualifiedName);
+ }
+ if (value instanceof PsiPackage) {
+ final boolean flatten = myStateBean.myFlattenPackages;
+ if (columnIndex == 1) {
+ return myAnnotator.getPackageClassPercentage((PsiPackage)value, flatten);
+ } else if (columnIndex == 2) {
+ return myAnnotator.getPackageMethodPercentage((PsiPackage)value, flatten);
+ }
+ return myAnnotator.getPackageLinePercentage((PsiPackage)value, flatten);
+ }
+ return null;
+ }
+
+ @Override
+ public PsiElement getElementToSelect(Object object) {
+ PsiElement psiElement = super.getElementToSelect(object);
+ if (psiElement != null) {
+ final PsiFile containingFile = psiElement.getContainingFile();
+ if (containingFile instanceof PsiClassOwner) {
+ final PsiClass[] classes = ((PsiClassOwner)containingFile).getClasses();
+ if (classes.length == 1) return classes[0];
+ for (PsiClass aClass : classes) {
+ if (PsiTreeUtil.isAncestor(aClass, psiElement, false)) return aClass;
+ }
+ }
+ }
+ return psiElement;
+ }
+
+ @Override
+ public VirtualFile getVirtualFile(Object object) {
+ if (object instanceof PsiPackage) {
+ final PsiDirectory[] directories = ((PsiPackage)object).getDirectories();
+ return directories.length > 0 ? directories[0].getVirtualFile() : null;
+ }
+ return super.getVirtualFile(object);
+ }
+
+ @Nullable
+ @Override
+ public PsiElement getParentElement(PsiElement element) {
+ if (element instanceof PsiClass) {
+ final PsiDirectory containingDirectory = element.getContainingFile().getContainingDirectory();
+ return containingDirectory != null ? JavaDirectoryService.getInstance().getPackage(containingDirectory) : null;
+ }
+ return ((PsiPackage)element).getParentPackage();
+ }
+
+ @Override
+ public AbstractTreeNode createRootNode() {
+ return new CoverageListRootNode(myProject, JavaPsiFacade.getInstance(myProject).findPackage(""), mySuitesBundle, myStateBean);
+ }
+
+ @Override
+ public List<AbstractTreeNode> createTopLevelNodes() {
+ final List<AbstractTreeNode> topLevelNodes = new ArrayList<AbstractTreeNode>();
+ final LinkedHashSet<PsiPackage> packages = new LinkedHashSet<PsiPackage>();
+ final LinkedHashSet<PsiClass> classes = new LinkedHashSet<PsiClass>();
+ for (CoverageSuite suite : mySuitesBundle.getSuites()) {
+ packages.addAll(((JavaCoverageSuite)suite).getCurrentSuitePackages(myProject));
+ classes.addAll(((JavaCoverageSuite)suite).getCurrentSuiteClasses(myProject));
+ }
+
+ final Set<PsiPackage> packs = new HashSet<PsiPackage>();
+ for (PsiPackage aPackage : packages) {
+ final String qualifiedName = aPackage.getQualifiedName();
+ for (PsiPackage psiPackage : packages) {
+ if (psiPackage.getQualifiedName().startsWith(qualifiedName + ".")) {
+ packs.add(psiPackage);
+ break;
+ }
+ }
+ }
+ packages.removeAll(packs);
+
+ for (PsiPackage aPackage : packages) {
+ final GlobalSearchScope searchScope = mySuitesBundle.getSearchScope(myProject);
+ if (aPackage.getDirectories(searchScope).length == 0) continue;
+ if (aPackage.getClasses(searchScope).length != 0) {
+ final CoverageListNode node = new CoverageListNode(myProject, aPackage, mySuitesBundle, myStateBean);
+ topLevelNodes.add(node);
+ }
+ collectSubPackages(topLevelNodes, aPackage, mySuitesBundle, myStateBean);
+ }
+
+ for (PsiClass aClass : classes) {
+ if (getClassCoverageInfo(aClass) == null) continue;
+ topLevelNodes.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean));
+ }
+ return topLevelNodes;
+ }
+
+ private static void collectSubPackages(List<AbstractTreeNode> children,
+ final PsiPackage rootPackage,
+ final CoverageSuitesBundle data,
+ final CoverageViewManager.StateBean stateBean) {
+ final GlobalSearchScope searchScope = data.getSearchScope(rootPackage.getProject());
+ final PsiPackage[] subPackages = ApplicationManager.getApplication().runReadAction(new Computable<PsiPackage[]>() {
+ public PsiPackage[] compute() {
+ return rootPackage.getSubPackages(searchScope);
+ }
+ });
+ for (final PsiPackage aPackage : subPackages) {
+ final PsiDirectory[] directories = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory[]>() {
+ public PsiDirectory[] compute() {
+ return aPackage.getDirectories(searchScope);
+ }
+ });
+ if (directories.length == 0 && !ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return JavaPsiFacade.getInstance(aPackage.getProject()).isPartOfPackagePrefix(aPackage.getQualifiedName());
+ }
+ })) continue;
+ if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return isInCoverageScope(aPackage, data);
+ }
+ })) {
+ final CoverageListNode node = new CoverageListNode(rootPackage.getProject(), aPackage, data, stateBean);
+ children.add(node);
+ }
+ else if (!stateBean.myFlattenPackages) {
+ collectSubPackages(children, aPackage, data, stateBean);
+ }
+ if (stateBean.myFlattenPackages) {
+ collectSubPackages(children, aPackage, data, stateBean);
+ }
+ }
+ }
+
+
+ @Override
+ public List<AbstractTreeNode> getChildrenNodes(final AbstractTreeNode node) {
+ List<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>();
+ if (node instanceof CoverageListNode) {
+ final Object val = node.getValue();
+ if (val instanceof PsiClass) return Collections.emptyList();
+
+ //append package classes
+ if (val instanceof PsiPackage) {
+ if (!myStateBean.myFlattenPackages) {
+ collectSubPackages(children, (PsiPackage)val, mySuitesBundle, myStateBean);
+ }
+ if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return isInCoverageScope((PsiPackage)val, mySuitesBundle);
+ }
+ })) {
+ final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+ public PsiClass[] compute() {
+ return ((PsiPackage)val).getClasses(mySuitesBundle.getSearchScope(node.getProject()));
+ }
+ });
+ for (PsiClass aClass : classes) {
+ if (!(node instanceof CoverageListRootNode) && getClassCoverageInfo(aClass) == null) continue;
+ children.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean));
+ }
+ }
+ }
+ if (node instanceof CoverageListRootNode) {
+ for (CoverageSuite suite : mySuitesBundle.getSuites()) {
+ final List<PsiClass> classes = ((JavaCoverageSuite)suite).getCurrentSuiteClasses(myProject);
+ for (PsiClass aClass : classes) {
+ children.add(new CoverageListNode(myProject, aClass, mySuitesBundle, myStateBean));
+ }
+ }
+ }
+ for (AbstractTreeNode childNode : children) {
+ childNode.setParent(node);
+ }
+ }
+ return children;
+ }
+
+ @Nullable
+ private PackageAnnotator.ClassCoverageInfo getClassCoverageInfo(final PsiClass aClass) {
+ return myAnnotator.getClassCoverageInfo(ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
+ public String compute() {
+ return aClass.getQualifiedName();
+ }
+ }));
+ }
+
+ @Override
+ public ColumnInfo[] createColumnInfos() {
+ return new ColumnInfo[]{
+ new ElementColumnInfo(),
+ new PercentageCoverageColumnInfo(1, "Class, %", mySuitesBundle, myStateBean),
+ new PercentageCoverageColumnInfo(2, "Method, %", mySuitesBundle, myStateBean),
+ new PercentageCoverageColumnInfo(3, "Line, %", mySuitesBundle, myStateBean)
+ };
+ }
+
+ private static boolean isInCoverageScope(PsiElement element, CoverageSuitesBundle suitesBundle) {
+ if (element instanceof PsiPackage) {
+ final PsiPackage psiPackage = (PsiPackage)element;
+ final String qualifiedName = psiPackage.getQualifiedName();
+ for (CoverageSuite suite : suitesBundle.getSuites()) {
+ if (((JavaCoverageSuite)suite).isPackageFiltered(qualifiedName)) return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canSelectInCoverageView(Object object) {
+ final PsiFile psiFile = object instanceof VirtualFile ? PsiManager.getInstance(myProject).findFile((VirtualFile)object) : null;
+ if (psiFile instanceof PsiClassOwner) {
+ final String packageName = ((PsiClassOwner)psiFile).getPackageName();
+ return isInCoverageScope(JavaPsiFacade.getInstance(myProject).findPackage(packageName), mySuitesBundle);
+ }
+ if (object instanceof PsiPackage) {
+ return isInCoverageScope((PsiElement)object, mySuitesBundle);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean supportFlattenPackages() {
+ return true;
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/execution/configurations/coverage/CoverageConfigurable.java b/plugins/coverage/src/com/intellij/execution/configurations/coverage/CoverageConfigurable.java
new file mode 100644
index 000000000000..3bf32a19aec2
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/execution/configurations/coverage/CoverageConfigurable.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.execution.configurations.coverage;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.coverage.CoverageRunner;
+import com.intellij.coverage.JavaCoverageEngine;
+import com.intellij.execution.CommonJavaRunConfigurationParameters;
+import com.intellij.execution.ExecutionBundle;
+import com.intellij.execution.configurations.ModuleBasedConfiguration;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.util.JreVersionDetector;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.PackageChooserDialog;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SettingsEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.PackageChooser;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.ui.classFilter.ClassFilterEditor;
+import com.intellij.util.IconUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+/**
+ * Base {@link com.intellij.openapi.options.Configurable} for configuring code coverage
+ * To obtain a full configurable use
+ * <code>
+ * SettingsEditorGroup<YourConfiguration> group = new SettingsEditorGroup<YourConfiguration>();
+ * group.addEditor(title, yourConfigurable);
+ * group.addEditor(title, yourCoverageConfigurable);
+ * </code>
+ * @author ven
+ */
+public class CoverageConfigurable extends SettingsEditor<RunConfigurationBase> {
+ private static final Logger LOG = Logger.getInstance("#" + CoverageConfigurable.class.getName());
+
+ private final JreVersionDetector myVersionDetector = new JreVersionDetector();
+ Project myProject;
+ private MyClassFilterEditor myClassFilterEditor;
+ private JLabel myCoverageNotSupportedLabel;
+ private JComboBox myCoverageRunnerCb;
+ private JPanel myRunnerPanel;
+ private JCheckBox myTrackPerTestCoverageCb;
+ private JCheckBox myTrackTestSourcesCb;
+
+ private JRadioButton myTracingRb;
+ private JRadioButton mySamplingRb;
+ private final RunConfigurationBase myConfig;
+
+ private static class MyClassFilterEditor extends ClassFilterEditor {
+ public MyClassFilterEditor(Project project) {
+ super(project, new ClassFilter() {
+ public boolean isAccepted(PsiClass aClass) {
+ if (aClass.getContainingClass() != null) return false;
+ return true;
+ }
+ });
+ }
+
+ protected void addPatternFilter() {
+ PackageChooser chooser = new PackageChooserDialog(CodeInsightBundle.message("coverage.pattern.filter.editor.choose.package.title"), myProject);
+ chooser.show();
+ if (chooser.isOK()) {
+ List<PsiPackage> packages = chooser.getSelectedPackages();
+ if (!packages.isEmpty()) {
+ for (final PsiPackage aPackage : packages) {
+ final String fqName = aPackage.getQualifiedName();
+ final String pattern = fqName.length() > 0 ? fqName + ".*" : "*";
+ myTableModel.addRow(createFilter(pattern));
+ }
+ int row = myTableModel.getRowCount() - 1;
+ myTable.getSelectionModel().setSelectionInterval(row, row);
+ myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+ myTable.requestFocus();
+ }
+ }
+ }
+
+ protected String getAddPatternButtonText() {
+ return CodeInsightBundle.message("coverage.button.add.package");
+ }
+
+ @Override
+ protected Icon getAddPatternButtonIcon() {
+ return IconUtil.getAddPackageIcon();
+ }
+ }
+
+ public CoverageConfigurable(RunConfigurationBase config) {
+ myConfig = config;
+ myProject = config.getProject();
+ }
+
+ protected void resetEditorFrom(final RunConfigurationBase runConfiguration) {
+ final boolean isJre50;
+ if (runConfiguration instanceof CommonJavaRunConfigurationParameters && myVersionDetector.isJre50Configured((CommonJavaRunConfigurationParameters)runConfiguration)) {
+ isJre50 = true;
+ } else if (runConfiguration instanceof ModuleBasedConfiguration){
+ isJre50 = myVersionDetector.isModuleJre50Configured((ModuleBasedConfiguration)runConfiguration);
+ } else {
+ isJre50 = true;
+ }
+
+ myCoverageNotSupportedLabel.setVisible(!isJre50);
+
+ final JavaCoverageEnabledConfiguration configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
+ CoverageRunner runner = configuration.getCoverageRunner();
+ if (runner != null) {
+ myCoverageRunnerCb.setSelectedItem(new CoverageRunnerItem(runner));
+ } else {
+ final String runnerId = configuration.getRunnerId();
+ if (runnerId != null){
+ final CoverageRunnerItem runnerItem = new CoverageRunnerItem(runnerId);
+ final DefaultComboBoxModel model = (DefaultComboBoxModel)myCoverageRunnerCb.getModel();
+ if (model.getIndexOf(runnerItem) == -1) {
+ model.addElement(runnerItem);
+ }
+ myCoverageRunnerCb.setSelectedItem(runnerItem);
+ } else {
+ myCoverageRunnerCb.setSelectedIndex(0);
+ }
+ runner = ((CoverageRunnerItem)myCoverageRunnerCb.getSelectedItem()).getRunner();
+ }
+ UIUtil.setEnabled(myRunnerPanel, isJre50, true);
+
+
+ myClassFilterEditor.setFilters(configuration.getCoveragePatterns());
+ final boolean isCoverageByTestApplicable = runner != null && runner.isCoverageByTestApplicable();
+ myTracingRb.setEnabled(myTracingRb.isEnabled() && isCoverageByTestApplicable);
+ mySamplingRb.setSelected(configuration.isSampling() || !isCoverageByTestApplicable);
+ myTracingRb.setSelected(!mySamplingRb.isSelected());
+
+ myTrackPerTestCoverageCb.setSelected(configuration.isTrackPerTestCoverage());
+ myTrackPerTestCoverageCb.setEnabled(myTracingRb.isEnabled() && myTracingRb.isSelected() && canHavePerTestCoverage());
+
+ myTrackTestSourcesCb.setSelected(configuration.isTrackTestFolders());
+ }
+
+ protected boolean canHavePerTestCoverage() {
+ return CoverageEnabledConfiguration.getOrCreate(myConfig).canHavePerTestCoverage();
+ }
+
+ protected void applyEditorTo(final RunConfigurationBase runConfiguration) throws ConfigurationException {
+ final JavaCoverageEnabledConfiguration configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
+ configuration.setCoveragePatterns(myClassFilterEditor.getFilters());
+ configuration.setCoverageRunner(getSelectedRunner());
+ configuration.setTrackPerTestCoverage(myTrackPerTestCoverageCb.isSelected());
+ configuration.setSampling(mySamplingRb.isSelected());
+ configuration.setTrackTestFolders(myTrackTestSourcesCb.isSelected());
+ }
+
+ @NotNull
+ protected JComponent createEditor() {
+ JPanel result = new JPanel(new GridBagLayout());
+
+ final DefaultComboBoxModel runnersModel = new DefaultComboBoxModel();
+ myCoverageRunnerCb = new JComboBox(runnersModel);
+
+ final JavaCoverageEnabledConfiguration javaCoverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(myConfig);
+ LOG.assertTrue(javaCoverageEnabledConfiguration != null);
+ final JavaCoverageEngine provider = javaCoverageEnabledConfiguration.getCoverageProvider();
+ for (CoverageRunner runner : Extensions.getExtensions(CoverageRunner.EP_NAME)) {
+ if (runner.acceptsCoverageEngine(provider)) {
+ runnersModel.addElement(new CoverageRunnerItem(runner));
+ }
+ }
+ myCoverageRunnerCb.setRenderer(new ListCellRendererWrapper<CoverageRunnerItem>() {
+ @Override
+ public void customize(JList list, CoverageRunnerItem value, int index, boolean selected, boolean hasFocus) {
+ if (value != null) {
+ setText(value.getPresentableName());
+ }
+ }
+ });
+ myCoverageRunnerCb.addActionListener(new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ final CoverageRunner runner = getSelectedRunner();
+ enableTracingPanel(runner != null && runner.isCoverageByTestApplicable());
+ myTrackPerTestCoverageCb.setEnabled(myTracingRb.isSelected() && canHavePerTestCoverage() && runner != null && runner.isCoverageByTestApplicable());
+ }
+ });
+ myRunnerPanel = new JPanel(new GridBagLayout());
+ myRunnerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ myRunnerPanel.add(new JLabel("Choose coverage runner:"), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,10), 0, 0));
+ myRunnerPanel.add(myCoverageRunnerCb, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0, 0));
+ final JPanel cPanel = new JPanel(new VerticalFlowLayout());
+
+ mySamplingRb = new JRadioButton("Sampling");
+ cPanel.add(mySamplingRb);
+ myTracingRb = new JRadioButton("Tracing");
+ cPanel.add(myTracingRb);
+
+ final ButtonGroup group = new ButtonGroup();
+ group.add(mySamplingRb);
+ group.add(myTracingRb);
+
+ ActionListener samplingListener = new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ final CoverageRunner runner = getSelectedRunner();
+ myTrackPerTestCoverageCb.setEnabled(canHavePerTestCoverage() && myTracingRb.isSelected() && runner != null && runner.isCoverageByTestApplicable());
+ }
+ };
+
+ mySamplingRb.addActionListener(samplingListener);
+ myTracingRb.addActionListener(samplingListener);
+
+ myTrackPerTestCoverageCb = new JCheckBox("Track per test coverage");
+ final JPanel tracingPanel = new JPanel(new BorderLayout());
+ tracingPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
+ tracingPanel.add(myTrackPerTestCoverageCb, BorderLayout.CENTER);
+ cPanel.add(tracingPanel);
+ myRunnerPanel.add(cPanel, new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0, 0));
+
+ final GridBagConstraints gc = new GridBagConstraints(0, GridBagConstraints.RELATIVE,
+ 1, 1, 1, 0,
+ GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
+ new Insets(0, 0, 0, 0), 0, 0);
+ result.add(myRunnerPanel, gc);
+
+ JPanel panel = new JPanel(new GridBagLayout());
+ panel.setBorder(IdeBorderFactory.createTitledBorder(ExecutionBundle.message("record.coverage.filters.title"), false));
+ myClassFilterEditor = new MyClassFilterEditor(myProject);
+ final GridBagConstraints bagConstraints =
+ new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
+ new Insets(0, 0, 0, 0), 0, 0);
+ panel.add(myClassFilterEditor, bagConstraints);
+
+ bagConstraints.weighty = 0;
+ myTrackTestSourcesCb = new JCheckBox("Enable coverage in test folders");
+ panel.add(myTrackTestSourcesCb, bagConstraints);
+
+ result.add(panel, gc);
+
+ myCoverageNotSupportedLabel = new JLabel(CodeInsightBundle.message("code.coverage.is.not.supported"));
+ myCoverageNotSupportedLabel.setIcon(AllIcons.General.WarningDialog);
+ result.add(myCoverageNotSupportedLabel, gc);
+ return result;
+ }
+
+ @Nullable
+ private CoverageRunner getSelectedRunner() {
+ final CoverageRunnerItem runnerItem = (CoverageRunnerItem)myCoverageRunnerCb.getSelectedItem();
+ if (runnerItem == null) {
+ LOG.debug("Available runners: " + myCoverageRunnerCb.getModel().getSize());
+ }
+ return runnerItem != null ? runnerItem.getRunner() : null;
+ }
+
+ private void enableTracingPanel(final boolean enabled) {
+ myTracingRb.setEnabled(enabled);
+ if (!enabled) {
+ mySamplingRb.setSelected(true);
+ }
+ }
+
+ private static class CoverageRunnerItem {
+ private CoverageRunner myRunner;
+ private @NotNull String myRunnerId;
+
+ private CoverageRunnerItem(@NotNull CoverageRunner runner) {
+ myRunner = runner;
+ myRunnerId = runner.getId();
+ }
+
+ private CoverageRunnerItem(String runnerId) {
+ myRunnerId = runnerId;
+ }
+
+ public CoverageRunner getRunner() {
+ return myRunner;
+ }
+
+ public String getRunnerId() {
+ return myRunnerId;
+ }
+
+ public String getPresentableName() {
+ return myRunner != null ? myRunner.getPresentableName() : myRunnerId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CoverageRunnerItem that = (CoverageRunnerItem)o;
+
+ if (!myRunnerId.equals(that.myRunnerId)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myRunnerId.hashCode();
+ }
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/execution/configurations/coverage/JavaCoverageEnabledConfiguration.java b/plugins/coverage/src/com/intellij/execution/configurations/coverage/JavaCoverageEnabledConfiguration.java
new file mode 100644
index 000000000000..f8d3c14ace28
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/execution/configurations/coverage/JavaCoverageEnabledConfiguration.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2000-2007 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.execution.configurations.coverage;
+
+import com.intellij.coverage.CoverageRunner;
+import com.intellij.coverage.IDEACoverageRunner;
+import com.intellij.coverage.JavaCoverageEngine;
+import com.intellij.coverage.JavaCoverageRunner;
+import com.intellij.execution.configurations.RunConfigurationBase;
+import com.intellij.execution.configurations.SimpleJavaParameters;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.ui.classFilter.ClassFilter;
+import com.intellij.util.ArrayUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+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.List;
+
+/**
+ * Base class for java run configurations with enabled code coverage
+ * @author ven
+ */
+public class JavaCoverageEnabledConfiguration extends CoverageEnabledConfiguration {
+ private static final Logger LOG = Logger.getInstance("com.intellij.execution.configurations.coverage.JavaCoverageEnabledConfiguration");
+
+ private ClassFilter[] myCoveragePatterns;
+
+ private boolean myIsMergeWithPreviousResults = false;
+ private String mySuiteToMergeWith;
+
+ @NonNls private static final String COVERAGE_PATTERN_ELEMENT_NAME = "pattern";
+ @NonNls private static final String COVERAGE_MERGE_ATTRIBUTE_NAME = "merge";
+ @NonNls private static final String COVERAGE_MERGE_SUITE_ATT_NAME = "merge_suite";
+
+ private JavaCoverageEngine myCoverageProvider;
+
+ public JavaCoverageEnabledConfiguration(final RunConfigurationBase configuration,
+ final JavaCoverageEngine coverageProvider) {
+ super(configuration);
+ myCoverageProvider = coverageProvider;
+ setCoverageRunner(CoverageRunner.getInstance(IDEACoverageRunner.class));
+ }
+
+ @Nullable
+ public static JavaCoverageEnabledConfiguration getFrom(final RunConfigurationBase configuration) {
+ final CoverageEnabledConfiguration coverageEnabledConfiguration = getOrCreate(configuration);
+ if (coverageEnabledConfiguration instanceof JavaCoverageEnabledConfiguration) {
+ return (JavaCoverageEnabledConfiguration)coverageEnabledConfiguration;
+ }
+ return null;
+ }
+
+ public void appendCoverageArgument(final SimpleJavaParameters javaParameters) {
+ final CoverageRunner runner = getCoverageRunner();
+ try {
+ if (runner != null && runner instanceof JavaCoverageRunner) {
+ final String path = getCoverageFilePath();
+ assert path != null; // cannot be null here if runner != null
+
+ ((JavaCoverageRunner)runner).appendCoverageArgument(new File(path).getCanonicalPath(),
+ getPatterns(),
+ javaParameters,
+ isTrackPerTestCoverage() && !isSampling(),
+ isSampling());
+ }
+ }
+ catch (IOException e) {
+ LOG.info(e);
+ }
+ }
+
+
+ @NotNull
+ public JavaCoverageEngine getCoverageProvider() {
+ return myCoverageProvider;
+ }
+
+ public ClassFilter[] getCoveragePatterns() {
+ return myCoveragePatterns;
+ }
+
+ @Nullable
+ public String [] getPatterns() {
+ if (myCoveragePatterns != null) {
+ List<String> patterns = new ArrayList<String>();
+ for (ClassFilter coveragePattern : myCoveragePatterns) {
+ if (coveragePattern.isEnabled()) patterns.add(coveragePattern.getPattern());
+ }
+ return ArrayUtil.toStringArray(patterns);
+ }
+ return null;
+ }
+
+ public void setCoveragePatterns(final ClassFilter[] coveragePatterns) {
+ myCoveragePatterns = coveragePatterns;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+
+ // merge with prev results
+ final String mergeAttribute = element.getAttributeValue(COVERAGE_MERGE_ATTRIBUTE_NAME);
+ myIsMergeWithPreviousResults = mergeAttribute != null && Boolean.valueOf(mergeAttribute).booleanValue();
+
+ mySuiteToMergeWith = element.getAttributeValue(COVERAGE_MERGE_SUITE_ATT_NAME);
+
+ // coverage patters
+ final List children = element.getChildren(COVERAGE_PATTERN_ELEMENT_NAME);
+ if (children.size() > 0) {
+ myCoveragePatterns = new ClassFilter[children.size()];
+ for (int i = 0; i < children.size(); i++) {
+ myCoveragePatterns[i] = new ClassFilter();
+ @NonNls final Element e = (Element)children.get(i);
+ myCoveragePatterns[i].readExternal(e);
+ final String val = e.getAttributeValue("value");
+ if (val != null) {
+ myCoveragePatterns[i].setPattern(val);
+ }
+ }
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ // just for backward compatibility with settings format before "Huge Coverage Refactoring"
+ // see [IDEA-56800] ProjectRunConfigurationManager component: "coverage" extension: "merge" attribute is misplaced
+ // here we can't use super.writeExternal(...) due to differences in format between IDEA 10 and IDEA 9.x
+
+ // enabled
+ element.setAttribute(COVERAGE_ENABLED_ATTRIBUTE_NAME, String.valueOf(isCoverageEnabled()));
+
+ // merge with prev
+ element.setAttribute(COVERAGE_MERGE_ATTRIBUTE_NAME, String.valueOf(myIsMergeWithPreviousResults));
+
+ if (myIsMergeWithPreviousResults && mySuiteToMergeWith != null) {
+ element.setAttribute(COVERAGE_MERGE_SUITE_ATT_NAME, mySuiteToMergeWith);
+ }
+
+ // track per test
+ final boolean trackPerTestCoverage = isTrackPerTestCoverage();
+ if (!trackPerTestCoverage) {
+ element.setAttribute(TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME, String.valueOf(trackPerTestCoverage));
+ }
+
+ // sampling
+ final boolean sampling = isSampling();
+ if (sampling) {
+ element.setAttribute(SAMPLING_COVERAGE_ATTRIBUTE_NAME, String.valueOf(sampling));
+ }
+
+ // test folders
+ final boolean trackTestFolders = isTrackTestFolders();
+ if (trackTestFolders) {
+ element.setAttribute(TRACK_TEST_FOLDERS, String.valueOf(trackTestFolders));
+ }
+
+ // runner
+ final CoverageRunner coverageRunner = getCoverageRunner();
+ final String runnerId = getRunnerId();
+ if (coverageRunner != null) {
+ element.setAttribute(COVERAGE_RUNNER, coverageRunner.getId());
+ } else if (runnerId != null) {
+ element.setAttribute(COVERAGE_RUNNER, runnerId);
+ }
+
+ // patterns
+ if (myCoveragePatterns != null) {
+ for (ClassFilter pattern : myCoveragePatterns) {
+ @NonNls final Element patternElement = new Element(COVERAGE_PATTERN_ELEMENT_NAME);
+ pattern.writeExternal(patternElement);
+ element.addContent(patternElement);
+ }
+ }
+ }
+
+ @Nullable
+ public String getCoverageFilePath() {
+ if (myCoverageFilePath != null ) {
+ return myCoverageFilePath;
+ }
+ myCoverageFilePath = createCoverageFile();
+ return myCoverageFilePath;
+ }
+
+ public void setUpCoverageFilters(String className, String packageName) {
+ if (getCoveragePatterns() == null) {
+ String pattern = null;
+ if (className != null && className.length() > 0) {
+ int index = className.lastIndexOf('.');
+ if (index >= 0) {
+ pattern = className.substring(0, index);
+ }
+ }
+ else if (packageName != null) {
+ pattern = packageName;
+ }
+
+
+ if (pattern != null && pattern.length() > 0) {
+ setCoveragePatterns(new ClassFilter[]{new ClassFilter(pattern + ".*")});
+ }
+ }
+ }
+}
diff --git a/plugins/coverage/src/com/intellij/execution/coverage/CoverageJavaRunConfigurationExtension.java b/plugins/coverage/src/com/intellij/execution/coverage/CoverageJavaRunConfigurationExtension.java
new file mode 100644
index 000000000000..130b85bdbfc5
--- /dev/null
+++ b/plugins/coverage/src/com/intellij/execution/coverage/CoverageJavaRunConfigurationExtension.java
@@ -0,0 +1,275 @@
+/*
+ * User: anna
+ * Date: 27-Aug-2009
+ */
+package com.intellij.execution.coverage;
+
+import com.intellij.coverage.*;
+import com.intellij.coverage.listeners.CoverageListener;
+import com.intellij.execution.CommonJavaRunConfigurationParameters;
+import com.intellij.execution.Location;
+import com.intellij.execution.RunConfigurationExtension;
+import com.intellij.execution.configurations.*;
+import com.intellij.execution.configurations.coverage.CoverageConfigurable;
+import com.intellij.execution.configurations.coverage.CoverageEnabledConfiguration;
+import com.intellij.execution.configurations.coverage.JavaCoverageEnabledConfiguration;
+import com.intellij.execution.junit.RefactoringListeners;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
+import com.intellij.openapi.options.SettingsEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.refactoring.listeners.RefactoringElementListener;
+import com.intellij.refactoring.listeners.RefactoringElementListenerComposite;
+import com.intellij.ui.classFilter.ClassFilter;
+import com.intellij.util.ArrayUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Registers "Coverage" tab in Java run configurations
+ */
+public class CoverageJavaRunConfigurationExtension extends RunConfigurationExtension {
+ public void attachToProcess(@NotNull final RunConfigurationBase configuration, @NotNull ProcessHandler handler, RunnerSettings runnerSettings) {
+ CoverageDataManager.getInstance(configuration.getProject()).attachToProcess(handler, configuration, runnerSettings);
+ }
+
+ @Nullable
+ public SettingsEditor createEditor(@NotNull RunConfigurationBase configuration) {
+ return new CoverageConfigurable(configuration);
+ }
+
+ public String getEditorTitle() {
+ return CoverageEngine.getEditorTitle();
+ }
+
+ @NotNull
+ @Override
+ public String getSerializationId() {
+ return "coverage";
+ }
+
+ public void updateJavaParameters(RunConfigurationBase configuration, JavaParameters params, RunnerSettings runnerSettings) {
+ if (!isApplicableFor(configuration)) {
+ return;
+ }
+
+ final JavaCoverageEnabledConfiguration coverageConfig = JavaCoverageEnabledConfiguration.getFrom(configuration);
+ //noinspection ConstantConditions
+ coverageConfig.setCurrentCoverageSuite(null);
+ final CoverageRunner coverageRunner = coverageConfig.getCoverageRunner();
+ if (runnerSettings instanceof CoverageRunnerData && coverageRunner != null) {
+ final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(configuration.getProject());
+ coverageConfig.setCurrentCoverageSuite(coverageDataManager.addCoverageSuite(coverageConfig));
+ coverageConfig.appendCoverageArgument(params);
+
+ final Sdk jdk = params.getJdk();
+ if (jdk != null && JavaSdk.getInstance().isOfVersionOrHigher(jdk, JavaSdkVersion.JDK_1_7) && coverageRunner instanceof JavaCoverageRunner && !((JavaCoverageRunner)coverageRunner).isJdk7Compatible()) {
+ Notifications.Bus.notify(new Notification("Coverage", "Coverage instrumentation is not fully compatible with JDK 7",
+ coverageRunner.getPresentableName() +
+ " coverage instrumentation can lead to java.lang.VerifyError errors with JDK 7. If so, please try IDEA coverage runner.",
+ NotificationType.WARNING));
+ }
+ }
+ }
+
+ @Override
+ public void readExternal(@NotNull final RunConfigurationBase runConfiguration, @NotNull Element element) throws InvalidDataException {
+ if (!isApplicableFor(runConfiguration)) {
+ return;
+ }
+
+ //noinspection ConstantConditions
+ JavaCoverageEnabledConfiguration.getFrom(runConfiguration).readExternal(element);
+ }
+
+ @Override
+ public void writeExternal(@NotNull RunConfigurationBase runConfiguration, @NotNull Element element) throws WriteExternalException {
+ if (!isApplicableFor(runConfiguration)) {
+ return;
+ }
+ //noinspection ConstantConditions
+ JavaCoverageEnabledConfiguration.getFrom(runConfiguration).writeExternal(element);
+ }
+
+ @Override
+ public void extendCreatedConfiguration(@NotNull RunConfigurationBase runJavaConfiguration, @NotNull Location location) {
+ final JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(runJavaConfiguration);
+ assert coverageEnabledConfiguration != null;
+ if (runJavaConfiguration instanceof CommonJavaRunConfigurationParameters) {
+ coverageEnabledConfiguration.setUpCoverageFilters(((CommonJavaRunConfigurationParameters)runJavaConfiguration).getRunClass(),
+ ((CommonJavaRunConfigurationParameters)runJavaConfiguration).getPackage());
+ }
+ }
+
+ @Override
+ public void cleanUserData(RunConfigurationBase runConfiguration) {
+ runConfiguration.putCopyableUserData(CoverageEnabledConfiguration.COVERAGE_KEY, null);
+ }
+
+ @Override
+ public void validateConfiguration(@NotNull RunConfigurationBase runJavaConfiguration, boolean isExecution)
+ throws RuntimeConfigurationException {
+ }
+
+ @Override
+ public RefactoringElementListener wrapElementListener(PsiElement element,
+ RunConfigurationBase configuration,
+ RefactoringElementListener listener) {
+ if (!isApplicableFor(configuration)) {
+ return listener;
+ }
+ final JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(configuration);
+ if (coverageEnabledConfiguration != null) {
+ final Project project = configuration.getProject();
+ final ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns();
+ final String[] filters = getFilters(coverageEnabledConfiguration);
+ if (patterns != null) {
+ assert filters != null;
+ if (element instanceof PsiClass) {
+ final int idx = ArrayUtil.find(filters, ((PsiClass)element).getQualifiedName());
+ if (idx > -1) {
+ final RefactoringListeners.Accessor<PsiClass> accessor = new MyClassAccessor(project, patterns, idx, filters);
+ final RefactoringElementListener classListener = RefactoringListeners.getClassOrPackageListener(element, accessor);
+ if (classListener != null) {
+ listener = appendListener(listener, classListener);
+ }
+ }
+ } else if (element instanceof PsiPackage) {
+ final String qualifiedName = ((PsiPackage)element).getQualifiedName();
+ for (int i = 0, filtersLength = filters.length; i < filtersLength; i++) {
+ if (filters[i].startsWith(qualifiedName + ".")) {
+ final RefactoringElementListener packageListener;
+ if (filters[i].endsWith("*")) {
+ packageListener = RefactoringListeners.getListener((PsiPackage)element,
+ new MyPackageAccessor(project, patterns, i, filters));
+ } else {
+ packageListener = RefactoringListeners.getClassOrPackageListener(element,
+ new MyClassAccessor(project, patterns, i, filters));
+ }
+ if (packageListener != null) {
+ listener = appendListener(listener, packageListener);
+ }
+ }
+ }
+ }
+ }
+ }
+ return listener;
+ }
+
+ @Nullable
+ private static String[] getFilters(JavaCoverageEnabledConfiguration coverageEnabledConfiguration) {
+ final ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns();
+ if (patterns != null) {
+ final List<String> filters = new ArrayList<String>();
+ for (ClassFilter classFilter : patterns) {
+ filters.add(classFilter.getPattern());
+ }
+ return ArrayUtil.toStringArray(filters);
+ }
+ return null;
+ }
+
+ private static RefactoringElementListener appendListener(RefactoringElementListener listener,
+ final RefactoringElementListener classOrPackageListener) {
+ if (listener == null) {
+ listener = new RefactoringElementListenerComposite();
+ } else if (!(listener instanceof RefactoringElementListenerComposite)) {
+ final RefactoringElementListenerComposite composite = new RefactoringElementListenerComposite();
+ composite.addListener(listener);
+ listener = composite;
+ }
+ ((RefactoringElementListenerComposite)listener).addListener(classOrPackageListener);
+ return listener;
+ }
+
+ @Override
+ public boolean isListenerDisabled(RunConfigurationBase configuration, Object listener, RunnerSettings runnerSettings) {
+ if (listener instanceof CoverageListener) {
+ if (!(runnerSettings instanceof CoverageRunnerData)) return true;
+ final CoverageEnabledConfiguration coverageEnabledConfiguration = CoverageEnabledConfiguration.getOrCreate(configuration);
+ return !(coverageEnabledConfiguration.getCoverageRunner() instanceof IDEACoverageRunner) ||
+ !(coverageEnabledConfiguration.isTrackPerTestCoverage() && !coverageEnabledConfiguration.isSampling());
+ }
+ return false;
+ }
+
+ protected boolean isApplicableFor(@NotNull final RunConfigurationBase configuration) {
+ return CoverageEnabledConfiguration.isApplicableTo(configuration);
+ }
+
+ private static class MyPackageAccessor extends MyAccessor implements RefactoringListeners.Accessor<PsiPackage> {
+
+
+ private MyPackageAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) {
+ super(project, patterns, idx, filters);
+ }
+
+ public void setName(String qualifiedName) {
+ super.setName(qualifiedName + ".*");
+ }
+
+ public PsiPackage getPsiElement() {
+ final String name = getName();
+ return JavaPsiFacade.getInstance(getProject()).findPackage(name.substring(0, name.length() - ".*".length()));
+ }
+
+ public void setPsiElement(PsiPackage psiElement) {
+ setName(psiElement.getQualifiedName());
+ }
+ }
+
+ private static class MyClassAccessor extends MyAccessor implements RefactoringListeners.Accessor<PsiClass> {
+
+ private MyClassAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) {
+ super(project, patterns, idx, filters);
+ }
+
+ public PsiClass getPsiElement() {
+ return JavaPsiFacade.getInstance(getProject()).findClass(getName(), GlobalSearchScope.allScope(getProject()));
+ }
+
+ public void setPsiElement(PsiClass psiElement) {
+ setName(psiElement.getQualifiedName());
+ }
+ }
+
+ private static class MyAccessor {
+ private final Project myProject;
+ private final ClassFilter[] myPatterns;
+ private final int myIdx;
+ private final String[] myFilters;
+
+ private MyAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) {
+ myProject = project;
+ myPatterns = patterns;
+ myIdx = idx;
+ myFilters = filters;
+ }
+
+ public void setName(String qName) {
+ myPatterns[myIdx] = new ClassFilter(qName);
+ }
+
+ public String getName() {
+ return myFilters[myIdx];
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties
index 15ce261fa653..31acb1581014 100644
--- a/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties
+++ b/plugins/cvs/cvs-core/src/com/intellij/cvsSupport2/CvsBundle.properties
@@ -79,7 +79,7 @@ operation.name.test.connection=Test Connection
message.connecting.to.cvs.server=Connecting to CVS server
message.current.global.timeout.setting=Current global timeout setting: {0} seconds
test.connection.login.failed.text=Login failed
-cvs.root.configuration.on.branch.string.representation={0} (on.branch {1})
+cvs.root.configuration.on.branch.string.representation={0} (on branch {1})
cvs.root.configuration.on.date.string.representation={0} (for date {1})
dialog.title.global.cvs.settings=Global CVS Settings
operation.status.connection.successful=Connection successful
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsFilePath.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsFilePath.java
index aa9164bf419d..2bfc4e1633f7 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsFilePath.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/CvsFilePath.java
@@ -27,11 +27,12 @@ public class CvsFilePath extends FilePathImpl {
private final CvsRepositoryLocation myRepositoryLocation;
- public CvsFilePath(@NotNull VirtualFile virtualFile, CvsRepositoryLocation repositoryLocation) {
+ public CvsFilePath(@NotNull VirtualFile virtualFile, @NotNull CvsRepositoryLocation repositoryLocation) {
super(virtualFile);
myRepositoryLocation = repositoryLocation;
}
+ @NotNull
public CvsRepositoryLocation getRepositoryLocation() {
return myRepositoryLocation;
}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsEntriesManager.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsEntriesManager.java
index 05602bfac677..45e14c04399e 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsEntriesManager.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsEntriesManager.java
@@ -35,8 +35,8 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.HashMap;
-import com.intellij.util.containers.HashSet;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.netbeans.lib.cvsclient.admin.Entry;
@@ -53,15 +53,15 @@ public class CvsEntriesManager extends VirtualFileAdapter {
private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.application.CvsEntriesManager");
- private final Map<VirtualFile, CvsInfo> myInfoByParentDirectoryPath = new HashMap<VirtualFile, CvsInfo>();
+ private final Map<VirtualFile, CvsInfo> myInfoByParentDirectoryPath = new THashMap<VirtualFile, CvsInfo>();
private static final String CVS_ADMIN_DIRECTORY_NAME = CvsUtil.CVS;
private final Collection<CvsEntriesListener> myEntriesListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private int myIsActive = 0;
- private final Collection<String> myFilesToRefresh = new HashSet<String>();
+ private final Collection<String> myFilesToRefresh = new THashSet<String>();
- private final Map<String, CvsConnectionSettings> myStringToSettingsMap = new HashMap<String, CvsConnectionSettings>();
+ private final Map<String, CvsConnectionSettings> myStringToSettingsMap = new THashMap<String, CvsConnectionSettings>();
private final UserDirIgnores myUserDirIgnores = new UserDirIgnores();
private final MyVirtualFileManagerListener myVirtualFileManagerListener = new MyVirtualFileManagerListener();
private final CvsApplicationLevelConfiguration myApplicationLevelConfiguration;
@@ -116,8 +116,9 @@ public class CvsEntriesManager extends VirtualFileAdapter {
@NotNull
private synchronized CvsInfo getInfoFor(VirtualFile parent) {
+ if (parent == null) return CvsInfo.getDummyCvsInfo();
if (!myInfoByParentDirectoryPath.containsKey(parent)) {
- CvsInfo cvsInfo = new CvsInfo(parent, this);
+ CvsInfo cvsInfo = new CvsInfo(parent);
myInfoByParentDirectoryPath.put(cvsInfo.getKey(), cvsInfo);
}
return myInfoByParentDirectoryPath.get(parent);
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java
index d385be061481..7a9d9320147c 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/application/CvsInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -57,14 +57,12 @@ public class CvsInfo {
private boolean myIsLoaded = false;
private final VirtualFile myParent;
- private final CvsEntriesManager myCvsEntriesManager;
private static final VirtualFile DUMMY_ROOT = null;
private boolean myStickyTagIsLoaded = false;
- public CvsInfo(VirtualFile parent, CvsEntriesManager cvsEntriesManager) {
+ public CvsInfo(VirtualFile parent) {
myParent = parent;
- myCvsEntriesManager = cvsEntriesManager;
}
public synchronized CvsConnectionSettings getConnectionSettings() {
@@ -85,7 +83,7 @@ public class CvsInfo {
myRepository = CvsUtil.getRelativeRepositoryPath(myRepository, myConnectionSettings.REPOSITORY);
}
- myCvsEntriesManager.watchForCvsAdminFiles(myParent);
+ CvsEntriesManager.getInstance().watchForCvsAdminFiles(myParent);
}
finally {
myIsLoaded = true;
@@ -107,11 +105,11 @@ public class CvsInfo {
myConnectionSettings = getAbsentSettings();
}
else {
- myConnectionSettings = myCvsEntriesManager.createConnectionSettingsOn(cvsRoot);
+ myConnectionSettings = CvsEntriesManager.getInstance().createConnectionSettingsOn(cvsRoot);
}
}
catch (Exception ex) {
- myConnectionSettings = new MyInvalidCvsConnectionSettings();
+ myConnectionSettings = getAbsentSettings();
}
}
@@ -125,7 +123,7 @@ public class CvsInfo {
if (myParent == null) {
myIgnoreFilter = IgnoredFilesInfo.IGNORE_NOTHING;
}
- else if (myCvsEntriesManager.fileIsIgnored(myParent)) {
+ else if (CvsEntriesManager.getInstance().fileIsIgnored(myParent)) {
myIgnoreFilter = IgnoredFilesInfo.IGNORE_ALL;
}
else if (!CvsUtil.fileIsUnderCvs(myParent)) {
@@ -320,7 +318,7 @@ public class CvsInfo {
@SuppressWarnings({"NonSynchronizedMethodOverridesSynchronizedMethod"})
private static class DummyCvsInfo extends CvsInfo {
public DummyCvsInfo() {
- super(null, null);
+ super(null);
}
@Override
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/checkout/CvsCheckoutProvider.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/checkout/CvsCheckoutProvider.java
index 3d494b700ac5..1d7c7e4cdf54 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/checkout/CvsCheckoutProvider.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/checkout/CvsCheckoutProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -45,7 +45,7 @@ public class CvsCheckoutProvider implements CheckoutProvider {
final CvsElement[] selectedElements = checkoutWizard.getSelectedElements();
final CvsHandler checkoutHandler = CommandCvsHandler.createCheckoutHandler(
- checkoutWizard.getSelectedConfiguration(),
+ checkoutWizard.getConfigurationWithDateOrRevisionSettings(),
collectCheckoutPaths(selectedElements),
checkoutDirectory,
useAlternateCheckoutPath,
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/CvsRootConfiguration.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/CvsRootConfiguration.java
index ec247dbc400c..fec6b5d6fef8 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/CvsRootConfiguration.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/CvsRootConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -91,12 +91,7 @@ public class CvsRootConfiguration extends AbstractConfiguration implements CvsEn
public static String createStringRepresentationOn(CvsMethod method, String user, String host, int port, String repository) {
if (method == CvsMethod.LOCAL_METHOD) {
- final StringBuilder result = new StringBuilder();
- result.append(SEPARATOR);
- result.append(method.getName());
- result.append(SEPARATOR);
- result.append(repository);
- return result.toString();
+ return SEPARATOR + method.getName() + SEPARATOR + repository;
}
final StringBuilder result = new StringBuilder();
result.append(SEPARATOR);
@@ -138,15 +133,6 @@ public class CvsRootConfiguration extends AbstractConfiguration implements CvsEn
return DATE_OR_REVISION_SETTINGS.USE_BRANCH && !DATE_OR_REVISION_SETTINGS.BRANCH.isEmpty();
}
- public CvsRootConfiguration getMyCopy() {
- try {
- return (CvsRootConfiguration)clone();
- }
- catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
- }
-
public void testConnection(Project project) throws AuthenticationException, IOException {
final IConnection connection = createSettings().createConnection(new ReadWriteStatistics());
final ErrorMessagesProcessor errorProcessor = new ErrorMessagesProcessor();
@@ -267,15 +253,20 @@ public class CvsRootConfiguration extends AbstractConfiguration implements CvsEn
}
@Override
- public Object clone() throws CloneNotSupportedException {
- final CvsRootConfiguration result = (CvsRootConfiguration)super.clone();
- result.DATE_OR_REVISION_SETTINGS = DATE_OR_REVISION_SETTINGS.clone();
- result.PROXY_SETTINGS = PROXY_SETTINGS.clone();
- result.EXT_CONFIGURATION = EXT_CONFIGURATION.clone();
- result.SSH_CONFIGURATION = SSH_CONFIGURATION.clone();
- result.SSH_FOR_EXT_CONFIGURATION = SSH_FOR_EXT_CONFIGURATION.clone();
- result.LOCAL_CONFIGURATION = LOCAL_CONFIGURATION.clone();
- return result;
+ public CvsRootConfiguration clone() {
+ try {
+ final CvsRootConfiguration result = (CvsRootConfiguration)super.clone();
+ result.DATE_OR_REVISION_SETTINGS = DATE_OR_REVISION_SETTINGS.clone();
+ result.PROXY_SETTINGS = PROXY_SETTINGS.clone();
+ result.EXT_CONFIGURATION = EXT_CONFIGURATION.clone();
+ result.SSH_CONFIGURATION = SSH_CONFIGURATION.clone();
+ result.SSH_FOR_EXT_CONFIGURATION = SSH_FOR_EXT_CONFIGURATION.clone();
+ result.LOCAL_CONFIGURATION = LOCAL_CONFIGURATION.clone();
+ return result;
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
}
@Override
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java
index 6182b816ef38..a051da3c11b7 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationsListEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -131,7 +131,7 @@ public class CvsConfigurationsListEditor extends DialogWrapper implements DataPr
private void fillModel(List<CvsRootConfiguration> configurations) {
for (final CvsRootConfiguration configuration : configurations) {
- myModel.addElement(configuration.getMyCopy());
+ myModel.addElement(configuration.clone());
}
}
@@ -198,8 +198,7 @@ public class CvsConfigurationsListEditor extends DialogWrapper implements DataPr
private void copySelectedConfiguration() {
if (!saveSelectedConfiguration()) return;
- final CvsRootConfiguration newConfig = mySelection.getMyCopy();
- myModel.addElement(newConfig);
+ myModel.addElement(mySelection.clone());
myList.setSelectedIndex(myModel.getSize() - 1);
}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java
index 579515c0883d..6d654523a4fa 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/GetAllBranchesOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -32,14 +32,20 @@ public class GetAllBranchesOperation extends LocalPathIndifferentOperation imple
@NonNls private final static String START = "symbolic names:";
@NonNls private final static String END = "keyword substitution:";
private boolean myIsInBranchesMode = false;
-
+ private final String myModuleName;
public GetAllBranchesOperation(CvsEnvironment environment) {
+ this(environment, ".");
+ }
+
+ public GetAllBranchesOperation(CvsEnvironment environment, String moduleName) {
super(environment);
+ myModuleName = moduleName;
}
protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) {
final RlogCommand command = new RlogCommand();
+ command.setModuleName(myModuleName);
// TODO[yole]: it would be best to implement smarter handling similar to LoadHistoryOperation, but it's too cumbersome without a major refactoring
command.setSuppressEmptyHeaders(false); // see IDEADEV-14276
return command;
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java
index ea326d216dfa..9ec75f49ac2f 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/cvsoperations/cvsTagOrBranch/TagsProviderOnEnvironment.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,15 +23,20 @@ import org.jetbrains.annotations.Nullable;
/**
* author: lesya
*/
-public abstract class TagsProviderOnEnvironment implements TagsProvider{
+public abstract class TagsProviderOnEnvironment implements TagsProvider {
+
@Override
@Nullable
public CvsCommandOperation getOperation() throws VcsException {
final CvsEnvironment env = getCvsEnvironment();
if (env == null) return null;
- return new GetAllBranchesOperation(env);
+ return new GetAllBranchesOperation(env, getModule());
}
@Nullable
protected abstract CvsEnvironment getCvsEnvironment();
+
+ public String getModule() {
+ return ".";
+ }
}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java
index 263a486e362d..d455ec93df62 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/SelectCvsElementStep.java
@@ -99,12 +99,7 @@ public class SelectCvsElementStep extends WizardStep {
}
final boolean logged = isLogged(selectedConfiguration);
if (logged) {
- try {
- myCvsTree.setCvsRootConfiguration((CvsRootConfiguration)selectedConfiguration.clone());
- }
- catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
+ myCvsTree.setCvsRootConfiguration((CvsRootConfiguration)selectedConfiguration.clone());
}
return logged;
}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java
index c8f7ffdbd299..d807e052f5e4 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/CheckoutWizard.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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 CheckoutWizard extends CvsWizard {
TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION, true, true);
mySelectLocationStep = new MySelectLocationStep(project);
- myChooseModeStep = new ChooseCheckoutMode(this);
+ myChooseModeStep = new ChooseCheckoutMode(project, this);
addStep(mySelectCVSConfigurationStep);
addStep(mySelectCvsElementStep);
@@ -81,6 +81,12 @@ public class CheckoutWizard extends CvsWizard {
return mySelectCVSConfigurationStep.getSelectedConfiguration();
}
+ public CvsRootConfiguration getConfigurationWithDateOrRevisionSettings() {
+ final CvsRootConfiguration configuration = getSelectedConfiguration().clone();
+ myChooseModeStep.saveDateOrRevisionSettings(configuration);
+ return configuration;
+ }
+
public boolean useAlternativeCheckoutLocation() {
return myChooseModeStep.useAlternativeCheckoutLocation();
}
diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java
index 7ead00b42cab..fabba066d749 100644
--- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java
+++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/ui/experts/checkout/ChooseCheckoutMode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,13 +17,23 @@ package com.intellij.cvsSupport2.ui.experts.checkout;
import com.intellij.CvsBundle;
import com.intellij.cvsSupport2.config.CvsApplicationLevelConfiguration;
+import com.intellij.cvsSupport2.config.CvsRootConfiguration;
+import com.intellij.cvsSupport2.connections.CvsEnvironment;
import com.intellij.cvsSupport2.cvsBrowser.CvsElement;
import com.intellij.cvsSupport2.cvsBrowser.CvsFile;
+import com.intellij.cvsSupport2.cvsoperations.common.CvsCommandOperation;
+import com.intellij.cvsSupport2.cvsoperations.cvsLog.LocalPathIndifferentLogOperation;
+import com.intellij.cvsSupport2.cvsoperations.cvsLog.LogOperation;
+import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.TagsProvider;
+import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.TagsProviderOnEnvironment;
+import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.ui.DateOrRevisionOrTagSettings;
import com.intellij.cvsSupport2.ui.ChangeKeywordSubstitutionPanel;
import com.intellij.cvsSupport2.ui.experts.WizardStep;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.checkout.CheckoutStrategy;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.ScrollPaneFactory;
@@ -33,6 +43,8 @@ import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.HashSet;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.netbeans.lib.cvsclient.command.KeywordSubstitution;
import javax.swing.*;
@@ -55,6 +67,7 @@ public class ChooseCheckoutMode extends WizardStep {
private final JCheckBox myMakeNewFilesReadOnly = new JCheckBox(CvsBundle.message("checkbox.make.new.files.read.only"));
private final JCheckBox myPruneEmptyDirectories = new JCheckBox(CvsBundle.message("checkbox.prune.empty.directories"));
private final ChangeKeywordSubstitutionPanel myChangeKeywordSubstitutionPanel;
+ private final DateOrRevisionOrTagSettings myDateOrRevisionOrTagSettings;
private final JPanel myCenterPanel = new JPanel(new CardLayout());
@@ -62,7 +75,9 @@ public class ChooseCheckoutMode extends WizardStep {
@NonNls public static final String MESSAGE = "MESSSAGE";
@NonNls private final JLabel myMessage = new JLabel("XXX");
- public ChooseCheckoutMode(CheckoutWizard wizard) {
+ private CvsRootConfiguration myConfiguration = null;
+
+ public ChooseCheckoutMode(Project project, CheckoutWizard wizard) {
super("###", wizard);
myCheckoutModeList.setCellRenderer(new ColoredListCellRenderer() {
@Override
@@ -93,9 +108,67 @@ public class ChooseCheckoutMode extends WizardStep {
myMessage.setBackground(UIUtil.getTableBackground());
myCenterPanel.add(MESSAGE, ScrollPaneFactory.createScrollPane(messagePanel));
+ myDateOrRevisionOrTagSettings = new DateOrRevisionOrTagSettings(new TagsProviderOnEnvironment() {
+ @Nullable
+ @Override
+ protected CvsEnvironment getCvsEnvironment() {
+ return getWizard().getSelectedConfiguration();
+ }
+
+ @Override
+ public String getModule() {
+ final CvsElement[] selectedElements = getWizard().getSelectedElements();
+ String module = null;
+ for (CvsElement element : selectedElements) {
+ final String checkoutPath = element.getCheckoutPath();
+ if (module == null) {
+ module = checkoutPath;
+ continue;
+ }
+ final String commonParentModule = findCommonParentModule(module, checkoutPath);
+ if (commonParentModule == null) {
+ return super.getModule();
+ }
+ module = commonParentModule;
+ }
+ return module;
+ }
+ }, project);
+
init();
}
+ private static String findCommonParentModule(String module1, String module2) {
+ int diff = indexOfFirstDifference(module1, module2);
+ if (diff == 0) {
+ return null;
+ }
+ if (diff == module1.length()) {
+ return module1;
+ }
+ if (module1.charAt(diff - 1) == '/') {
+ return module1.substring(0, diff);
+ }
+ else {
+ int index = module1.lastIndexOf('/', diff);
+ if (index < 0) {
+ return null;
+ }
+ return module1.substring(0, index);
+ }
+ }
+
+ private static int indexOfFirstDifference(@NotNull String a, @NotNull String b) {
+ int max = Math.min(a.length(), b.length());
+ for (int i = 0; i < max; i++) {
+ final char c = a.charAt(i);
+ if (c != b.charAt(i)) {
+ return i;
+ }
+ }
+ return max;
+ }
+
@Override
protected CheckoutWizard getWizard() {
return (CheckoutWizard)super.getWizard();
@@ -122,6 +195,7 @@ public class ChooseCheckoutMode extends WizardStep {
result.add(myMakeNewFilesReadOnly);
result.add(myPruneEmptyDirectories);
result.add(myChangeKeywordSubstitutionPanel.getComponent());
+ result.add(myDateOrRevisionOrTagSettings.getPanel());
return result;
}
@@ -155,6 +229,11 @@ public class ChooseCheckoutMode extends WizardStep {
else if (selectedLocation == null) {
getWizard().updateButtons();
}
+ final CvsRootConfiguration configuration = getWizard().getSelectedConfiguration();
+ if (myConfiguration != configuration) {
+ myDateOrRevisionOrTagSettings.updateFrom(configuration.DATE_OR_REVISION_SETTINGS);
+ myConfiguration = configuration;
+ }
}
private StringBuilder composeLocationsMessage() {
@@ -257,4 +336,8 @@ public class ChooseCheckoutMode extends WizardStep {
public KeywordSubstitution getKeywordSubstitution() {
return myChangeKeywordSubstitutionPanel.getKeywordSubstitution();
}
+
+ public void saveDateOrRevisionSettings(CvsRootConfiguration configuration) {
+ myDateOrRevisionOrTagSettings.saveTo(configuration.DATE_OR_REVISION_SETTINGS);
+ }
}
diff --git a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java
index f23542f30593..7837acc244f9 100644
--- a/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java
+++ b/plugins/cvs/javacvs-src/org/netbeans/lib/cvsclient/admin/Entries.java
@@ -13,9 +13,10 @@
package org.netbeans.lib.cvsclient.admin;
import com.intellij.openapi.util.io.FileUtil;
-import org.netbeans.lib.cvsclient.util.BugLog;
-import org.netbeans.lib.cvsclient.JavaCvsSrcBundle;
+import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
+import org.netbeans.lib.cvsclient.JavaCvsSrcBundle;
+import org.netbeans.lib.cvsclient.util.BugLog;
import java.io.*;
import java.util.*;
@@ -27,7 +28,7 @@ public final class Entries {
// Fields =================================================================
- private final Map<String, Entry> fileNameToEntryMap = new HashMap<String, Entry>();
+ private final Map<String, Entry> fileNameToEntryMap = new THashMap<String, Entry>();
@NonNls private static final String DIRECTORY_PREFIX = "D";
// Accessing ==============================================================
diff --git a/plugins/devkit/devkit.iml b/plugins/devkit/devkit.iml
index 72329902a0e5..62aa16567062 100644
--- a/plugins/devkit/devkit.iml
+++ b/plugins/devkit/devkit.iml
@@ -21,7 +21,7 @@
<orderEntry type="module" module-name="execution-impl" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="java-impl" />
- <orderEntry type="library" name="TestNG" level="project" />
+ <orderEntry type="library" scope="TEST" name="TestNG" level="project" />
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="properties" />
<orderEntry type="module" module-name="idea-ui" scope="TEST" />
diff --git a/plugins/devkit/src/dom/impl/I18nReferenceContributor.java b/plugins/devkit/src/dom/impl/I18nReferenceContributor.java
index 05301b5d4b1e..f88cdda1b212 100644
--- a/plugins/devkit/src/dom/impl/I18nReferenceContributor.java
+++ b/plugins/devkit/src/dom/impl/I18nReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -53,7 +53,7 @@ public class I18nReferenceContributor extends PsiReferenceContributor {
private static final String INTENTION_ACTION_BUNDLE_TAG = "bundleName";
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registerKeyProviders(registrar);
registerBundleNameProviders(registrar);
diff --git a/plugins/devkit/src/inspections/internal/FileEqualsUsageInspection.java b/plugins/devkit/src/inspections/internal/FileEqualsUsageInspection.java
index f066b1d0f7b8..b8cc8ae4cdd1 100644
--- a/plugins/devkit/src/inspections/internal/FileEqualsUsageInspection.java
+++ b/plugins/devkit/src/inspections/internal/FileEqualsUsageInspection.java
@@ -21,7 +21,7 @@ import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
public class FileEqualsUsageInspection extends InternalInspection {
- private static final String MESSAGE =
+ static final String MESSAGE =
"Do not use File.equals/hashCode/compareTo as they don't honor case-sensitivity on MacOS. " +
"Please use FileUtil.filesEquals/fileHashCode/compareFiles instead";
diff --git a/plugins/devkit/src/inspections/internal/UndesirableClassUsageInspection.java b/plugins/devkit/src/inspections/internal/UndesirableClassUsageInspection.java
index 8348b0e838c3..be3cc8d34cb3 100644
--- a/plugins/devkit/src/inspections/internal/UndesirableClassUsageInspection.java
+++ b/plugins/devkit/src/inspections/internal/UndesirableClassUsageInspection.java
@@ -26,7 +26,7 @@ import com.intellij.ui.components.JBTabbedPane;
import com.intellij.ui.table.JBTable;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.QueryExecutor;
-import gnu.trove.THashMap;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -34,17 +34,17 @@ import java.awt.image.BufferedImage;
import java.util.Map;
public class UndesirableClassUsageInspection extends InternalInspection {
- private static final Map<String, String> CLASSES = new THashMap<String, String>();
- static {
- CLASSES.put(JList.class.getName(), JBList.class.getName());
- CLASSES.put(JTable.class.getName(), JBTable.class.getName());
- CLASSES.put(JTree.class.getName(), Tree.class.getName());
- CLASSES.put(JScrollPane.class.getName(), JBScrollPane.class.getName());
- CLASSES.put(JTabbedPane.class.getName(), JBTabbedPane.class.getName());
- CLASSES.put(JComboBox.class.getName(), ComboBox.class.getName());
- CLASSES.put(QueryExecutor.class.getName(), QueryExecutorBase.class.getName());
- CLASSES.put(BufferedImage.class.getName(), "UIUtil.createImage()");
- }
+
+ private static final Map<String, String> CLASSES = ContainerUtil.<String, String>immutableMapBuilder()
+ .put(JList.class.getName(), JBList.class.getName())
+ .put(JTable.class.getName(), JBTable.class.getName())
+ .put(JTree.class.getName(), Tree.class.getName())
+ .put(JScrollPane.class.getName(), JBScrollPane.class.getName())
+ .put(JTabbedPane.class.getName(), JBTabbedPane.class.getName())
+ .put(JComboBox.class.getName(), ComboBox.class.getName())
+ .put(QueryExecutor.class.getName(), QueryExecutorBase.class.getName())
+ .put(BufferedImage.class.getName(), "UIUtil.createImage()")
+ .build();
@Override
@NotNull
diff --git a/plugins/devkit/src/inspections/quickfix/PluginDescriptorChooser.java b/plugins/devkit/src/inspections/quickfix/PluginDescriptorChooser.java
index e701055d07a2..7b4068b1145a 100644
--- a/plugins/devkit/src/inspections/quickfix/PluginDescriptorChooser.java
+++ b/plugins/devkit/src/inspections/quickfix/PluginDescriptorChooser.java
@@ -72,7 +72,7 @@ public class PluginDescriptorChooser {
List<DomFileElement<IdeaPlugin>> elements =
DomService.getInstance().getFileElements(IdeaPlugin.class,
project,
- module.getModuleContentWithDependenciesScope());
+ module.getModuleWithDependenciesScope());
elements = ContainerUtil.filter(elements, new Condition<DomFileElement<IdeaPlugin>>() {
@Override
diff --git a/plugins/devkit/src/module/PluginModuleBuilder.java b/plugins/devkit/src/module/PluginModuleBuilder.java
index bf6daf190c84..155fecffabb6 100644
--- a/plugins/devkit/src/module/PluginModuleBuilder.java
+++ b/plugins/devkit/src/module/PluginModuleBuilder.java
@@ -15,21 +15,27 @@
*/
package org.jetbrains.idea.devkit.module;
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.SettingsStep;
-import com.intellij.openapi.module.JavaModuleType;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleType;
-import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.devkit.DevKitBundle;
import org.jetbrains.idea.devkit.build.PluginBuildConfiguration;
import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
+import org.jetbrains.idea.devkit.run.PluginConfigurationType;
public class PluginModuleBuilder extends JavaModuleBuilder{
@NonNls private static final String META_INF = "META-INF";
@@ -44,16 +50,36 @@ public class PluginModuleBuilder extends JavaModuleBuilder{
super.setupRootModel(rootModel);
final String defaultPluginXMLLocation = getModuleFileDirectory() + '/' + META_INF + '/' + PLUGIN_XML;
final Module module = rootModel.getModule();
- StartupManager.getInstance(module.getProject()).runWhenProjectIsInitialized(new Runnable() {
+ final Project project = module.getProject();
+ StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
public void run() {
final PluginBuildConfiguration buildConfiguration = PluginBuildConfiguration.getInstance(module);
if (buildConfiguration != null) {
buildConfiguration.setPluginXmlPathAndCreateDescriptorIfDoesntExist(defaultPluginXMLLocation);
}
+
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(defaultPluginXMLLocation);
+ if (file != null) {
+ FileEditorManager.getInstance(project).openFile(file, true);
+ }
}
});
}
+ @Nullable
+ @Override
+ public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) {
+ Module module = super.commitModule(project, model);
+ if (module != null) {
+ RunManager runManager = RunManager.getInstance(project);
+ RunnerAndConfigurationSettings configuration =
+ runManager.createRunConfiguration(DevKitBundle.message("run.configuration.title"), new PluginConfigurationType().getConfigurationFactories()[0]);
+ runManager.addConfiguration(configuration, false);
+ runManager.setSelectedConfiguration(configuration);
+ }
+ return module;
+ }
+
@Override
public boolean isSuitableSdkType(SdkTypeId sdk) {
return sdk == IdeaJdk.getInstance();
diff --git a/plugins/devkit/src/projectRoots/IdeaJdk.java b/plugins/devkit/src/projectRoots/IdeaJdk.java
index df65b363a1e5..1539a893dbad 100644
--- a/plugins/devkit/src/projectRoots/IdeaJdk.java
+++ b/plugins/devkit/src/projectRoots/IdeaJdk.java
@@ -27,14 +27,12 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.ZipFileCache;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.cls.BytePointer;
-import com.intellij.util.cls.ClsFormatException;
-import com.intellij.util.cls.ClsUtil;
import icons.DevkitIcons;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -43,16 +41,19 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.DevKitBundle;
import javax.swing.*;
+import java.io.DataInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
/**
- * User: anna
- * Date: Nov 22, 2004
+ * @author anna
+ * @since Nov 22, 2004
*/
public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
private static final Icon ADD_SDK = DevkitIcons.Add_sdk;
@@ -176,7 +177,7 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
appendIdeaLibrary(home, result, "junit.jar");
appendIdeaLibrary(plugins + "JavaEE", result, "javaee-impl.jar", "jpa-console.jar");
appendIdeaLibrary(plugins + "PersistenceSupport", result, "persistence-impl.jar");
- appendIdeaLibrary(plugins + "DatabaseSupport", result, "database-impl.jar", "jdbc-console.jar");
+ appendIdeaLibrary(plugins + "DatabaseTools", result, "database-impl.jar", "jdbc-console.jar");
appendIdeaLibrary(plugins + "css", result, "css.jar");
appendIdeaLibrary(plugins + "uml", result, "uml-support.jar");
appendIdeaLibrary(plugins + "Spring", result,
@@ -262,26 +263,33 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
return false;
}
- private static int getIdeaClassFileVersion(final Sdk ideaSdk) {
- int result = -1;
- File apiJar = getOpenApiJar(ideaSdk.getHomePath());
- if (apiJar == null) return -1;
- final VirtualFile mainClassFile = JarFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(apiJar.getPath()) +
- "!/com/intellij/psi/PsiManager.class");
- if (mainClassFile != null) {
- final BytePointer ptr;
- try {
- ptr = new BytePointer(mainClassFile.contentsToByteArray(), 6);
- result = ClsUtil.readU2(ptr);
- }
- catch (IOException e) {
- // ignore
- }
- catch (ClsFormatException e) {
- // ignore
+ private static int getIdeaClassFileVersion(Sdk ideaSdk) {
+ try {
+ File apiJar = getOpenApiJar(ideaSdk.getHomePath());
+ if (apiJar != null) {
+ ZipFile zipFile = ZipFileCache.acquire(apiJar.getPath());
+ try {
+ ZipEntry entry = zipFile.getEntry("com/intellij/psi/PsiManager.class");
+ if (entry != null) {
+ DataInputStream stream = new DataInputStream(zipFile.getInputStream(entry));
+ try {
+ if (stream.skip(6) == 6) {
+ return stream.readUnsignedShort();
+ }
+ }
+ finally {
+ stream.close();
+ }
+ }
+ }
+ finally {
+ ZipFileCache.release(zipFile);
+ }
}
}
- return result;
+ catch (IOException ignored) { }
+
+ return -1;
}
@Nullable
diff --git a/plugins/devkit/src/references/IconsReferencesContributor.java b/plugins/devkit/src/references/IconsReferencesContributor.java
index eac85d8f0f3c..a7a903555717 100644
--- a/plugins/devkit/src/references/IconsReferencesContributor.java
+++ b/plugins/devkit/src/references/IconsReferencesContributor.java
@@ -60,7 +60,7 @@ import static com.intellij.patterns.PsiJavaPatterns.*;
*/
public class IconsReferencesContributor extends PsiReferenceContributor implements QueryExecutor<PsiReference, ReferencesSearch.SearchParameters> {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
final StringPattern methodName = string().oneOf("findIcon", "getIcon");
final PsiMethodPattern method = psiMethod().withName(methodName).definedInClass(IconLoader.class.getName());
final PsiJavaElementPattern.Capture<PsiLiteralExpression> javaFile
diff --git a/plugins/devkit/src/run/PluginConfigurationType.java b/plugins/devkit/src/run/PluginConfigurationType.java
index cb25590b4ce1..9c0d01e0ece7 100644
--- a/plugins/devkit/src/run/PluginConfigurationType.java
+++ b/plugins/devkit/src/run/PluginConfigurationType.java
@@ -39,7 +39,7 @@ public class PluginConfigurationType implements ConfigurationType {
private final ConfigurationFactory myFactory;
private String myVmParameters;
- PluginConfigurationType() {
+ public PluginConfigurationType() {
myFactory = new ConfigurationFactory(this) {
public RunConfiguration createTemplateConfiguration(Project project) {
final PluginRunConfiguration runConfiguration = new PluginRunConfiguration(project, this, "");
diff --git a/plugins/devkit/src/run/PluginRunConfiguration.java b/plugins/devkit/src/run/PluginRunConfiguration.java
index 51eb8f5091ea..ed0764c5581c 100644
--- a/plugins/devkit/src/run/PluginRunConfiguration.java
+++ b/plugins/devkit/src/run/PluginRunConfiguration.java
@@ -168,6 +168,9 @@ public class PluginRunConfiguration extends RunConfigurationBase implements Modu
else if (buildNumber.startsWith("CP")) {
prefix = PlatformUtils.CPP_PREFIX;
}
+ else if (buildNumber.startsWith("DB")) {
+ prefix = PlatformUtils.DBE_PREFIX;
+ }
if (prefix != null) {
vm.defineProperty(PlatformUtils.PLATFORM_PREFIX_KEY, prefix);
diff --git a/plugins/devkit/src/run/PluginRunConfigurationEditor.java b/plugins/devkit/src/run/PluginRunConfigurationEditor.java
index a5165334b1df..f65bd28a8fc4 100644
--- a/plugins/devkit/src/run/PluginRunConfigurationEditor.java
+++ b/plugins/devkit/src/run/PluginRunConfigurationEditor.java
@@ -24,7 +24,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.ui.configuration.ModulesCombobox;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.RawCommandLineEditor;
@@ -49,7 +49,7 @@ import java.io.IOException;
import java.util.ArrayList;
public class PluginRunConfigurationEditor extends SettingsEditor<PluginRunConfiguration> implements PanelWithAnchor {
- private final ModulesCombobox myModules = new ModulesCombobox();
+ private final ModulesComboBox myModules = new ModulesComboBox();
private final JBLabel myModuleLabel = new JBLabel(ExecutionBundle.message("application.configuration.use.classpath.and.jdk.of.module.label"));
private final LabeledComponent<RawCommandLineEditor> myVMParameters = new LabeledComponent<RawCommandLineEditor>();
private final LabeledComponent<RawCommandLineEditor> myProgramParameters = new LabeledComponent<RawCommandLineEditor>();
diff --git a/plugins/devkit/src/testAssistant/TestDataGuessByExistingFilesUtil.java b/plugins/devkit/src/testAssistant/TestDataGuessByExistingFilesUtil.java
index 770e8e89c83f..e37fb720c25a 100644
--- a/plugins/devkit/src/testAssistant/TestDataGuessByExistingFilesUtil.java
+++ b/plugins/devkit/src/testAssistant/TestDataGuessByExistingFilesUtil.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.jetbrains.idea.devkit.testAssistant;
import com.intellij.codeInsight.AnnotationUtil;
@@ -130,7 +145,7 @@ public class TestDataGuessByExistingFilesUtil {
@NotNull
public static String getTestName(@NotNull String methodName) {
- return methodName.startsWith("test") ? methodName.substring("test".length()) : methodName;
+ return StringUtil.trimStart(methodName, "test");
}
@Nullable
diff --git a/plugins/devkit/src/testAssistant/TestDataLineMarkerProvider.java b/plugins/devkit/src/testAssistant/TestDataLineMarkerProvider.java
index 916e38c9f876..73f0ae40d4a2 100644
--- a/plugins/devkit/src/testAssistant/TestDataLineMarkerProvider.java
+++ b/plugins/devkit/src/testAssistant/TestDataLineMarkerProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +30,7 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.util.Function;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -62,13 +63,16 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
return new LineMarkerInfo<PsiMethod>(
method, method.getModifierList().getTextRange(), PlatformIcons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL, null, new TestDataNavigationHandler(),
GutterIconRenderer.Alignment.LEFT);
- }
+ }
} else if (element instanceof PsiClass) {
final PsiClass psiClass = (PsiClass)element;
final String basePath = getTestDataBasePath(psiClass);
if (basePath != null) {
+ PsiModifierList modifierList = psiClass.getModifierList();
+ assert modifierList != null;
return new LineMarkerInfo<PsiClass>(
- psiClass, psiClass.getModifierList().getTextRange(), PlatformIcons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL, null, new GutterIconNavigationHandler<PsiClass>() {
+ psiClass, modifierList.getTextRange(), PlatformIcons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL,
+ new TooltipProvider(basePath), new GutterIconNavigationHandler<PsiClass>() {
@Override
public void navigate(MouseEvent e, PsiClass elt) {
final VirtualFile baseDir = VfsUtil.findFileByIoFile(new File(basePath), true);
@@ -76,7 +80,7 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
new OpenFileDescriptor(psiClass.getProject(), baseDir).navigate(true);
}
}
- },
+ },
GutterIconRenderer.Alignment.LEFT);
}
}
@@ -101,7 +105,7 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
if (testDataPath == null) {
return false;
}
- List<String> fileNames = new TestDataReferenceCollector(testDataPath, name.substring(4)).collectTestDataReferences(method);
+ List<String> fileNames = new TestDataReferenceCollector(testDataPath, TestDataGuessByExistingFilesUtil.getTestName(name)).collectTestDataReferences(method);
return fileNames != null && !fileNames.isEmpty();
}
@@ -144,4 +148,33 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
return null;
}
+ private static class TooltipProvider implements Function<PsiClass, String> {
+ @NotNull private final String myBasePath;
+
+ public TooltipProvider(@NotNull String basePath) {
+ myBasePath = basePath;
+ }
+
+ @Override
+ public String fun(PsiClass aClass) {
+ return myBasePath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof TooltipProvider)) return false;
+
+ TooltipProvider provider = (TooltipProvider)o;
+
+ if (!myBasePath.equals(provider.myBasePath)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myBasePath.hashCode();
+ }
+ }
}
diff --git a/plugins/devkit/src/testAssistant/TestDataReferenceContributor.java b/plugins/devkit/src/testAssistant/TestDataReferenceContributor.java
index de3d4a446bb1..f0cc660dcc8a 100644
--- a/plugins/devkit/src/testAssistant/TestDataReferenceContributor.java
+++ b/plugins/devkit/src/testAssistant/TestDataReferenceContributor.java
@@ -44,7 +44,7 @@ import static org.jetbrains.idea.devkit.testAssistant.TestDataLineMarkerProvider
*/
public class TestDataReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(literalExpression().annotationParam(TEST_DATA_PATH_ANNOTATION_QUALIFIED_NAME),
new TestDataReferenceProvider());
}
diff --git a/plugins/devkit/testSources/PluginProjectWizardTest.java b/plugins/devkit/testSources/PluginProjectWizardTest.java
index 1b6dd25aacbd..99ba3f4cbb9c 100644
--- a/plugins/devkit/testSources/PluginProjectWizardTest.java
+++ b/plugins/devkit/testSources/PluginProjectWizardTest.java
@@ -15,8 +15,12 @@
*/
package org.jetbrains.idea.devkit;
+import com.intellij.execution.RunManager;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.projectWizard.NewProjectWizardTestCase;
+import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -34,6 +38,15 @@ public class PluginProjectWizardTest extends NewProjectWizardTestCase {
VirtualFile baseDir = project.getBaseDir();
VirtualFile virtualFile = VfsUtilCore.findRelativeFile("META-INF/plugin.xml", baseDir);
assertNotNull(virtualFile);
+
+ RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
+ assertNotNull(configuration);
+ ConfigurationType type = configuration.getType();
+ assertNotNull(type);
+ assertEquals(DevKitBundle.message("run.configuration.title"), type.getDisplayName());
+
+ VirtualFile[] files = FileEditorManager.getInstance(project).getOpenFiles();
+ assertEquals(1, files.length);
}
public void testProjectWithoutSdk() throws Exception {
diff --git a/plugins/devkit/testSources/inspections/internal/FileEqualsUsageInspectionTest.java b/plugins/devkit/testSources/inspections/internal/FileEqualsUsageInspectionTest.java
new file mode 100644
index 000000000000..dda60062e900
--- /dev/null
+++ b/plugins/devkit/testSources/inspections/internal/FileEqualsUsageInspectionTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.inspections.internal;
+
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.idea.devkit.inspections.PluginModuleTestCase;
+
+public class FileEqualsUsageInspectionTest extends PluginModuleTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ myFixture.enableInspections(new FileEqualsUsageInspection());
+ }
+
+ public void testEquals() {
+ doTest("equals(null)", true);
+ }
+
+ public void testCompareTo() {
+ doTest("compareTo(null)", true);
+ }
+
+ public void testHashCode() {
+ doTest("hashCode()", true);
+ }
+
+ public void testGetName() {
+ doTest("getName()", false);
+ }
+
+ private void doTest(String methodExpressionText, boolean highlightError) {
+ String expectedMethodExpression;
+ if (highlightError) {
+ String methodName = StringUtil.substringBefore(methodExpressionText, "(");
+ String methodParams = StringUtil.substringAfter(methodExpressionText, methodName);
+ expectedMethodExpression = "<warning descr=\"" + FileEqualsUsageInspection.MESSAGE + "\">" +
+ methodName +
+ "</warning>" +
+ methodParams;
+ }
+ else {
+ expectedMethodExpression = methodExpressionText;
+ }
+
+ myFixture.configureByText("Testing.java",
+ "public class Testing {" +
+ " public void method() {" +
+ " java.io.File file = null;" +
+ " file." + expectedMethodExpression + ";" +
+ " }" +
+ "}");
+ myFixture.testHighlighting();
+ }
+} \ No newline at end of file
diff --git a/plugins/devkit/testSources/inspections/internal/UndesirableClassUsageInspectionTest.java b/plugins/devkit/testSources/inspections/internal/UndesirableClassUsageInspectionTest.java
new file mode 100644
index 000000000000..80aaccbc5bc0
--- /dev/null
+++ b/plugins/devkit/testSources/inspections/internal/UndesirableClassUsageInspectionTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.inspections.internal;
+
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.idea.devkit.inspections.PluginModuleTestCase;
+
+public class UndesirableClassUsageInspectionTest extends PluginModuleTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ myFixture.enableInspections(new UndesirableClassUsageInspection());
+ }
+
+ public void testUsages() {
+ doTest("javax.swing.JList", "com.intellij.ui.components.JBList");
+ doTest("javax.swing.JTable", "com.intellij.ui.table.JBTable");
+ doTest("javax.swing.JTree", "com.intellij.ui.treeStructure.Tree");
+ doTest("javax.swing.JScrollPane", "com.intellij.ui.components.JBScrollPane");
+ doTest("javax.swing.JTabbedPane", "com.intellij.ui.components.JBTabbedPane");
+ doTest("javax.swing.JComboBox", "com.intellij.openapi.ui.ComboBox");
+ doTest("com.intellij.util.QueryExecutor", "com.intellij.openapi.application.QueryExecutorBase");
+ doTest("java.awt.image.BufferedImage", "UIUtil.createImage()");
+ }
+
+ private void doTest(String classFqn, String replacementText) {
+ myFixture.addClass("package " + StringUtil.getPackageName(classFqn) + ";" +
+ "public class " + StringUtil.getShortName(classFqn) + " {}");
+
+ myFixture.configureByText("Testing.java",
+ "public class Testing {" +
+ " public void method() {" +
+ "<warning descr=\"Please use '" + replacementText + "' instead\">" +
+ "new " + classFqn + "()" +
+ "</warning>;" +
+ " }" +
+ "}");
+ myFixture.testHighlighting();
+ }
+} \ No newline at end of file
diff --git a/plugins/devkit/testSources/inspections/internal/UseVirtualFileEqualsInspectionTest.java b/plugins/devkit/testSources/inspections/internal/UseVirtualFileEqualsInspectionTest.java
new file mode 100644
index 000000000000..e64ac3e17d75
--- /dev/null
+++ b/plugins/devkit/testSources/inspections/internal/UseVirtualFileEqualsInspectionTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.devkit.inspections.internal;
+
+import org.jetbrains.idea.devkit.inspections.PluginModuleTestCase;
+
+public class UseVirtualFileEqualsInspectionTest extends PluginModuleTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ myFixture.addClass("package com.intellij.openapi.vfs; public class VirtualFile {}");
+ myFixture.enableInspections(new UseVirtualFileEqualsInspection());
+ }
+
+ public void testNulls() {
+ doTest("vf1 == null");
+ doTest("null == vf1");
+ }
+
+ public void testThis() {
+ doTest("this == this");
+ doTest("getTesting() == this");
+ }
+
+ public void testVirtualFile() {
+ doTest("<warning descr=\"VirtualFile objects should be compared by equals(), not ==\">vf1 != vf2</warning>");
+ doTest("<warning descr=\"VirtualFile objects should be compared by equals(), not ==\">vf1 == vf2</warning>");
+ }
+
+ private void doTest(String expression) {
+ myFixture.configureByText("Testing.java",
+ "import com.intellij.openapi.vfs.VirtualFile;" +
+ "public class Testing {" +
+ " public void method() {" +
+ " VirtualFile vf1 = null;" +
+ " VirtualFile vf2 = null;" +
+ " if (" + expression + ") {}" +
+ " }" +
+ " public Testing getTesting() { return null; }" +
+ "}");
+ myFixture.testHighlighting();
+ }
+} \ No newline at end of file
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileType.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileType.java
index b4d8cd06a9c6..ad0677d26560 100644
--- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileType.java
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileType.java
@@ -31,6 +31,9 @@ import javax.swing.*;
* Author: Vladislav.Kaznacheev
*/
public class EclipseFileType implements FileType {
+
+ public static final FileType INSTANCE = new EclipseFileType();
+
@NotNull
@NonNls
public String getName() {
diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileTypeFactory.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileTypeFactory.java
index 77e64e6dc3b5..8d9c4a8245bf 100644
--- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileTypeFactory.java
+++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseFileTypeFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,7 +15,6 @@
*/
package org.jetbrains.idea.eclipse.config;
-import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeConsumer;
import com.intellij.openapi.fileTypes.FileTypeFactory;
import org.jetbrains.annotations.NotNull;
@@ -25,9 +24,8 @@ import org.jetbrains.idea.eclipse.EclipseXml;
* Author: Vladislav.Kaznacheev
*/
public class EclipseFileTypeFactory extends FileTypeFactory {
- private final static FileType fileType = new EclipseFileType();
public void createFileTypes(final @NotNull FileTypeConsumer consumer) {
- consumer.consume(fileType, EclipseXml.CLASSPATH_EXT + ";" + EclipseXml.PROJECT_EXT);
+ consumer.consume(EclipseFileType.INSTANCE, EclipseXml.CLASSPATH_EXT + ";" + EclipseXml.PROJECT_EXT);
}
}
diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImportWizardTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImportWizardTest.java
index bbf0d4acfa67..f46eb8b1da21 100644
--- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImportWizardTest.java
+++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImportWizardTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -62,7 +62,9 @@ public class EclipseImportWizardTest extends ProjectWizardTestCase {
}
public void testImportingFromTwoProviders() throws Exception {
- File file = createTempFile("Foo.java", "class Foo {}");
+ File dir = createTempDirectory();
+ File file = new File(dir, "Foo.java");
+ FileUtil.writeToFile(file, "class Foo {}");
Module module = importProjectFrom(file.getParent(), null, new ImportFromSourcesProvider(),
new EclipseProjectImportProvider(new EclipseImportBuilder()));
VirtualFile[] sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots();
diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java
index 7fe517d51d04..46efd1944d93 100644
--- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java
+++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/inspection/ClassHasNoToStringMethodInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2013 the original author or authors.
+ * Copyright 2001-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,14 @@ package org.jetbrains.generate.tostring.inspection;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.ui.RegExFormatter;
+import com.intellij.codeInspection.ui.RegExInputVerifier;
+import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.ui.DocumentAdapter;
import com.intellij.util.ui.CheckBox;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.GenerateToStringContext;
import org.jetbrains.generate.tostring.GenerateToStringUtils;
@@ -31,6 +36,8 @@ import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import java.awt.*;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
/**
* Inspection to check if the current class overrides the toString() method.
@@ -42,6 +49,8 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti
/** User options for classes to exclude. Must be a regexp pattern */
public String excludeClassNames = ""; // must be public for JDOMSerialization
+ private Pattern excludeClassNamesPattern;
+
/** User options for excluded exception classes */
public boolean excludeException = true; // must be public for JDOMSerialization
/** User options for excluded deprecated classes */
@@ -55,7 +64,14 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti
public boolean excludeInnerClasses = false;
- @Override
+ public ClassHasNoToStringMethodInspection() {
+ try {
+ excludeClassNamesPattern = Pattern.compile(excludeClassNames);
+ } catch (PatternSyntaxException e) {
+ }
+ }
+
+ @Override
@NotNull
public String getDisplayName() {
return "Class does not override 'toString()' method";
@@ -101,11 +117,13 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti
}
// if it is an excluded class - then skip
- if (StringUtil.isNotEmpty(excludeClassNames)) {
- String name = clazz.getName();
- if (name != null && name.matches(excludeClassNames)) {
- return;
- }
+ if (excludeClassNamesPattern != null) {
+ try {
+ String name = clazz.getName();
+ if (name != null && excludeClassNamesPattern.matcher(name).matches()) {
+ return;
+ }
+ } catch (PatternSyntaxException ignore) {}
}
// must have fields
@@ -170,27 +188,23 @@ public class ClassHasNoToStringMethodInspection extends AbstractToStringInspecti
constraints.fill = GridBagConstraints.NONE;
panel.add(new JLabel("Exclude classes (reg exp):"), constraints);
- final JTextField excludeClassNamesField = new JTextField(excludeClassNames, 40);
- excludeClassNamesField.setMinimumSize(new Dimension(140, 20));
+ final JFormattedTextField excludeClassNamesField = new JFormattedTextField(new RegExFormatter());
+ excludeClassNamesField.setValue(excludeClassNamesPattern);
+ excludeClassNamesField.setColumns(25);
+ excludeClassNamesField.setInputVerifier(new RegExInputVerifier());
+ excludeClassNamesField.setFocusLostBehavior(JFormattedTextField.COMMIT);
+ excludeClassNamesField.setMinimumSize(excludeClassNamesField.getPreferredSize());
+ UIUtil.fixFormattedField(excludeClassNamesField);
Document document = excludeClassNamesField.getDocument();
- document.addDocumentListener(new DocumentListener() {
- @Override
- public void changedUpdate(DocumentEvent e) {
- textChanged();
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- textChanged();
- }
+ document.addDocumentListener(new DocumentAdapter() {
@Override
- public void removeUpdate(DocumentEvent e) {
- textChanged();
- }
-
- private void textChanged() {
- excludeClassNames = excludeClassNamesField.getText();
+ protected void textChanged(DocumentEvent e) {
+ try {
+ excludeClassNamesField.commitEdit();
+ excludeClassNamesPattern = (Pattern)excludeClassNamesField.getValue();
+ excludeClassNames = excludeClassNamesPattern.pattern();
+ } catch (final Exception ignore) {}
}
});
constraints.gridx = 1;
diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java
index 2a6d2752677f..a886f29c84f1 100644
--- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java
+++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/psi/PsiAdapter.java
@@ -15,7 +15,6 @@
*/
package org.jetbrains.generate.tostring.psi;
-import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -31,6 +30,8 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
+import static com.intellij.psi.CommonClassNames.*;
+
/**
* Basic PSI Adapter with common function that works in all supported versions of IDEA.
*/
@@ -169,7 +170,7 @@ public class PsiAdapter {
* @return true if it's a String type.
*/
public static boolean isStringType(PsiElementFactory factory, PsiType type) {
- return isTypeOf(factory, type, "java.lang.String");
+ return isTypeOf(factory, type, JAVA_LANG_STRING);
}
/**
@@ -180,7 +181,7 @@ public class PsiAdapter {
* @return true if it's an Object type.
*/
public static boolean isObjectType(PsiElementFactory factory, PsiType type) {
- return isTypeOf(factory, type, CommonClassNames.JAVA_LANG_OBJECT);
+ return isTypeOf(factory, type, JAVA_LANG_OBJECT);
}
/**
@@ -219,7 +220,7 @@ public class PsiAdapter {
return "boolean".equals(s);
} else {
// test for Object type of Boolean
- return isTypeOf(factory, type, "java.lang.Boolean");
+ return isTypeOf(factory, type, JAVA_LANG_BOOLEAN);
}
}
@@ -554,7 +555,7 @@ public class PsiAdapter {
}
// parameter must be Object
- if (!(parameters[0].getType().getCanonicalText().equals(CommonClassNames.JAVA_LANG_OBJECT))) {
+ if (!(parameters[0].getType().getCanonicalText().equals(JAVA_LANG_OBJECT))) {
continue;
}
diff --git a/plugins/git4idea/git4idea.iml b/plugins/git4idea/git4idea.iml
index 75efba73b775..1b6091a77419 100644
--- a/plugins/git4idea/git4idea.iml
+++ b/plugins/git4idea/git4idea.iml
@@ -48,17 +48,6 @@
</SOURCES>
</library>
</orderEntry>
- <orderEntry type="module-library">
- <library name="jgit-2.1.0">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r_source.zip!/" />
- </SOURCES>
- </library>
- </orderEntry>
<orderEntry type="library" scope="TEST" name="Groovy" level="project" />
<orderEntry type="module" module-name="dvcs" exported="" />
<orderEntry type="library" scope="TEST" name="cucumber-jvm" level="project" />
diff --git a/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r.jar b/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r.jar
deleted file mode 100644
index 2257a22a8fb6..000000000000
--- a/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r_source.zip b/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r_source.zip
deleted file mode 100644
index 78cb17ebe989..000000000000
--- a/plugins/git4idea/lib/jgit/org.eclipse.jgit-2.1.0.201209190230-r_source.zip
+++ /dev/null
Binary files differ
diff --git a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java
index 43a1c6cbe349..874360a86c5b 100644
--- a/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java
+++ b/plugins/git4idea/remote-servers-git/src/com/intellij/remoteServer/util/CloudGitDeploymentRuntime.java
@@ -5,14 +5,13 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.*;
+import com.intellij.openapi.vcs.changes.ui.CommitChangeListDialog;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -30,12 +29,15 @@ import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import git4idea.util.GitFileUtils;
+import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -48,9 +50,79 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
private static final String COMMIT_MESSAGE = "Deploy";
+ private static final CommitSession NO_COMMIT = new CommitSession() {
+
+ @Nullable
+ @Override
+ public JComponent getAdditionalConfigurationUI() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public JComponent getAdditionalConfigurationUI(Collection<Change> changes, String commitMessage) {
+ return null;
+ }
+
+ @Override
+ public boolean canExecute(Collection<Change> changes, String commitMessage) {
+ return true;
+ }
+
+ @Override
+ public void execute(Collection<Change> changes, String commitMessage) {
+
+ }
+
+ @Override
+ public void executionCanceled() {
+
+ }
+
+ @Override
+ public String getHelpId() {
+ return null;
+ }
+ };
+
+ private static final List<CommitExecutor> ourCommitExecutors = Arrays.asList(
+ new CommitExecutor() {
+
+ @Nls
+ @Override
+ public String getActionText() {
+ return "Commit and Push";
+ }
+
+ @NotNull
+ @Override
+ public CommitSession createCommitSession() {
+ return CommitSession.VCS_COMMIT;
+ }
+ },
+ new CommitExecutorBase() {
+
+ @Nls
+ @Override
+ public String getActionText() {
+ return "Push without Commit";
+ }
+
+ @NotNull
+ @Override
+ public CommitSession createCommitSession() {
+ return NO_COMMIT;
+ }
+
+ @Override
+ public boolean areChangesRequired() {
+ return false;
+ }
+ }
+ );
+
private final GitRepositoryManager myGitRepositoryManager;
private final Git myGit;
- private final AbstractVcsHelper myVcsHelper;
private final VirtualFile myContentRoot;
private final File myRepositoryRootFile;
@@ -87,7 +159,6 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
throw new ServerRuntimeException("Can't initialize GIT");
}
GitPlatformFacade gitPlatformFacade = ServiceManager.getService(GitPlatformFacade.class);
- myVcsHelper = gitPlatformFacade.getVcsHelper(project);
myChangeListManager = gitPlatformFacade.getChangeListManager(project);
}
@@ -124,32 +195,6 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
relevantChanges.add(change);
}
}
- if (relevantChanges.isEmpty()) {
- Integer showCommitDialogChoice = runOnEdt(new Computable<Integer>() {
-
- @Override
- public Integer compute() {
- return Messages.showYesNoCancelDialog(getProject(),
- "Active changelist does not contain a relevant change.\n"
- + "Do you want to show commit dialog anyway?\n\n"
- + "Yes - show commit dialog\n"
- + "No - push immediately\n"
- + "Cancel - interrupt deploy",
- "Deploy",
- Messages.getWarningIcon());
- }
- });
- if (showCommitDialogChoice == Messages.YES) {
- relevantChanges.addAll(changes);
- }
- else if (showCommitDialogChoice == Messages.NO) {
- pushApplication(application);
- return;
- }
- else {
- throw new ServerRuntimeException("Deploy interrupted");
- }
- }
final Semaphore commitSemaphore = new Semaphore();
commitSemaphore.down();
@@ -159,20 +204,26 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
@Override
public Boolean compute() {
- return myVcsHelper.commitChanges(relevantChanges, activeChangeList, COMMIT_MESSAGE,
- new CommitResultHandler() {
-
- @Override
- public void onSuccess(@NotNull String commitMessage) {
- commitSucceeded.set(true);
- commitSemaphore.up();
- }
-
- @Override
- public void onFailure() {
- commitSemaphore.up();
- }
- });
+ return CommitChangeListDialog.commitChanges(getProject(),
+ relevantChanges,
+ activeChangeList,
+ ourCommitExecutors,
+ false,
+ COMMIT_MESSAGE,
+ new CommitResultHandler() {
+
+ @Override
+ public void onSuccess(@NotNull String commitMessage) {
+ commitSucceeded.set(true);
+ commitSemaphore.up();
+ }
+
+ @Override
+ public void onFailure() {
+ commitSemaphore.up();
+ }
+ },
+ false);
}
});
if (commitStarted != null && commitStarted) {
@@ -183,7 +234,7 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
}
}
else {
- getLoggingHandler().println("Commit canceled");
+ throw new ServerRuntimeException("Deploy interrupted");
}
repository.update();
@@ -211,17 +262,6 @@ public class CloudGitDeploymentRuntime extends CloudDeploymentRuntime {
return result.get();
}
- public void undeploy() throws ServerRuntimeException {
- getAgentTaskExecutor().execute(new Computable<Object>() {
-
- @Override
- public Object compute() {
- getDeployment().deleteApplication();
- return null;
- }
- });
- }
-
public boolean isDeployed() throws ServerRuntimeException {
return findApplication() != null;
}
diff --git a/plugins/git4idea/src/META-INF/plugin.xml b/plugins/git4idea/src/META-INF/plugin.xml
index 80fa47fa1a86..32d254f6fb67 100644
--- a/plugins/git4idea/src/META-INF/plugin.xml
+++ b/plugins/git4idea/src/META-INF/plugin.xml
@@ -209,6 +209,6 @@
</extensions>
<extensionPoints>
- <extensionPoint qualifiedName="Git4Idea.GitHttpAuthDataProvider" interface="git4idea.jgit.GitHttpAuthDataProvider"/>
+ <extensionPoint qualifiedName="Git4Idea.GitHttpAuthDataProvider" interface="git4idea.remote.GitHttpAuthDataProvider"/>
</extensionPoints>
</idea-plugin>
diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java
index 7204f61aa0ab..4286aee1536b 100644
--- a/plugins/git4idea/src/git4idea/GitUtil.java
+++ b/plugins/git4idea/src/git4idea/GitUtil.java
@@ -23,6 +23,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.ex.MultiLineLabel;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -30,6 +32,9 @@ import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangeListManager;
+import com.intellij.openapi.vcs.changes.ChangeListManagerEx;
import com.intellij.openapi.vcs.changes.FilePathsHelper;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vcs.vfs.AbstractVcsVirtualFile;
@@ -37,6 +42,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcsUtil.VcsFileUtil;
import com.intellij.vcsUtil.VcsUtil;
@@ -50,6 +56,7 @@ import git4idea.repo.GitBranchTrackInfo;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
+import git4idea.util.GitSimplePathsBrowser;
import git4idea.util.GitUIUtil;
import git4idea.util.StringScanner;
import org.jetbrains.annotations.NotNull;
@@ -934,4 +941,73 @@ public class GitUtil {
return !output.trim().isEmpty();
}
+ @Nullable
+ public static VirtualFile findRefreshFileOrLog(@NotNull String absolutePath) {
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(absolutePath);
+ if (file == null) {
+ file = LocalFileSystem.getInstance().refreshAndFindFileByPath(absolutePath);
+ }
+ if (file == null) {
+ LOG.warn("VirtualFile not found for " + absolutePath);
+ }
+ return file;
+ }
+
+ @NotNull
+ public static String toAbsolute(@NotNull VirtualFile root, @NotNull String relativePath) {
+ return StringUtil.trimEnd(root.getPath(), "/") + "/" + StringUtil.trimStart(relativePath, "/");
+ }
+
+ @NotNull
+ public static Collection<String> toAbsolute(@NotNull final VirtualFile root, @NotNull Collection<String> relativePaths) {
+ return ContainerUtil.map(relativePaths, new Function<String, String>() {
+ @Override
+ public String fun(String s) {
+ return toAbsolute(root, s);
+ }
+ });
+ }
+
+ /**
+ * Given the list of paths converts them to the list of {@link Change Changes} found in the {@link ChangeListManager},
+ * i.e. this works only for local changes. </br>
+ * Paths can be absolute or relative to the repository.
+ * If a path is not found in the local changes, it is ignored, but the fact is logged.
+ */
+ @NotNull
+ public static List<Change> findLocalChangesForPaths(@NotNull Project project, @NotNull VirtualFile root,
+ @NotNull Collection<String> affectedPaths, boolean relativePaths) {
+ ChangeListManagerEx changeListManager = (ChangeListManagerEx)ChangeListManager.getInstance(project);
+ List<Change> affectedChanges = new ArrayList<Change>();
+ for (String path : affectedPaths) {
+ String absolutePath = relativePaths ? toAbsolute(root, path) : path;
+ VirtualFile file = findRefreshFileOrLog(absolutePath);
+ if (file != null) {
+ Change change = changeListManager.getChange(file);
+ if (change != null) {
+ affectedChanges.add(change);
+ }
+ else {
+ String message = "Change is not found for " + file.getPath();
+ if (changeListManager.isInUpdate()) {
+ message += " because ChangeListManager is being updated.";
+ }
+ LOG.warn(message);
+ }
+ }
+ }
+ return affectedChanges;
+ }
+
+ public static void showPathsInDialog(@NotNull Project project, @NotNull Collection<String> absolutePaths, @NotNull String title,
+ @Nullable String description) {
+ DialogBuilder builder = new DialogBuilder(project);
+ builder.setCenterPanel(new GitSimplePathsBrowser(project, absolutePaths));
+ if (description != null) {
+ builder.setNorthPanel(new MultiLineLabel(description));
+ }
+ builder.addOkAction();
+ builder.setTitle(title);
+ builder.show();
+ }
}
diff --git a/plugins/git4idea/src/git4idea/GitVcs.java b/plugins/git4idea/src/git4idea/GitVcs.java
index 6d1762117c0a..5b3aa4dc0f97 100644
--- a/plugins/git4idea/src/git4idea/GitVcs.java
+++ b/plugins/git4idea/src/git4idea/GitVcs.java
@@ -56,6 +56,7 @@ import com.intellij.util.containers.ComparatorDelegate;
import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsLog;
+import com.intellij.vcs.log.VcsUserRegistry;
import git4idea.annotate.GitAnnotationProvider;
import git4idea.annotate.GitRepositoryForAnnotationsListener;
import git4idea.changes.GitCommittedChangeListProvider;
@@ -68,7 +69,6 @@ import git4idea.config.*;
import git4idea.diff.GitDiffProvider;
import git4idea.diff.GitTreeDiffProvider;
import git4idea.history.GitHistoryProvider;
-import git4idea.history.NewGitUsersComponent;
import git4idea.history.browser.GitHeavyCommit;
import git4idea.history.browser.GitProjectLogManager;
import git4idea.history.wholeTree.GitCommitDetailsProvider;
@@ -328,7 +328,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
if (myVFSListener == null) {
myVFSListener = new GitVFSListener(myProject, this, myGit);
}
- NewGitUsersComponent.getInstance(myProject).activate();
+ ServiceManager.getService(myProject, VcsUserRegistry.class); // make sure to read the registry before opening commit dialog
if (!Registry.is("git.new.log")) {
GitProjectLogManager.getInstance(myProject).activate();
}
@@ -368,7 +368,6 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
Disposer.dispose(myVFSListener);
myVFSListener = null;
}
- NewGitUsersComponent.getInstance(myProject).deactivate();
GitProjectLogManager.getInstance(myProject).deactivate();
if (myBranchWidget != null) {
diff --git a/plugins/git4idea/src/git4idea/actions/GitMerge.java b/plugins/git4idea/src/git4idea/actions/GitMerge.java
index a19568cb4912..5eb1714f6d7c 100644
--- a/plugins/git4idea/src/git4idea/actions/GitMerge.java
+++ b/plugins/git4idea/src/git4idea/actions/GitMerge.java
@@ -15,54 +15,36 @@
*/
package git4idea.actions;
-import com.intellij.history.Label;
-import com.intellij.history.LocalHistory;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.update.ActionInfo;
import com.intellij.openapi.vfs.VirtualFile;
-import git4idea.GitRevisionNumber;
-import git4idea.GitUtil;
import git4idea.GitVcs;
-import git4idea.commands.GitHandlerUtil;
import git4idea.commands.GitLineHandler;
import git4idea.i18n.GitBundle;
import git4idea.merge.GitMergeDialog;
-import git4idea.merge.GitMergeUtil;
-import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
-/**
- * Git "merge" action
- */
-public class GitMerge extends GitRepositoryAction {
+public class GitMerge extends GitMergeAction {
- /**
- * {@inheritDoc}
- */
@Override
@NotNull
protected String getActionName() {
return GitBundle.getString("merge.action.name");
}
- /**
- * {@inheritDoc}
- */
- protected void perform(@NotNull final Project project,
- @NotNull final List<VirtualFile> gitRoots,
- @NotNull final VirtualFile defaultRoot,
- final Set<VirtualFile> affectedRoots,
- final List<VcsException> exceptions) throws VcsException {
+ @Nullable
+ @Override
+ protected DialogState displayDialog(@NotNull Project project, @NotNull List<VirtualFile> gitRoots, @NotNull VirtualFile defaultRoot) {
GitVcs vcs = GitVcs.getInstance(project);
if (vcs == null) {
- return;
+ return null;
}
- GitMergeDialog dialog = new GitMergeDialog(project, gitRoots, defaultRoot);
+ final GitMergeDialog dialog = new GitMergeDialog(project, gitRoots, defaultRoot);
try {
dialog.updateBranches();
}
@@ -70,28 +52,18 @@ public class GitMerge extends GitRepositoryAction {
if (vcs.getExecutableValidator().checkExecutableAndShowMessageIfNeeded(null)) {
vcs.showErrors(Collections.singletonList(e), GitBundle.getString("merge.retrieving.branches"));
}
- return;
+ return null;
}
dialog.show();
if (!dialog.isOK()) {
- return;
- }
- Label beforeLabel = LocalHistory.getInstance().putSystemLabel(project, "Before update");
- GitLineHandler h = dialog.handler();
- final VirtualFile root = dialog.getSelectedRoot();
- affectedRoots.add(root);
- GitRevisionNumber currentRev = GitRevisionNumber.resolve(project, root, "HEAD");
- try {
- GitHandlerUtil.doSynchronously(h, GitBundle.message("merging.title", dialog.getSelectedRoot().getPath()), h.printableCommandLine());
+ return null;
}
- finally {
- exceptions.addAll(h.errors());
- GitRepositoryManager manager = GitUtil.getRepositoryManager(project);
- manager.updateRepository(root);
- }
- if (exceptions.size() != 0) {
- return;
- }
- GitMergeUtil.showUpdates(this, project, exceptions, root, currentRev, beforeLabel, getActionName(), ActionInfo.INTEGRATE);
+ return new DialogState(dialog.getSelectedRoot(), GitBundle.message("merging.title", dialog.getSelectedRoot().getPath()),
+ new Computable<GitLineHandler>() {
+ @Override
+ public GitLineHandler compute() {
+ return dialog.handler();
+ }
+ });
}
}
diff --git a/plugins/git4idea/src/git4idea/actions/GitMergeAction.java b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java
new file mode 100644
index 000000000000..1d46335cc1b1
--- /dev/null
+++ b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.actions;
+
+import com.intellij.history.Label;
+import com.intellij.history.LocalHistory;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.update.ActionInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import git4idea.GitRevisionNumber;
+import git4idea.GitUtil;
+import git4idea.GitVcs;
+import git4idea.commands.*;
+import git4idea.merge.GitMergeUtil;
+import git4idea.repo.GitRepository;
+import git4idea.repo.GitRepositoryManager;
+import git4idea.util.GitUIUtil;
+import git4idea.util.LocalChangesWouldBeOverwrittenHelper;
+import git4idea.util.UntrackedFilesNotifier;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static git4idea.commands.GitLocalChangesWouldBeOverwrittenDetector.Operation.MERGE;
+
+abstract class GitMergeAction extends GitRepositoryAction {
+
+ protected static class DialogState {
+ final VirtualFile selectedRoot;
+ final String progressTitle;
+ final Computable<GitLineHandler> handlerProvider;
+ DialogState(@NotNull VirtualFile root, @NotNull String title, @NotNull Computable<GitLineHandler> provider) {
+ selectedRoot = root;
+ progressTitle = title;
+ handlerProvider = provider;
+ }
+ }
+
+ @Nullable
+ protected abstract DialogState displayDialog(@NotNull Project project, @NotNull List<VirtualFile> gitRoots,
+ @NotNull VirtualFile defaultRoot);
+
+ protected void perform(@NotNull final Project project,
+ @NotNull final List<VirtualFile> gitRoots,
+ @NotNull final VirtualFile defaultRoot,
+ final Set<VirtualFile> affectedRoots,
+ final List<VcsException> exceptions) throws VcsException {
+ final DialogState dialogState = displayDialog(project, gitRoots, defaultRoot);
+ if (dialogState == null) {
+ return;
+ }
+ final VirtualFile selectedRoot = dialogState.selectedRoot;
+ final Computable<GitLineHandler> handlerProvider = dialogState.handlerProvider;
+ final Label beforeLabel = LocalHistory.getInstance().putSystemLabel(project, "Before update");
+
+ new Task.Backgroundable(project, dialogState.progressTitle, false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ final GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
+ final Git git = ServiceManager.getService(Git.class);
+ final GitLocalChangesWouldBeOverwrittenDetector localChangesDetector =
+ new GitLocalChangesWouldBeOverwrittenDetector(selectedRoot, MERGE);
+ final GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector =
+ new GitUntrackedFilesOverwrittenByOperationDetector(selectedRoot);
+ GitCommandResult result = git.runCommand(new Computable<GitLineHandler>() {
+ @Override
+ public GitLineHandler compute() {
+ GitLineHandler handler = handlerProvider.compute();
+ handler.addLineListener(localChangesDetector);
+ handler.addLineListener(untrackedFilesDetector);
+ return handler;
+ }
+ });
+ affectedRoots.add(selectedRoot);
+
+ GitRepository repository = repositoryManager.getRepositoryForRoot(selectedRoot);
+ assert repository != null : "Repository can't be null for root " + selectedRoot;
+ String revision = repository.getCurrentRevision();
+ if (revision == null) {
+ return;
+ }
+ final GitRevisionNumber currentRev = new GitRevisionNumber(revision);
+ handleResult(result, project, localChangesDetector, untrackedFilesDetector, repository, currentRev, affectedRoots, beforeLabel);
+ }
+
+ }.queue();
+ }
+
+ private void handleResult(GitCommandResult result, Project project, GitLocalChangesWouldBeOverwrittenDetector localChangesDetector,
+ GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector, GitRepository repository,
+ GitRevisionNumber currentRev, Set<VirtualFile> affectedRoots, Label beforeLabel) {
+ GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
+ VirtualFile root = repository.getRoot();
+ if (result.success()) {
+ root.refresh(false, true);
+ List<VcsException> exceptions = new ArrayList<VcsException>();
+ GitMergeUtil.showUpdates(this, project, exceptions, root, currentRev, beforeLabel, getActionName(), ActionInfo.UPDATE);
+ repositoryManager.updateRepository(root);
+ runFinalTasks(project, GitVcs.getInstance(project), affectedRoots, getActionName(), exceptions);
+ }
+ else if (localChangesDetector.wasMessageDetected()) {
+ LocalChangesWouldBeOverwrittenHelper.showErrorNotification(project, repository.getRoot(), getActionName(),
+ localChangesDetector.getRelativeFilePaths());
+ }
+ else if (untrackedFilesDetector.wasMessageDetected()) {
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(project, root, untrackedFilesDetector.getRelativeFilePaths(),
+ getActionName(), null);
+ }
+ else {
+ GitUIUtil.notifyError(project, "Git " + getActionName() + " Failed", result.getErrorOutputAsJoinedString(), true, null);
+ repositoryManager.updateRepository(root);
+ }
+ }
+
+ @Override
+ protected boolean executeFinalTasksSynchronously() {
+ return false;
+ }
+
+}
diff --git a/plugins/git4idea/src/git4idea/actions/GitPull.java b/plugins/git4idea/src/git4idea/actions/GitPull.java
index 1831be7c37d9..1df7e93abf7e 100644
--- a/plugins/git4idea/src/git4idea/actions/GitPull.java
+++ b/plugins/git4idea/src/git4idea/actions/GitPull.java
@@ -15,38 +15,21 @@
*/
package git4idea.actions;
-import com.intellij.history.Label;
-import com.intellij.history.LocalHistory;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.update.ActionInfo;
import com.intellij.openapi.vfs.VirtualFile;
-import git4idea.GitRevisionNumber;
import git4idea.GitUtil;
-import git4idea.GitVcs;
-import git4idea.commands.Git;
-import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandler;
import git4idea.i18n.GitBundle;
-import git4idea.merge.GitMergeUtil;
import git4idea.merge.GitPullDialog;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
-import git4idea.util.GitUIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
-import java.util.Set;
-/**
- * Git "pull" action
- */
-public class GitPull extends GitRepositoryAction {
+public class GitPull extends GitMergeAction {
@Override
@NotNull
@@ -54,64 +37,33 @@ public class GitPull extends GitRepositoryAction {
return GitBundle.getString("pull.action.name");
}
- protected void perform(@NotNull final Project project,
- @NotNull final List<VirtualFile> gitRoots,
- @NotNull final VirtualFile defaultRoot,
- final Set<VirtualFile> affectedRoots,
- final List<VcsException> exceptions) throws VcsException {
+ @Override
+ protected DialogState displayDialog(@NotNull Project project, @NotNull List<VirtualFile> gitRoots,
+ @NotNull VirtualFile defaultRoot) {
final GitPullDialog dialog = new GitPullDialog(project, gitRoots, defaultRoot);
dialog.show();
if (!dialog.isOK()) {
- return;
+ return null;
}
- final Label beforeLabel = LocalHistory.getInstance().putSystemLabel(project, "Before update");
-
- new Task.Backgroundable(project, GitBundle.message("pulling.title", dialog.getRemote()), true) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- final GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
- GitRepository repository = repositoryManager.getRepositoryForRoot(dialog.gitRoot());
- assert repository != null : "Repository can't be null for root " + dialog.gitRoot();
- String remoteOrUrl = dialog.getRemote();
-
-
- GitRemote remote = GitUtil.findRemoteByName(repository, remoteOrUrl);
- final String url = (remote == null) ? remoteOrUrl : remote.getFirstUrl();
- if (url == null) {
- return;
- }
+ GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
+ GitRepository repository = repositoryManager.getRepositoryForRoot(dialog.gitRoot());
+ assert repository != null : "Repository can't be null for root " + dialog.gitRoot();
+ String remoteOrUrl = dialog.getRemote();
+
+ GitRemote remote = GitUtil.findRemoteByName(repository, remoteOrUrl);
+ final String url = (remote == null) ? remoteOrUrl : remote.getFirstUrl();
+ if (url == null) {
+ return null;
+ }
- final Git git = ServiceManager.getService(Git.class);
- GitCommandResult result = git.runRemoteCommand(new Computable<GitLineHandler>() {
- @Override
- public GitLineHandler compute() {
- return dialog.makeHandler(url);
- }
- });
- final VirtualFile root = dialog.gitRoot();
- affectedRoots.add(root);
- String revision = repository.getCurrentRevision();
- if (revision == null) {
- return;
- }
- final GitRevisionNumber currentRev = new GitRevisionNumber(revision);
- if (result.success()) {
- root.refresh(false, true);
- GitMergeUtil.showUpdates(GitPull.this, project, exceptions, root, currentRev, beforeLabel, getActionName(), ActionInfo.UPDATE);
- repositoryManager.updateRepository(root);
- runFinalTasks(project, GitVcs.getInstance(project), affectedRoots, getActionName(), exceptions);
- }
- else {
- GitUIUtil.notifyError(project, "Error pulling " + dialog.getRemote(), result.getErrorOutputAsJoinedString(), true, null);
- repositoryManager.updateRepository(root);
- }
+ Computable<GitLineHandler> handlerProvider = new Computable<GitLineHandler>() {
+ @Override
+ public GitLineHandler compute() {
+ return dialog.makeHandler(url);
}
- }.queue();
+ };
+ return new DialogState(dialog.gitRoot(), GitBundle.message("pulling.title", dialog.getRemote()), handlerProvider);
}
- @Override
- protected boolean executeFinalTasksSynchronously() {
- return false;
- }
}
diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchOperation.java b/plugins/git4idea/src/git4idea/branch/GitBranchOperation.java
index b65d4cc6097e..7c2f77eeebd2 100644
--- a/plugins/git4idea/src/git4idea/branch/GitBranchOperation.java
+++ b/plugins/git4idea/src/git4idea/branch/GitBranchOperation.java
@@ -19,7 +19,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsNotifier;
@@ -261,21 +260,21 @@ abstract class GitBranchOperation {
* If some repositories succeeded, shows a dialog with the list of these files and a proposal to rollback the operation of those
* repositories.
*/
- protected void fatalUntrackedFilesError(@NotNull Collection<VirtualFile> untrackedFiles) {
+ protected void fatalUntrackedFilesError(@NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
if (wereSuccessful()) {
- showUntrackedFilesDialogWithRollback(untrackedFiles);
+ showUntrackedFilesDialogWithRollback(root, relativePaths);
}
else {
- showUntrackedFilesNotification(untrackedFiles);
+ showUntrackedFilesNotification(root, relativePaths);
}
}
- private void showUntrackedFilesNotification(@NotNull Collection<VirtualFile> untrackedFiles) {
- myUiHandler.showUntrackedFilesNotification(getOperationName(), untrackedFiles);
+ private void showUntrackedFilesNotification(@NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
+ myUiHandler.showUntrackedFilesNotification(getOperationName(), root, relativePaths);
}
- private void showUntrackedFilesDialogWithRollback(@NotNull Collection<VirtualFile> untrackedFiles) {
- boolean ok = myUiHandler.showUntrackedFilesDialogWithRollback(getOperationName(), getRollbackProposal(), untrackedFiles);
+ private void showUntrackedFilesDialogWithRollback(@NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
+ boolean ok = myUiHandler.showUntrackedFilesDialogWithRollback(getOperationName(), getRollbackProposal(), root, relativePaths);
if (ok) {
rollback();
}
@@ -293,7 +292,7 @@ abstract class GitBranchOperation {
for (GitRepository repository : repositories) {
try {
Collection<String> diff = GitUtil.getPathsDiffBetweenRefs(myGit, repository, currentBranch, otherBranch);
- List<Change> changesInRepo = convertPathsToChanges(repository, diff, false);
+ List<Change> changesInRepo = GitUtil.findLocalChangesForPaths(myProject, repository.getRoot(), diff, false);
if (!changesInRepo.isEmpty()) {
changes.put(repository, changesInRepo);
}
@@ -324,7 +323,9 @@ abstract class GitBranchOperation {
String currentBranch, String nextBranch) {
// get changes overwritten by checkout from the error message captured from Git
- List<Change> affectedChanges = convertPathsToChanges(currentRepository, localChangesOverwrittenBy.getRelativeFilePaths(), true);
+ List<Change> affectedChanges = GitUtil.findLocalChangesForPaths(myProject, currentRepository.getRoot(),
+ localChangesOverwrittenBy.getRelativeFilePaths(), true
+ );
// get all other conflicting changes
// get changes in all other repositories (except those which already have succeeded) to avoid multiple dialogs proposing smart checkout
Map<GitRepository, List<Change>> conflictingChangesInRepositories =
@@ -339,34 +340,4 @@ abstract class GitBranchOperation {
return Pair.create(allConflictingRepositories, affectedChanges);
}
-
- /**
- * Given the list of paths converts them to the list of {@link com.intellij.openapi.vcs.changes.Change Changes} found in the {@link com.intellij.openapi.vcs.changes.ChangeListManager},
- * i.e. this works only for local changes.
- * Paths can be absolute or relative to the repository.
- * If a path is not in the local changes, it is ignored.
- */
- @NotNull
- private List<Change> convertPathsToChanges(@NotNull GitRepository repository,
- @NotNull Collection<String> affectedPaths, boolean relativePaths) {
- List<Change> affectedChanges = new ArrayList<Change>();
- for (String path : affectedPaths) {
- VirtualFile file;
- if (relativePaths) {
- file = repository.getRoot().findFileByRelativePath(FileUtil.toSystemIndependentName(path));
- }
- else {
- file = myFacade.getVirtualFileByPath(path);
- }
-
- if (file != null) {
- Change change = myFacade.getChangeListManager(myProject).getChange(file);
- if (change != null) {
- affectedChanges.add(change);
- }
- }
- }
- return affectedChanges;
- }
-
}
diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java
index 9a153bb9dfed..3b694c455c7b 100644
--- a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java
+++ b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandler.java
@@ -58,22 +58,24 @@ public interface GitBranchUiHandler {
/**
* Show notification about "untracked files would be overwritten by merge/checkout".
- * @param untrackedFiles
*/
- void showUntrackedFilesNotification(@NotNull String operationName, @NotNull Collection<VirtualFile> untrackedFiles);
+ void showUntrackedFilesNotification(@NotNull String operationName, @NotNull VirtualFile root, @NotNull Collection<String> relativePaths);
boolean showUntrackedFilesDialogWithRollback(@NotNull String operationName, @NotNull String rollbackProposal,
- @NotNull Collection<VirtualFile> untrackedFiles);
+ @NotNull VirtualFile root, @NotNull Collection<String> relativePaths);
/**
* Shows the dialog proposing to execute the operation (checkout or merge) smartly, i.e. stash-execute-unstash.
+ *
* @param project
- * @param changes local changes that would be overwritten by checkout or merge.
- * @param operation operation name
- * @param force can the operation be executed force (force checkout is possible, force merge - not).
+ * @param changes local changes that would be overwritten by checkout or merge.
+ * @param paths paths reported by Git (in most cases this is covered by {@code changes}.
+ * @param operation operation name: checkout or merge
+ * @param isForcePossible can the operation be executed force (force checkout is possible, force merge - not).
* @return the code of the decision.
*/
- int showSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull String operation, boolean force);
+ int showSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull Collection<String> paths,
+ @NotNull String operation, boolean isForcePossible);
boolean showBranchIsNotFullyMergedDialog(@NotNull Project project, @NotNull Map<GitRepository, List<GitCommit>> history,
@NotNull String unmergedBranch, @NotNull List<String> mergedToBranches,
diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java
index 0c1878a5ec82..cea2b55596e0 100644
--- a/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java
+++ b/plugins/git4idea/src/git4idea/branch/GitBranchUiHandlerImpl.java
@@ -19,14 +19,19 @@ import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.MultiLineLabelUI;
import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ui.SelectFilesDialog;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.components.JBLabel;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.xml.util.XmlStringUtil;
import git4idea.GitCommit;
@@ -36,12 +41,15 @@ import git4idea.MessageManager;
import git4idea.commands.Git;
import git4idea.merge.GitConflictResolver;
import git4idea.repo.GitRepository;
+import git4idea.ui.ChangesBrowserWithRollback;
+import git4idea.util.GitSimplePathsBrowser;
import git4idea.util.UntrackedFilesNotifier;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -119,26 +127,41 @@ public class GitBranchUiHandlerImpl implements GitBranchUiHandler {
}
@Override
- public void showUntrackedFilesNotification(@NotNull String operationName, @NotNull Collection<VirtualFile> untrackedFiles) {
- UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject,
- untrackedFiles, operationName, null);
+ public void showUntrackedFilesNotification(@NotNull String operationName, @NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root, relativePaths, operationName, null);
}
@Override
- public boolean showUntrackedFilesDialogWithRollback(@NotNull String operationName, @NotNull String rollbackProposal,
- @NotNull Collection<VirtualFile> untrackedFiles) {
- String title = "Could not " + StringUtil.capitalize(operationName);
- String description = UntrackedFilesNotifier.createUntrackedFilesOverwrittenDescription(operationName, false);
+ public boolean showUntrackedFilesDialogWithRollback(@NotNull String operationName, @NotNull final String rollbackProposal,
+ @NotNull VirtualFile root, @NotNull final Collection<String> relativePaths) {
+ final String title = "Could not " + StringUtil.capitalize(operationName);
+ final String description = UntrackedFilesNotifier.createUntrackedFilesOverwrittenDescription(operationName, false);
- final SelectFilesDialog dialog = new UntrackedFilesDialog(myProject, untrackedFiles, StringUtil.stripHtml(description, true), rollbackProposal);
- dialog.setTitle(title);
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ final Collection<String> absolutePaths = GitUtil.toAbsolute(root, relativePaths);
+ final List<VirtualFile> untrackedFiles = ContainerUtil.mapNotNull(absolutePaths, new Function<String, VirtualFile>() {
@Override
- public void run() {
+ public VirtualFile fun(String absolutePath) {
+ return GitUtil.findRefreshFileOrLog(absolutePath);
+ }
+ });
+
+ return UIUtil.invokeAndWaitIfNeeded(new Computable<Boolean>() {
+ @Override
+ public Boolean compute() {
+ JComponent filesBrowser;
+ if (untrackedFiles.isEmpty()) {
+ filesBrowser = new GitSimplePathsBrowser(myProject, absolutePaths);
+ }
+ else {
+ filesBrowser = new SelectFilesDialog.VirtualFileList(myProject, untrackedFiles, false, false);
+ }
+ DialogWrapper dialog = new UntrackedFilesRollBackDialog(myProject, filesBrowser, StringUtil.stripHtml(description, true),
+ rollbackProposal);
+ dialog.setTitle(title);
myFacade.showDialog(dialog);
+ return dialog.isOK();
}
});
- return dialog.isOK();
}
@NotNull
@@ -148,8 +171,16 @@ public class GitBranchUiHandlerImpl implements GitBranchUiHandler {
}
@Override
- public int showSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull String operation, boolean force) {
- return GitSmartOperationDialog.showAndGetAnswer(myProject, changes, operation, true);
+ public int showSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull Collection<String> paths,
+ @NotNull String operation, boolean isForcePossible) {
+ JComponent fileBrowser;
+ if (!changes.isEmpty()) {
+ fileBrowser = new ChangesBrowserWithRollback(project, changes);
+ }
+ else {
+ fileBrowser = new GitSimplePathsBrowser(project, paths);
+ }
+ return GitSmartOperationDialog.showAndGetAnswer(myProject, fileBrowser, operation, isForcePossible);
}
@Override
@@ -177,13 +208,17 @@ public class GitBranchUiHandlerImpl implements GitBranchUiHandler {
"After resolving conflicts you also probably would want to commit your files to the current branch.";
}
- private static class UntrackedFilesDialog extends SelectFilesDialog {
+ private static class UntrackedFilesRollBackDialog extends DialogWrapper {
+ @NotNull private final JComponent myFilesBrowser;
+ @NotNull private final String myPrompt;
@NotNull private final String myRollbackProposal;
- public UntrackedFilesDialog(@NotNull Project project, @NotNull Collection<VirtualFile> originalFiles, @NotNull String prompt,
- @NotNull String rollbackProposal) {
- super(project, new ArrayList<VirtualFile>(originalFiles), prompt, null, false, false, false);
+ public UntrackedFilesRollBackDialog(@NotNull Project project, @NotNull JComponent filesBrowser, @NotNull String prompt,
+ @NotNull String rollbackProposal) {
+ super(project);
+ myFilesBrowser = filesBrowser;
+ myPrompt = prompt;
myRollbackProposal = rollbackProposal;
setOKButtonText("Rollback");
setCancelButtonText("Don't rollback");
@@ -198,5 +233,20 @@ public class GitBranchUiHandlerImpl implements GitBranchUiHandler {
panel.add(buttons);
return panel;
}
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return myFilesBrowser;
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createNorthPanel() {
+ JLabel label = new JLabel(myPrompt);
+ label.setUI(new MultiLineLabelUI());
+ label.setBorder(new EmptyBorder(5, 1, 5, 1));
+ return label;
+ }
}
}
diff --git a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java
index a48582680fa0..d49dc15827b7 100644
--- a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java
+++ b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import git4idea.GitPlatformFacade;
+import git4idea.GitUtil;
import git4idea.commands.*;
import git4idea.repo.GitRepository;
import git4idea.util.GitPreservingProcess;
@@ -90,7 +91,7 @@ class GitCheckoutOperation extends GitBranchOperation {
}
}
else if (untrackedOverwrittenByCheckout.wasMessageDetected()) {
- fatalUntrackedFilesError(untrackedOverwrittenByCheckout.getFiles());
+ fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByCheckout.getRelativeFilePaths());
fatalErrorHappened = true;
}
else {
@@ -112,7 +113,8 @@ class GitCheckoutOperation extends GitBranchOperation {
List<GitRepository> allConflictingRepositories = conflictingRepositoriesAndAffectedChanges.getFirst();
List<Change> affectedChanges = conflictingRepositoriesAndAffectedChanges.getSecond();
- int smartCheckoutDecision = myUiHandler.showSmartOperationDialog(myProject, affectedChanges, "checkout", true);
+ Collection<String> absolutePaths = GitUtil.toAbsolute(repository.getRoot(), localChangesOverwrittenByCheckout.getRelativeFilePaths());
+ int smartCheckoutDecision = myUiHandler.showSmartOperationDialog(myProject, affectedChanges, absolutePaths, "checkout", true);
if (smartCheckoutDecision == GitSmartOperationDialog.SMART_EXIT_CODE) {
boolean smartCheckedOutSuccessfully = smartCheckout(allConflictingRepositories, myStartPointReference, myNewBranch, getIndicator());
if (smartCheckedOutSuccessfully) {
diff --git a/plugins/git4idea/src/git4idea/branch/GitDeleteRemoteBranchOperation.java b/plugins/git4idea/src/git4idea/branch/GitDeleteRemoteBranchOperation.java
index 5ce85f114892..46630d0e1125 100644
--- a/plugins/git4idea/src/git4idea/branch/GitDeleteRemoteBranchOperation.java
+++ b/plugins/git4idea/src/git4idea/branch/GitDeleteRemoteBranchOperation.java
@@ -23,12 +23,10 @@ import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.util.ui.UIUtil;
-import git4idea.GitBranch;
import git4idea.GitPlatformFacade;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitCompoundResult;
-import git4idea.jgit.GitHttpAdapter;
import git4idea.push.GitSimplePushResult;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
@@ -166,15 +164,7 @@ class GitDeleteRemoteBranchOperation extends GitBranchOperation {
LOG.warn("No urls are defined for remote: " + remote);
return GitCommandResult.error("There is no urls defined for remote " + remote.getName());
}
- if (GitHttpAdapter.shouldUseJGit(remoteUrl)) {
- String fullBranchName = branchName.startsWith(GitBranch.REFS_HEADS_PREFIX) ? branchName : GitBranch.REFS_HEADS_PREFIX + branchName;
- String spec = ":" + fullBranchName;
- GitSimplePushResult simplePushResult = GitHttpAdapter.push(repository, remote.getName(), remoteUrl, spec);
- return convertSimplePushResultToCommandResult(simplePushResult);
- }
- else {
- return pushDeletionNatively(repository, remoteName, remoteUrl, branchName);
- }
+ return pushDeletionNatively(repository, remoteName, remoteUrl, branchName);
}
@NotNull
@@ -255,6 +245,7 @@ class GitDeleteRemoteBranchOperation extends GitBranchOperation {
return false;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return checkboxMessage;
diff --git a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java
index 81e5cc35f750..e90d1eb808ef 100644
--- a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java
+++ b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java
@@ -116,7 +116,7 @@ class GitMergeOperation extends GitBranchOperation {
}
else if (untrackedOverwrittenByMerge.wasMessageDetected()) {
LOG.info("Untracked files would be overwritten by merge!");
- fatalUntrackedFilesError(untrackedOverwrittenByMerge.getFiles());
+ fatalUntrackedFilesError(repository.getRoot(), untrackedOverwrittenByMerge.getRelativeFilePaths());
fatalErrorHappened = true;
}
else {
@@ -187,7 +187,8 @@ class GitMergeOperation extends GitBranchOperation {
List<GitRepository> allConflictingRepositories = conflictingRepositoriesAndAffectedChanges.getFirst();
List<Change> affectedChanges = conflictingRepositoriesAndAffectedChanges.getSecond();
- int smartCheckoutDecision = myUiHandler.showSmartOperationDialog(myProject, affectedChanges, "merge", false);
+ Collection<String> absolutePaths = GitUtil.toAbsolute(repository.getRoot(), localChangesOverwrittenByMerge.getRelativeFilePaths());
+ int smartCheckoutDecision = myUiHandler.showSmartOperationDialog(myProject, affectedChanges, absolutePaths, "merge", false);
if (smartCheckoutDecision == GitSmartOperationDialog.SMART_EXIT_CODE) {
return doSmartMerge(allConflictingRepositories);
}
diff --git a/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java b/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java
index c7f7f9ab476e..9c2ef4a8d107 100644
--- a/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java
+++ b/plugins/git4idea/src/git4idea/branch/GitSmartOperationDialog.java
@@ -19,8 +19,6 @@ import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.vcs.changes.Change;
-import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.UIUtil;
@@ -29,7 +27,6 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
-import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static com.intellij.openapi.util.text.StringUtil.capitalize;
@@ -39,29 +36,26 @@ import static com.intellij.openapi.util.text.StringUtil.capitalize;
* "Your local changes to the following files would be overwritten by merge/checkout"
* happens.
* Displays the list of these files and proposes to make a "smart" merge or checkout.
- *
- * @author Kirill Likhodedov
*/
public class GitSmartOperationDialog extends DialogWrapper {
public static final int SMART_EXIT_CODE = OK_EXIT_CODE;
public static final int FORCE_EXIT_CODE = NEXT_USER_EXIT_CODE;
-
- private final Project myProject;
- private final List<Change> myChanges;
+
+ @NotNull private final JComponent myFileBrowser;
@NotNull private final String myOperationTitle;
- private final boolean myForceButton;
+ private final boolean myShowForceButton;
/**
* Shows the dialog with the list of local changes preventing merge/checkout and returns the dialog exit code.
*/
- static int showAndGetAnswer(@NotNull final Project project, @NotNull final List<Change> changes, @NotNull final String operationTitle,
- final boolean forceButton) {
+ static int showAndGetAnswer(@NotNull final Project project, @NotNull final JComponent fileBrowser,
+ @NotNull final String operationTitle, final boolean showForceButton) {
final AtomicInteger exitCode = new AtomicInteger();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
- GitSmartOperationDialog dialog = new GitSmartOperationDialog(project, changes, operationTitle, forceButton);
+ GitSmartOperationDialog dialog = new GitSmartOperationDialog(project, fileBrowser, operationTitle, showForceButton);
ServiceManager.getService(project, GitPlatformFacade.class).showDialog(dialog);
exitCode.set(dialog.getExitCode());
}
@@ -69,15 +63,18 @@ public class GitSmartOperationDialog extends DialogWrapper {
return exitCode.get();
}
- private GitSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull String operationTitle,
- boolean forceButton) {
+ private GitSmartOperationDialog(@NotNull Project project, @NotNull JComponent fileBrowser, @NotNull String operationTitle,
+ boolean showForceButton) {
super(project);
- myProject = project;
- myChanges = changes;
+ myFileBrowser = fileBrowser;
myOperationTitle = operationTitle;
- myForceButton = forceButton;
- setOKButtonText("Smart " + capitalize(myOperationTitle));
- setCancelButtonText("Don't " + capitalize(myOperationTitle));
+ myShowForceButton = showForceButton;
+ String capitalizedOperation = capitalize(myOperationTitle);
+ setTitle("Git " + capitalizedOperation + " Problem");
+
+ setOKButtonText("Smart " + capitalizedOperation);
+ getOKAction().putValue(Action.SHORT_DESCRIPTION, "Stash local changes, " + operationTitle + ", unstash");
+ setCancelButtonText("Don't " + capitalizedOperation);
getCancelAction().putValue(FOCUSED_ACTION, Boolean.TRUE);
init();
}
@@ -85,8 +82,8 @@ public class GitSmartOperationDialog extends DialogWrapper {
@NotNull
@Override
protected Action[] createLeftSideActions() {
- if (myForceButton) {
- return new Action[] {new ForceCheckoutAction(myOperationTitle) };
+ if (myShowForceButton) {
+ return new Action[] {new ForceCheckoutAction(myOperationTitle) };
}
return new Action[0];
}
@@ -102,10 +99,7 @@ public class GitSmartOperationDialog extends DialogWrapper {
@Override
protected JComponent createCenterPanel() {
- ChangesBrowser changesBrowser =
- new ChangesBrowser(myProject, null, myChanges, null, false, true, null, ChangesBrowser.MyUseCase.LOCAL_CHANGES, null);
- changesBrowser.setChangesToDisplay(myChanges);
- return changesBrowser;
+ return myFileBrowser;
}
@Override
@@ -118,6 +112,7 @@ public class GitSmartOperationDialog extends DialogWrapper {
ForceCheckoutAction(@NotNull String operationTitle) {
super("&Force " + capitalize(operationTitle));
+ putValue(Action.SHORT_DESCRIPTION, capitalize(operationTitle) + " and overwrite local changes");
}
@Override
diff --git a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java
index e23f8ed91c30..157373e4f8b8 100644
--- a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java
+++ b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java
@@ -186,18 +186,23 @@ public class GitChangeUtils {
@NotNull
public static GitRevisionNumber resolveReference(@NotNull Project project, @NotNull VirtualFile vcsRoot,
@NotNull String reference) throws VcsException {
- GitSimpleHandler handler = new GitSimpleHandler(project, vcsRoot, GitCommand.REV_LIST);
- handler.addParameters("--timestamp", "--max-count=1", reference);
- handler.endOptions();
- handler.setSilent(true);
+ GitSimpleHandler handler = createRefResolveHandler(project, vcsRoot, reference);
String output = handler.run();
StringTokenizer stk = new StringTokenizer(output, "\n\r \t", false);
if (!stk.hasMoreTokens()) {
- GitSimpleHandler dh = new GitSimpleHandler(project, vcsRoot, GitCommand.LOG);
- dh.addParameters("-1", "HEAD");
- dh.setSilent(true);
- String out = dh.run();
- LOG.info("Diagnostic output from 'git log -1 HEAD': [" + out + "]");
+ try {
+ GitSimpleHandler dh = new GitSimpleHandler(project, vcsRoot, GitCommand.LOG);
+ dh.addParameters("-1", "HEAD");
+ dh.setSilent(true);
+ String out = dh.run();
+ LOG.info("Diagnostic output from 'git log -1 HEAD': [" + out + "]");
+ dh = createRefResolveHandler(project, vcsRoot, reference);
+ out = dh.run();
+ LOG.info("Diagnostic output from 'git rev-list -1 --timestamp HEAD': [" + out + "]");
+ }
+ catch (VcsException e) {
+ LOG.info("Exception while trying to get some diagnostics info", e);
+ }
throw new VcsException(String.format("The string '%s' does not represent a revision number. Output: [%s]\n Root: %s",
reference, output, vcsRoot));
}
@@ -205,6 +210,15 @@ public class GitChangeUtils {
return new GitRevisionNumber(stk.nextToken(), timestamp);
}
+ @NotNull
+ private static GitSimpleHandler createRefResolveHandler(@NotNull Project project, @NotNull VirtualFile root, @NotNull String reference) {
+ GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.REV_LIST);
+ handler.addParameters("--timestamp", "--max-count=1", reference);
+ handler.endOptions();
+ handler.setSilent(true);
+ return handler;
+ }
+
/**
* Check if the exception means that HEAD is missing for the current repository.
*
diff --git a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java
index baf835820ddb..f1ab1d476c6f 100644
--- a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java
+++ b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
@@ -197,7 +198,14 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
final Collection<Change> changes = commit.getChanges();
if (changes.size() == 1) {
- return Pair.create(commit, changes.iterator().next().getAfterRevision().getFile());
+ Change change = changes.iterator().next();
+ ContentRevision revision = change.getAfterRevision();
+ if (revision == null) {
+ revision = change.getBeforeRevision();
+ }
+ assert revision != null : "Revision can't be null in " + change;
+ FilePath filePathInRevision = revision.getFile();
+ return Pair.create(commit, filePathInRevision);
}
for (Change change : changes) {
if (change.getAfterRevision() != null && FileUtil.filesEqual(filePath.getIOFile(), change.getAfterRevision().getFile().getIOFile())) {
diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
index 170dffff0492..2eb0219485b6 100644
--- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
+++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
@@ -20,6 +20,8 @@ import com.intellij.dvcs.DvcsCommitAdditionalComponent;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Ref;
@@ -27,7 +29,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.FilePath;
-import com.intellij.openapi.vcs.ObjectsConvertor;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.ui.SelectFilePathsDialog;
@@ -35,15 +36,15 @@ import com.intellij.openapi.vcs.checkin.CheckinChangeListSpecificComponent;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
import com.intellij.ui.GuiUtils;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.FunctionUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.PairConsumer;
+import com.intellij.ui.StringComboboxEditor;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsUser;
+import com.intellij.vcs.log.VcsUserRegistry;
import com.intellij.vcsUtil.VcsFileUtil;
import com.intellij.vcsUtil.VcsUtil;
import git4idea.GitPlatformFacade;
@@ -54,7 +55,6 @@ import git4idea.commands.GitSimpleHandler;
import git4idea.config.GitConfigUtil;
import git4idea.config.GitVcsSettings;
import git4idea.config.GitVersionSpecialty;
-import git4idea.history.NewGitUsersComponent;
import git4idea.i18n.GitBundle;
import git4idea.push.GitPusher;
import git4idea.repo.GitRepositoryFiles;
@@ -71,9 +71,6 @@ import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
-/**
- * Git environment for commit operations.
- */
public class GitCheckinEnvironment implements CheckinEnvironment {
private static final Logger log = Logger.getInstance(GitCheckinEnvironment.class.getName());
@NonNls private static final String GIT_COMMIT_MSG_FILE_PREFIX = "git-commit-msg-"; // the file name prefix for commit message file
@@ -207,7 +204,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
}
}
catch (VcsException e) {
- exceptions.add(e);
+ exceptions.add(cleanupExceptionText(e));
}
}
catch (IOException ex) {
@@ -226,8 +223,23 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return exceptions;
}
+ @NotNull
+ private static VcsException cleanupExceptionText(VcsException original) {
+ String msg = original.getMessage();
+ final String FATAL_PREFIX = "fatal:";
+ if (msg.startsWith(FATAL_PREFIX)) {
+ msg = msg.substring(FATAL_PREFIX.length());
+ }
+ final String DURING_EXECUTING_SUFFIX = GitSimpleHandler.DURING_EXECUTING_ERROR_MESSAGE;
+ int suffix = msg.indexOf(DURING_EXECUTING_SUFFIX);
+ if (suffix > 0) {
+ msg = msg.substring(0, suffix);
+ }
+ return new VcsException(msg.trim(), original.getCause());
+ }
+
public List<VcsException> commit(List<Change> changes, String preparedComment) {
- return commit(changes, preparedComment, FunctionUtil.<Object, Object>nullConstant(), null);
+ return commit(changes, preparedComment, FunctionUtil.nullConstant(), null);
}
/**
@@ -424,9 +436,6 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return file;
}
- /**
- * {@inheritDoc}
- */
public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> files) {
ArrayList<VcsException> rc = new ArrayList<VcsException>();
Map<VirtualFile, List<FilePath>> sortedFiles;
@@ -450,21 +459,6 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return rc;
}
- /**
- * Prepare delete files handler.
- *
- *
- *
- * @param project the project
- * @param root a vcs root
- * @param files a files to commit
- * @param message a message file to use
- * @param nextCommitAuthor a author for the next commit
- * @param nextCommitAmend true, if the commit should be amended
- * @param nextCommitAuthorDate Author date timestamp to override the date of the commit or null if this overriding is not needed.
- * @return a simple handler that does the task
- * @throws VcsException in case of git problem
- */
private static void commit(Project project,
VirtualFile root,
Collection<FilePath> files,
@@ -499,10 +493,6 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
}
}
-
- /**
- * {@inheritDoc}
- */
public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
ArrayList<VcsException> rc = new ArrayList<VcsException>();
Map<VirtualFile, List<VirtualFile>> sortedFiles;
@@ -542,13 +532,6 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
}
}
- /**
- * Sort changes by roots
- *
- * @param changes a change list
- * @param exceptions exceptions to collect
- * @return sorted changes
- */
private static Map<VirtualFile, Collection<Change>> sortChangesByGitRoot(@NotNull List<Change> changes, List<VcsException> exceptions) {
Map<VirtualFile, Collection<Change>> result = new HashMap<VirtualFile, Collection<Change>>();
for (Change change : changes) {
@@ -579,11 +562,6 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return result;
}
- /**
- * Mark root as dirty
- *
- * @param root a vcs root to rescan
- */
private void markRootDirty(final VirtualFile root) {
// Note that the root is invalidated because changes are detected per-root anyway.
// Otherwise it is not possible to detect moves.
@@ -597,14 +575,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
myNextCommitAuthorDate = null;
}
- /**
- * Checkin options for git
- */
private class GitCheckinOptions extends DvcsCommitAdditionalComponent implements CheckinChangeListSpecificComponent {
private final GitVcs myVcs;
- /**
- * The author ComboBox, the combobox contains previously selected authors.
- */
private final ComboBox myAuthor;
private Date myAuthorDate;
@@ -630,17 +602,26 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
final List<String> usersList = getUsersList(project);
- final Set<String> authors = usersList == null ? new HashSet<String>() : new HashSet<String>(usersList);
+ final Set<String> authors = new HashSet<String>(usersList);
ContainerUtil.addAll(authors, mySettings.getCommitAuthors());
List<String> list = new ArrayList<String>(authors);
Collections.sort(list);
- list = ObjectsConvertor.convert(list, new Convertor<String, String>() {
+
+ myAuthor = new ComboBox(ArrayUtil.toObjectArray(list)) {
@Override
- public String convert(String o) {
- return StringUtil.shortenTextWithEllipsis(o, 30, 0);
+ public void addNotify() {
+ super.addNotify();
+
+ // adding in addNotify to make sure the editor is ready for further customization
+ StringComboboxEditor comboboxEditor = new StringComboboxEditor(project, FileTypes.PLAIN_TEXT, myAuthor, true);
+ myAuthor.setEditor(comboboxEditor);
+ EditorEx editor = (EditorEx)comboboxEditor.getEditor();
+ assert editor != null;
+ SpellCheckingEditorCustomization.getInstance(false).customize(editor);
}
- });
- myAuthor = new ComboBox(ArrayUtil.toObjectArray(list));
+ };
+ myAuthor.setMinimumAndPreferredWidth(100);
+
myAuthor.insertItemAt("", 0);
myAuthor.setSelectedItem("");
myAuthor.setEditable(true);
@@ -673,8 +654,15 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
return h.run();
}
- private List<String> getUsersList(final Project project) {
- return NewGitUsersComponent.getInstance(project).get();
+ @NotNull
+ private List<String> getUsersList(@NotNull Project project) {
+ VcsUserRegistry userRegistry = ServiceManager.getService(project, VcsUserRegistry.class);
+ return ContainerUtil.map(userRegistry.getUsers(), new Function<VcsUser, String>() {
+ @Override
+ public String fun(VcsUser user) {
+ return user.getName() + " <" + user.getEmail() + ">";
+ }
+ });
}
@Override
@@ -687,13 +675,12 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
@Override
public void saveState() {
String author = (String)myAuthor.getEditor().getItem();
- myNextCommitAuthor = author.length() == 0 ? null : author;
- if (author.length() == 0) {
+ if (StringUtil.isEmptyOrSpaces(author)) {
myNextCommitAuthor = null;
}
else {
- myNextCommitAuthor = author;
- mySettings.saveCommitAuthor(author);
+ myNextCommitAuthor = GitCommitAuthorCorrector.correct(author);
+ mySettings.saveCommitAuthor(myNextCommitAuthor);
}
myNextCommitAmend = myAmend.isSelected();
myNextCommitAuthorDate = myAuthorDate;
@@ -716,6 +703,7 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
}
}
+
public void setNextCommitIsPushed(Boolean nextCommitIsPushed) {
myNextCommitIsPushed = nextCommitIsPushed;
}
diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java
index 75a6df3e8f67..8bfc52ca261a 100644
--- a/plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java
+++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinHandlerFactory.java
@@ -22,7 +22,9 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.FilePath;
@@ -131,14 +133,17 @@ public class GitCheckinHandlerFactory extends VcsCheckinHandlerFactory {
}
if (crlfHelper.get().shouldWarn()) {
- final GitCrlfDialog dialog = new GitCrlfDialog(myProject);
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ Pair<Integer, Boolean> codeAndDontWarn = UIUtil.invokeAndWaitIfNeeded(new Computable<Pair<Integer, Boolean>>() {
@Override
- public void run() {
+ public Pair<Integer, Boolean> compute() {
+ final GitCrlfDialog dialog = new GitCrlfDialog(myProject);
dialog.show();
+ return Pair.create(dialog.getExitCode(), dialog.dontWarnAgain());
}
});
- int decision = dialog.getExitCode();
+ int decision = codeAndDontWarn.first;
+ boolean dontWarnAgain = codeAndDontWarn.second;
+
if (decision == GitCrlfDialog.CANCEL) {
return ReturnResult.CANCEL;
}
@@ -148,7 +153,7 @@ public class GitCheckinHandlerFactory extends VcsCheckinHandlerFactory {
setCoreAutoCrlfAttribute(anyRoot);
}
else {
- if (dialog.dontWarnAgain()) {
+ if (dontWarnAgain) {
settings.setWarnAboutCrlf(false);
}
}
diff --git a/plugins/git4idea/src/git4idea/checkin/GitCommitAuthorCorrector.java b/plugins/git4idea/src/git4idea/checkin/GitCommitAuthorCorrector.java
new file mode 100644
index 000000000000..e46e98a7887f
--- /dev/null
+++ b/plugins/git4idea/src/git4idea/checkin/GitCommitAuthorCorrector.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.checkin;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Corrects some simple but popular mistakes on the author format.<p/>
+ * The required format is: {@code author name <author.name@email.com>}
+ */
+class GitCommitAuthorCorrector {
+
+ @NotNull
+ public static String correct(@NotNull String author) {
+ author = author.trim();
+
+ int openBrace = author.indexOf('<');
+ int closeBrace = author.indexOf('>');
+
+ if (openBrace < 0) { // email should open with "<"
+ int at = author.lastIndexOf("@");
+ if (at < 0) {
+ return author;
+ }
+ int email = author.substring(0, at).lastIndexOf(' ');
+ if (email < 0) {
+ return author;
+ }
+ author = author.substring(0, email + 1) + "<" + author.substring(email + 1);
+ }
+ else if (openBrace > 0 && author.charAt(openBrace - 1) != ' ') { // insert space before email
+ author = author.substring(0, openBrace) + " " + author.substring(openBrace);
+ }
+
+ if (closeBrace < 0) { // email should close with ">"
+ author += ">";
+ }
+
+ return author;
+ }
+
+}
diff --git a/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java b/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java
index a8b78a151423..5629a93bac73 100644
--- a/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java
+++ b/plugins/git4idea/src/git4idea/checkout/GitCheckoutProvider.java
@@ -30,9 +30,6 @@ import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandlerListener;
import git4idea.commands.GitStandardProgressAnalyzer;
-import git4idea.jgit.GitHttpAdapter;
-import git4idea.update.GitFetchResult;
-import git4idea.update.GitFetcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -109,26 +106,13 @@ public class GitCheckoutProvider implements CheckoutProvider {
public static boolean doClone(@NotNull Project project, @NotNull ProgressIndicator indicator, @NotNull Git git,
@NotNull String directoryName, @NotNull String parentDirectory, @NotNull String sourceRepositoryURL) {
- if (GitHttpAdapter.shouldUseJGit(sourceRepositoryURL)) {
- GitFetchResult result = GitHttpAdapter.cloneRepository(project, new File(parentDirectory, directoryName), sourceRepositoryURL);
- GitFetcher.displayFetchResult(project, result, "Clone failed", result.getErrors());
- return result.isSuccess();
- }
- else {
- return cloneNatively(project, indicator, git, new File(parentDirectory), sourceRepositoryURL, directoryName);
- }
- }
-
- private static boolean cloneNatively(@NotNull Project project, @NotNull final ProgressIndicator indicator,
- @NotNull Git git, @NotNull File directory, @NotNull String url, @NotNull String cloneDirectoryName) {
indicator.setIndeterminate(false);
GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(indicator);
- GitCommandResult result = git.clone(project, directory, url, cloneDirectoryName, progressListener);
+ GitCommandResult result = git.clone(project, new File(parentDirectory), sourceRepositoryURL, directoryName, progressListener);
if (result.success()) {
return true;
}
VcsNotifier.getInstance(project).notifyError("Clone failed", result.getErrorOutputAsHtmlString());
return false;
}
-
}
diff --git a/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java b/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java
index 1f03a81c3fa4..831f833e0db5 100644
--- a/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java
+++ b/plugins/git4idea/src/git4idea/checkout/GitCloneDialog.java
@@ -40,8 +40,7 @@ public class GitCloneDialog extends CloneDvcsDialog {
}
/*
- * JGit doesn't have ls-remote command independent from repository yet.
- * That way, we have a hack here: if http response asked for a password, then the url is at least valid and existant, and we consider
+ * We have a hack here: if http response asked for a password, then the url is at least valid and existent, and we consider
* that the test passed.
*/
protected boolean test(@NotNull String url) {
diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
index d4b3a0fbf1d8..bd8635db89be 100644
--- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
+++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java
@@ -140,8 +140,8 @@ public class GitCherryPicker {
"Please move, remove or add them before you can cherry-pick. <a href='view'>View them</a>";
description += getSuccessfulCommitDetailsIfAny(successfulCommits);
- UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, untrackedFilesDetector.getFiles(),
- "cherry-pick", description);
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, repository.getRoot(),
+ untrackedFilesDetector.getRelativeFilePaths(), "cherry-pick", description);
return false;
}
else if (localChangesOverwrittenDetector.hasHappened()) {
diff --git a/plugins/git4idea/src/git4idea/commands/Git.java b/plugins/git4idea/src/git4idea/commands/Git.java
index eaf58ff824d2..284ccc1e20c5 100644
--- a/plugins/git4idea/src/git4idea/commands/Git.java
+++ b/plugins/git4idea/src/git4idea/commands/Git.java
@@ -36,13 +36,13 @@ import java.util.Set;
public interface Git {
/**
- * A generic method to run a Git remote command, when existing methods like {@link #fetch(GitRepository, String, String, List, String...)}
+ * A generic method to run a Git command, when existing methods like {@link #fetch(GitRepository, String, String, List, String...)}
* are not sufficient.
* @param handlerConstructor this is needed, since the operation may need to repeat (e.g. in case of authentication failure).
* make sure to supply a stateless constructor.
*/
@NotNull
- GitCommandResult runRemoteCommand(@NotNull Computable<GitLineHandler> handlerConstructor);
+ GitCommandResult runCommand(@NotNull Computable<GitLineHandler> handlerConstructor);
@NotNull
GitCommandResult init(@NotNull Project project, @NotNull VirtualFile root, @NotNull GitLineHandlerListener... listeners);
diff --git a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java
index 03cfab25bc84..fbc84ca1a7a2 100644
--- a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java
+++ b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java
@@ -15,7 +15,6 @@
*/
package git4idea.commands;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
@@ -28,21 +27,13 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.awt.EventQueue;
-import java.util.Collection;
+import java.awt.*;
/**
* Handler utilities that allow running handlers with progress indicators
*/
public class GitHandlerUtil {
- /**
- * The logger instance
- */
- private static final Logger LOG = Logger.getInstance(GitHandlerUtil.class.getName());
- /**
- * a private constructor for utility class
- */
private GitHandlerUtil() {
}
@@ -55,7 +46,7 @@ public class GitHandlerUtil {
* @return A stdout content or null if there was error (exit code != 0 or exception during start).
*/
@Nullable
- public static String doSynchronously(final GitSimpleHandler handler, String operationTitle, @NonNls final String operationName) {
+ public static String doSynchronously(final GitSimpleHandler handler, final String operationTitle, @NonNls final String operationName) {
handler.addListener(new GitHandlerListenerBase(handler, operationName) {
protected String getErrorText() {
String text = handler.getStderr();
@@ -65,7 +56,13 @@ public class GitHandlerUtil {
return text;
}
});
- runHandlerSynchronously(handler, operationTitle, ProgressManager.getInstance(), true);
+ final ProgressManager manager = ProgressManager.getInstance();
+ manager.runProcessWithProgressSynchronously(new Runnable() {
+ public void run() {
+ runInCurrentThread(handler, manager.getProgressIndicator(), true,
+ operationTitle);
+ }
+ }, operationTitle, false, handler.project());
if (!handler.isStarted() || handler.getExitCode() != 0) {
return null;
}
@@ -80,47 +77,12 @@ public class GitHandlerUtil {
* @param operationName an operation name shown in failure dialog
* @return An exit code
*/
- public static int doSynchronously(final GitLineHandler handler, String operationTitle, @NonNls final String operationName) {
- return doSynchronously(handler, operationTitle, operationName, true);
- }
-
- /**
- * Execute simple process synchronously with progress
- *
- * @param handler a handler
- * @param operationTitle an operation title shown in progress dialog
- * @param operationName an operation name shown in failure dialog
- * @param showErrors if true, the errors are shown when process is terminated
- * @return An exit code
- */
- public static int doSynchronously(final GitLineHandler handler,
- String operationTitle,
- @NonNls final String operationName,
- boolean showErrors) {
- return doSynchronously(handler, operationTitle, operationName, showErrors, true);
- }
-
-
- /**
- * Execute simple process synchronously with progress
- *
- * @param handler a handler
- * @param operationTitle an operation title shown in progress dialog
- * @param operationName an operation name shown in failure dialog
- * @param showErrors if true, the errors are shown when process is terminated
- * @param setIndeterminateFlag a flag indicating that progress should be configured as indeterminate
- * @return An exit code
- */
- public static int doSynchronously(final GitLineHandler handler,
- final String operationTitle,
- @NonNls final String operationName,
- final boolean showErrors,
- final boolean setIndeterminateFlag) {
+ public static int doSynchronously(final GitLineHandler handler, final String operationTitle, @NonNls final String operationName) {
final ProgressManager manager = ProgressManager.getInstance();
manager.run(new Task.Modal(handler.project(), operationTitle, false) {
public void run(@NotNull final ProgressIndicator indicator) {
- handler.addLineListener(new GitLineHandlerListenerProgress(indicator, handler, operationName, showErrors));
- runInCurrentThread(handler, indicator, setIndeterminateFlag, operationTitle);
+ handler.addLineListener(new GitLineHandlerListenerProgress(indicator, handler, operationName, true));
+ runInCurrentThread(handler, indicator, true, operationTitle);
}
});
if (!handler.isStarted()) {
@@ -131,26 +93,6 @@ public class GitHandlerUtil {
/**
- * Run handler synchronously. The method assumes that all listeners are set up.
- *
- * @param handler a handler to run
- * @param operationTitle operation title
- * @param manager a progress manager
- * @param setIndeterminateFlag if true handler is configured as indeterminate
- */
- private static void runHandlerSynchronously(final GitHandler handler,
- final String operationTitle,
- final ProgressManager manager,
- final boolean setIndeterminateFlag) {
- manager.runProcessWithProgressSynchronously(new Runnable() {
- public void run() {
- runInCurrentThread(handler, manager.getProgressIndicator(), setIndeterminateFlag,
- operationTitle);
- }
- }, operationTitle, false, handler.project());
- }
-
- /**
* Run handler in the current thread
*
* @param handler a handler to run
@@ -185,33 +127,6 @@ public class GitHandlerUtil {
handler.runInCurrentThread(postStartAction);
}
- /**
- * Run synchronously using progress indicator, but collect exceptions instead of showing error dialog
- *
- * @param handler a handler to use
- * @return the collection of exception collected during operation
- */
- public static Collection<VcsException> doSynchronouslyWithExceptions(final GitLineHandler handler) {
- final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
- return doSynchronouslyWithExceptions(handler, progressIndicator, null);
- }
-
- /**
- * Run synchronously using progress indicator, but collect exception instead of showing error dialog
- *
- * @param handler a handler to use
- * @param progressIndicator a progress indicator
- * @param operationName
- * @return the collection of exception collected during operation
- */
- public static Collection<VcsException> doSynchronouslyWithExceptions(final GitLineHandler handler,
- final ProgressIndicator progressIndicator,
- @Nullable String operationName) {
- handler.addLineListener(new GitLineHandlerListenerProgress(progressIndicator, handler, operationName, false));
- runInCurrentThread(handler, progressIndicator, false, operationName);
- return handler.errors();
- }
-
public static String formatOperationName(String operation, @NotNull VirtualFile root) {
return operation + " '" + root.getName() + "'...";
}
diff --git a/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java b/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java
index 141adca79937..5b3a2422254f 100644
--- a/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java
+++ b/plugins/git4idea/src/git4idea/commands/GitHttpGuiAuthenticator.java
@@ -25,13 +25,14 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.AuthData;
import com.intellij.util.UriUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.URLUtil;
import com.intellij.vcsUtil.AuthDialog;
-import git4idea.jgit.GitHttpAuthDataProvider;
+import git4idea.remote.GitHttpAuthDataProvider;
import git4idea.remote.GitRememberedInputs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -126,15 +127,8 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator {
return login;
}
- final AuthDialog dialog = new AuthDialog(myProject, myTitle, "Enter credentials for " + url, login, null, true);
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
- @Override
- public void run() {
- dialog.show();
- }
- }, myModalityState == null ? ModalityState.defaultModalityState() : myModalityState);
-
- if (!dialog.isOK()) {
+ AuthDialog dialog = showAuthDialog(url, login);
+ if (dialog == null || !dialog.isOK()) {
myWasCancelled = true;
return "";
}
@@ -149,6 +143,19 @@ class GitHttpGuiAuthenticator implements GitHttpAuthenticator {
return myLogin;
}
+ @Nullable
+ private AuthDialog showAuthDialog(final String url, final String login) {
+ final Ref<AuthDialog> dialog = Ref.create();
+ ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ dialog.set(new AuthDialog(myProject, myTitle, "Enter credentials for " + url, login, null, true));
+ dialog.get().show();
+ }
+ }, myModalityState == null ? ModalityState.defaultModalityState() : myModalityState);
+ return dialog.get();
+ }
+
@Override
public void saveAuthData() {
// save login and url
diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java
index b94cef0004ac..3e14a6414704 100644
--- a/plugins/git4idea/src/git4idea/commands/GitImpl.java
+++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java
@@ -373,7 +373,7 @@ public class GitImpl implements Git {
public GitCommandResult push(@NotNull final GitRepository repository, @NotNull final String remote, @NotNull final String url,
@NotNull final String spec, final boolean updateTracking,
@NotNull final GitLineHandlerListener... listeners) {
- return runRemoteCommand(new Computable<GitLineHandler>() {
+ return runCommand(new Computable<GitLineHandler>() {
@Override
public GitLineHandler compute() {
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(),
@@ -451,7 +451,7 @@ public class GitImpl implements Git {
@NotNull
public GitCommandResult fetch(@NotNull final GitRepository repository, @NotNull final String url, @NotNull final String remote,
@NotNull final List<GitLineHandlerListener> listeners, final String... params) {
- return runRemoteCommand(new Computable<GitLineHandler>() {
+ return runCommand(new Computable<GitLineHandler>() {
@Override
public GitLineHandler compute() {
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(),
@@ -543,7 +543,7 @@ public class GitImpl implements Git {
@Override
@NotNull
- public GitCommandResult runRemoteCommand(@NotNull Computable<GitLineHandler> handlerConstructor) {
+ public GitCommandResult runCommand(@NotNull Computable<GitLineHandler> handlerConstructor) {
return run(handlerConstructor);
}
diff --git a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
index 91114f05cdfd..5e66246805d0 100644
--- a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
+++ b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
@@ -34,6 +34,9 @@ import java.io.File;
* simple commands.
*/
public class GitSimpleHandler extends GitTextHandler {
+
+ public static final String DURING_EXECUTING_ERROR_MESSAGE = "during executing";
+
/**
* Stderr output
*/
@@ -235,7 +238,7 @@ public class GitSimpleHandler extends GitTextHandler {
});
runInCurrentThread(null);
if (ex[0] != null) {
- throw new VcsException(ex[0].getMessage() + " during executing " + printableCommandLine(), ex[0]);
+ throw new VcsException(ex[0].getMessage() + " " + DURING_EXECUTING_ERROR_MESSAGE + " " + printableCommandLine(), ex[0]);
}
if (result[0] == null) {
throw new VcsException("The git command returned null: " + printableCommandLine());
diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java
deleted file mode 100644
index dc468653b6f5..000000000000
--- a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.jgit;
-
-import com.intellij.ide.passwordSafe.PasswordSafe;
-import com.intellij.ide.passwordSafe.PasswordSafeException;
-import com.intellij.ide.passwordSafe.config.PasswordSafeSettings;
-import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl;
-import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.AuthData;
-import com.intellij.util.proxy.CommonProxy;
-import git4idea.GitBranch;
-import git4idea.GitUtil;
-import git4idea.GitVcs;
-import git4idea.push.GitSimplePushResult;
-import git4idea.remote.GitRememberedInputs;
-import git4idea.repo.GitRemote;
-import git4idea.repo.GitRepository;
-import git4idea.update.GitFetchResult;
-import git4idea.update.GitFetcher;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.InvalidRemoteException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.errors.NoRemoteRepositoryException;
-import org.eclipse.jgit.errors.NotSupportedException;
-import org.eclipse.jgit.errors.TransportException;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
-import org.eclipse.jgit.transport.RefSpec;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Handles remote operations over HTTP via JGit library.
- *
- * @author Kirill Likhodedov
- */
-public final class GitHttpAdapter {
-
- private static final Logger LOG = Logger.getInstance(GitHttpAdapter.class);
-
- private static final String IGNORECASE_SETTING = "ignorecase";
-
- public static boolean shouldUseJGit(@NotNull String url) {
- return "jgit".equals(System.getProperty("git.http"));
- }
-
- private enum GeneralResult {
- SUCCESS,
- CANCELLED,
- NOT_AUTHORIZED
- }
-
- private GitHttpAdapter() {
- }
-
- /**
- * Fetches the given remote in the given Git repository.
- * Asks username and password if needed.
- */
- @NotNull
- public static GitFetchResult fetch(@NotNull final GitRepository repository, @NotNull final GitRemote remote,
- @NotNull String remoteUrl, @Nullable String remoteBranch) {
- GitFetchResult.Type resultType;
- try {
- final Git git = convertToGit(repository);
- final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl);
-
- List<String> specs;
- if (remoteBranch == null) {
- specs = remote.getFetchRefSpecs();
- }
- else {
- specs = Collections.singletonList(GitFetcher.getFetchSpecForBranch(remoteBranch, remote.getName()));
- }
-
- GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Fetch(git, provider, remoteUrl, convertRefSpecs(specs)),
- repository.getProject());
- resultType = convertToFetchResultType(result);
- } catch (IOException e) {
- logException(repository, remote.getName(), remoteUrl, e, "fetching");
- return GitFetchResult.error(e);
- }
- catch (InvalidRemoteException e) {
- logException(repository, remote.getName(), remoteUrl, e, "fetching");
- return GitFetchResult.error(e);
- }
- catch (URISyntaxException e) {
- logException(repository, remote.getName(), remoteUrl, e, "fetching");
- return GitFetchResult.error(e);
- }
- return new GitFetchResult(resultType);
- }
-
- @NotNull
- private static List<RefSpec> convertRefSpecs(@NotNull List<String> refSpecs) {
- List<RefSpec> jgitSpecs = new ArrayList<RefSpec>();
- for (String spec : refSpecs) {
- jgitSpecs.add(new RefSpec(spec));
- }
- return jgitSpecs;
- }
-
- private static void logException(GitRepository repository, String remoteName, String remoteUrl, Exception e, String operation) {
- LOG.error("Exception while " + operation + " " + remoteName + "(" + remoteUrl + ")" + " in " + repository.toLogString(), e);
- }
-
- private static GitFetchResult.Type convertToFetchResultType(GeneralResult result) {
- switch (result) {
- case CANCELLED: return GitFetchResult.Type.CANCELLED;
- case SUCCESS: return GitFetchResult.Type.SUCCESS;
- case NOT_AUTHORIZED: return GitFetchResult.Type.NOT_AUTHORIZED;
- }
- return GitFetchResult.Type.CANCELLED;
- }
-
- @NotNull
- public static GitSimplePushResult push(@NotNull final GitRepository repository, @NotNull final String remoteName,
- @NotNull final String remoteUrl, @NotNull String pushSpec) {
- try {
- final Git git = convertToGit(repository);
- final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl);
- GitHttpRemoteCommand.Push pushCommand = new GitHttpRemoteCommand.Push(git, provider, remoteName, remoteUrl,
- convertRefSpecs(Collections.singletonList(pushSpec)));
- GeneralResult result = callWithAuthRetry(pushCommand, repository.getProject());
- GitSimplePushResult pushResult = pushCommand.getResult();
- if (pushResult == null) {
- return convertToPushResultType(result);
- } else {
- return pushResult;
- }
- }
- catch (SmartPushNotSupportedException e) {
- return GitSimplePushResult.error("Remote <code>" + remoteUrl + "</code> doesn't support <a href=\"http://progit.org/2010/03/04/smart-http.html\">" +
- "smart HTTP push. </a><br/>" +
- "Please set the server to use smart push or use other protocol (SSH for example). <br/>" +
- "If neither is possible, as a workaround you may add authentication data directly to the remote url in <code>.git/config</code>.");
- }
- catch (InvalidRemoteException e) {
- logException(repository, remoteName, remoteUrl, e, "pushing");
- return makeErrorResultFromException(e);
- }
- catch (IOException e) {
- logException(repository, remoteName, remoteUrl, e, "pushing");
- return makeErrorResultFromException(e);
- }
- catch (URISyntaxException e) {
- logException(repository, remoteName, remoteUrl, e, "pushing");
- return makeErrorResultFromException(e);
- }
- }
-
- @NotNull
- public static Collection<String> lsRemote(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String remoteUrl) {
- try {
- final Git git = convertToGit(repository);
- final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl);
- GitHttpRemoteCommand.LsRemote lsRemoteCommand = new GitHttpRemoteCommand.LsRemote(git, provider, remoteUrl);
- callWithAuthRetry(lsRemoteCommand, repository.getProject());
- return convertRefsToStrings(lsRemoteCommand.getRefs());
- } catch (IOException e) {
- logException(repository, remoteName, remoteUrl, e, "ls-remote");
- }
- catch (InvalidRemoteException e) {
- logException(repository, remoteName, remoteUrl, e, "ls-remote");
- }
- catch (URISyntaxException e) {
- logException(repository, remoteName, remoteUrl, e, "ls-remote");
- }
- return Collections.emptyList();
- }
-
- @NotNull
- private static Collection<String> convertRefsToStrings(@NotNull Collection<Ref> lsRemoteCommandRefs) {
- Collection<String> refs = new ArrayList<String>();
- for (Ref ref : lsRemoteCommandRefs) {
- String refName = ref.getName();
- if (refName.startsWith(GitBranch.REFS_HEADS_PREFIX)) {
- refName = refName.substring(GitBranch.REFS_HEADS_PREFIX.length());
- }
- refs.add(refName);
- }
- return refs;
- }
-
- @NotNull
- public static GitFetchResult cloneRepository(@NotNull Project project, @NotNull final File directory, @NotNull final String url) {
- GitFetchResult.Type resultType;
- try {
- final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(project, url);
- GitHttpRemoteCommand.Clone command = new GitHttpRemoteCommand.Clone(directory, provider, url);
- GeneralResult result = callWithAuthRetry(command, project);
- resultType = convertToFetchResultType(result);
- if (resultType.equals(GitFetchResult.Type.SUCCESS)) {
- updateCoreIgnoreCaseSetting(command.getGit());
- }
- return new GitFetchResult(resultType);
- }
- catch (InvalidRemoteException e) {
- LOG.info("Exception while cloning " + url + " to " + directory, e);
- return GitFetchResult.error(e);
- }
- catch (IOException e) {
- LOG.info("Exception while cloning " + url + " to " + directory, e);
- return GitFetchResult.error(e);
- }
- catch (URISyntaxException e) {
- LOG.info("Exception while cloning " + url + " to " + directory, e);
- return GitFetchResult.error(e);
- }
- }
-
- private static void updateCoreIgnoreCaseSetting(@Nullable Git git) {
- if (SystemInfo.isFileSystemCaseSensitive) {
- return;
- }
- if (git == null) {
- LOG.info("jgit.Git is null, the command should have failed. Not updating the settings.");
- return;
- }
- StoredConfig config = git.getRepository().getConfig();
- config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, IGNORECASE_SETTING, Boolean.TRUE.toString());
- try {
- config.save();
- }
- catch (IOException e) {
- LOG.info("Couldn't save config for " + git.getRepository().getDirectory().getPath(), e);
- }
- }
-
- @NotNull
- private static GitSimplePushResult convertToPushResultType(GeneralResult result) {
- switch (result) {
- case SUCCESS:
- return GitSimplePushResult.success();
- case CANCELLED:
- return GitSimplePushResult.cancel();
- case NOT_AUTHORIZED:
- return GitSimplePushResult.notAuthorized();
- default:
- return GitSimplePushResult.cancel();
- }
- }
-
-
- @NotNull
- private static GitSimplePushResult makeErrorResultFromException(Exception e) {
- return GitSimplePushResult.error(e.toString());
- }
-
- /**
- * Calls the given runnable.
- * If user cancels the authentication dialog, returns.
- * If user enters incorrect data, he has 2 more attempts to go before failure.
- * Cleanups are executed after each incorrect attempt to enter password, and after other retriable actions.
- */
- private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command, @NotNull Project project) throws InvalidRemoteException, IOException, URISyntaxException {
- boolean httpTransportErrorFixTried = false;
- boolean noRemoteWithoutGitErrorFixTried = false;
-
- String url = command.getUrl();
- GitHttpCredentialsProvider provider = command.getCredentialsProvider();
- try {
- for (int i = 0; i < 3; i++) {
- try {
- AuthData authData = getUsernameAndPassword(provider.getProject(), provider.getUrl());
- if (authData != null) {
- provider.fillAuthDataIfNotFilled(authData.getLogin(), authData.getPassword());
- }
- if (i == 0) {
- provider.setAlwaysShowDialog(false); // if username and password are supplied, no need to show the dialog
- } else {
- provider.setAlwaysShowDialog(true); // unless these values fail authentication
- }
- command.run();
- rememberPassword(provider);
- return GeneralResult.SUCCESS;
- }
- catch (GitAPIException e) {
- if (!noRemoteWithoutGitErrorFixTried && isNoRemoteWithoutDotGitError(e, url)) {
- url = addDotGitToUrl(url);
- command.setUrl(url);
- provider.setUrl(url);
- noRemoteWithoutGitErrorFixTried = true;
- // don't "eat" one password entering attempt
- //noinspection AssignmentToForLoopParameter
- i--;
- }
- command.cleanup();
- }
- catch (JGitInternalException e) {
- try {
- if (authError(e)) {
- if (provider.wasCancelled()) { // if user cancels the dialog, just return
- return GeneralResult.CANCELLED;
- }
- // otherwise give more tries to enter password
- }
- else if (!httpTransportErrorFixTried && isTransportExceptionForHttp(e, url)) {
- url = url.replaceFirst("http", "https");
- command.setUrl(url);
- provider.setUrl(url);
- httpTransportErrorFixTried = true;
- // don't "eat" one password entering attempt
- //noinspection AssignmentToForLoopParameter
- i--;
- }
- else if (!noRemoteWithoutGitErrorFixTried && isNoRemoteWithoutDotGitError(e, url)) {
- url = addDotGitToUrl(url);
- command.setUrl(url);
- provider.setUrl(url);
- noRemoteWithoutGitErrorFixTried = true;
- // don't "eat" one password entering attempt
- //noinspection AssignmentToForLoopParameter
- i--;
- }
- else if (smartHttpPushNotSupported(e)) {
- throw new SmartPushNotSupportedException(e.getCause().getMessage());
- }
- else {
- throw e;
- }
- }
- finally {
- command.cleanup();
- }
- }
- }
- return GeneralResult.NOT_AUTHORIZED;
- }
- finally {
- log(command, project);
- }
- }
-
- private static CommonProxy.HostInfo getHostInfo(String url) throws URISyntaxException {
- final boolean isSecure = url.startsWith("https");
- final String protocol = isSecure ? "https" : "http";
- final URI uri = new URI(url);
- int port = uri.getPort();
- port = port < 0 ? (isSecure ? 443 : 80) : port;
- return new CommonProxy.HostInfo(protocol, uri.getHost(), port);
- }
-
- @NotNull
- private static String addDotGitToUrl(@NotNull String url) {
- if (url.endsWith("/")) {
- url = url.substring(0, url.length() - 1);
- }
- return url + GitUtil.DOT_GIT;
- }
-
- private static void log(@NotNull GitHttpRemoteCommand command, @NotNull Project project) {
- GitVcs vcs = GitVcs.getInstance(project);
- if (vcs != null) {
- vcs.showCommandLine(command.getCommandString());
- }
- LOG.info(command.getLogString());
- }
-
- private static boolean smartHttpPushNotSupported(JGitInternalException e) {
- if (e.getCause() instanceof NotSupportedException) {
- NotSupportedException nse = (NotSupportedException)e.getCause();
- String message = nse.getMessage();
- return message != null && message.toLowerCase().contains("smart http push");
- }
- return false;
- }
-
- private static boolean isNoRemoteWithoutDotGitError(Throwable e, String url) {
- Throwable cause = e.getCause();
- if (cause == null || (!(cause instanceof NoRemoteRepositoryException) && !(cause.getCause() instanceof NoRemoteRepositoryException))) {
- return false;
- }
- return !url.toLowerCase().endsWith(GitUtil.DOT_GIT);
- }
-
- private static boolean isTransportExceptionForHttp(@NotNull JGitInternalException e, @NotNull String url) {
- if (!(e.getCause() instanceof TransportException)) {
- return false;
- }
- return url.toLowerCase().startsWith("http") && !url.toLowerCase().startsWith("https");
- }
-
- private static void rememberPassword(@NotNull GitHttpCredentialsProvider credentialsProvider) {
- if (!credentialsProvider.wasDialogShown()) { // the dialog is not shown => everything is already stored
- return;
- }
- final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
- if (passwordSafe.getSettings().getProviderType() == PasswordSafeSettings.ProviderType.DO_NOT_STORE) {
- return;
- }
- String login = credentialsProvider.getUserName();
- if (login == null || credentialsProvider.getPassword() == null) {
- return;
- }
-
- String url = adjustHttpUrl(credentialsProvider.getUrl());
- String key = keyForUrlAndLogin(url, login);
- try {
- // store in memory always
- storePassword(passwordSafe.getMemoryProvider(), credentialsProvider, key);
- if (credentialsProvider.isRememberPassword()) {
- storePassword(passwordSafe.getMasterKeyProvider(), credentialsProvider, key);
- }
- GitRememberedInputs.getInstance().addUrl(url, login);
- }
- catch (PasswordSafeException e) {
- LOG.info("Couldn't store the password for key [" + key + "]", e);
- }
- }
-
- private static void storePassword(PasswordSafeProvider passwordProvider, GitHttpCredentialsProvider credentialsProvider, String key) throws PasswordSafeException {
- passwordProvider.storePassword(credentialsProvider.getProject(), GitHttpCredentialsProvider.class, key, credentialsProvider.getPassword());
- }
-
- @Nullable
- private static AuthData getUsernameAndPassword(Project project, String url) {
- url = adjustHttpUrl(url);
- String userName = GitRememberedInputs.getInstance().getUserNameForUrl(url);
- if (userName == null) {
- return trySavedAuthDataFromProviders(url);
- }
- String key = keyForUrlAndLogin(url, userName);
- final PasswordSafe passwordSafe = PasswordSafe.getInstance();
- try {
- String password = passwordSafe.getPassword(project, GitHttpCredentialsProvider.class, key);
- if (password != null) {
- return new AuthData(userName, password);
- }
- return null;
- }
- catch (PasswordSafeException e) {
- LOG.info("Couldn't get the password for key [" + key + "]", e);
- return null;
- }
- }
-
- @Nullable
- private static AuthData trySavedAuthDataFromProviders(@NotNull String url) {
- GitHttpAuthDataProvider[] extensions = GitHttpAuthDataProvider.EP_NAME.getExtensions();
- for (GitHttpAuthDataProvider provider : extensions) {
- AuthData authData = provider.getAuthData(url);
- if (authData != null) {
- return authData;
- }
- }
- return null;
- }
-
- /**
- * If url is HTTPS, store it as HTTP in the password database, not to make user enter and remember same credentials twice.
- */
- @NotNull
- private static String adjustHttpUrl(@NotNull String url) {
- if (url.startsWith("https")) {
- return url.replaceFirst("https", "http");
- }
- return url;
- }
-
- @NotNull
- private static String keyForUrlAndLogin(@NotNull String stringUrl, @NotNull String login) {
- return login + ":" + stringUrl;
- }
-
- private static boolean authError(@NotNull JGitInternalException e) {
- Throwable cause = e.getCause();
- return (cause instanceof TransportException && cause.getMessage().contains("not authorized"));
- }
-
- /**
- * Converts {@link GitRepository} to JGit's {@link Repository}.
- */
- @NotNull
- private static Repository convert(@NotNull GitRepository repository) throws IOException {
- FileRepositoryBuilder builder = new FileRepositoryBuilder();
- return builder.setGitDir(new File(repository.getRoot().getPath(), GitUtil.DOT_GIT))
- .readEnvironment() // scan environment GIT_* variables
- .findGitDir() // scan up the file system tree
- .build();
- }
-
- /**
- * Converts {@link GitRepository} to JGit's {@link Git} object.
- */
- private static Git convertToGit(@NotNull GitRepository repository) throws IOException {
- return Git.wrap(convert(repository));
- }
-
- private static class SmartPushNotSupportedException extends NotSupportedException {
- private SmartPushNotSupportedException(String message) {
- super(message);
- }
- }
-}
diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpCredentialsProvider.java b/plugins/git4idea/src/git4idea/jgit/GitHttpCredentialsProvider.java
deleted file mode 100644
index e37796636ea2..000000000000
--- a/plugins/git4idea/src/git4idea/jgit/GitHttpCredentialsProvider.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.jgit;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.vcsUtil.AuthDialog;
-import org.eclipse.jgit.errors.UnsupportedCredentialItem;
-import org.eclipse.jgit.transport.CredentialItem;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.URIish;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author Kirill Likhodedov
- */
-public class GitHttpCredentialsProvider extends CredentialsProvider {
-
- private static final Pattern HTTP_URL_PATTERN = Pattern.compile("http(?:s?)://(?:([\\S^@\\.]*)@)?.*");
-
- private final Project myProject;
- private String myRemoteUrl;
-
- private boolean myCancelled;
- private boolean myRememberPassword;
- private String myPassword;
- private String myUserName;
- private boolean myShowDialog;
- private boolean myDialogShown;
-
- public GitHttpCredentialsProvider(@NotNull Project project, @NotNull String remoteUrl) {
- myProject = project;
- myRemoteUrl = remoteUrl;
- }
-
- @Override
- public boolean isInteractive() {
- return true;
- }
-
- @Override
- public boolean supports(CredentialItem... items) {
- for (CredentialItem item : items) {
- if (item instanceof CredentialItem.Password) {
- continue;
- }
- if (item instanceof CredentialItem.Username) {
- continue;
- }
- return false;
- }
- return true;
- }
-
- @Override
- public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
- CredentialItem.Username userNameItem = null;
- CredentialItem.Password passwordItem = null;
- for (CredentialItem item : items) {
- if (item instanceof CredentialItem.Username) {
- userNameItem = (CredentialItem.Username)item;
- } else if (item instanceof CredentialItem.Password) {
- passwordItem = (CredentialItem.Password)item;
- }
- }
-
- if (userNameItem != null || passwordItem != null) {
- String username = getUserNameFromUrl(myRemoteUrl);
- String password = null;
- if (username == null) { // username is not in the url => reading pre-filled value from the password storage
- username = myUserName;
- password = myPassword;
- } else if (username.equals(myUserName)) { // username is in url => read password only if it is for the same user
- password = myPassword;
- }
-
- boolean rememberPassword = myRememberPassword;
- boolean ok;
- if (username != null && password != null && !myShowDialog) {
- ok = true;
- myDialogShown = false;
- } else {
- final AuthDialog dialog = new AuthDialog(myProject, "Login required", "Login to " + myRemoteUrl, username, password, false);
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
- @Override
- public void run() {
- dialog.show();
- }
- });
- ok = dialog.isOK();
- myDialogShown = true;
- if (ok) {
- username = dialog.getUsername();
- password = dialog.getPassword();
- rememberPassword = dialog.isRememberPassword();
- }
- }
-
- if (ok) {
- if (userNameItem != null) {
- userNameItem.setValue(username);
- }
- if (passwordItem != null) {
- passwordItem.setValue(password.toCharArray());
- }
- myRememberPassword = rememberPassword;
- myPassword = password;
- myUserName = username;
- }
- else {
- myCancelled = true;
- myRememberPassword = false; // in case of re-usage of the provider
- }
- return ok;
- }
- return true;
- }
-
- public boolean isRememberPassword() {
- return myRememberPassword;
- }
-
- @NotNull
- public Project getProject() {
- return myProject;
- }
-
- @Nullable
- public String getPassword() {
- return myPassword;
- }
-
- @Nullable
- public String getUserName() {
- return myUserName;
- }
-
- @NotNull
- public String getUrl() {
- return myRemoteUrl;
- }
-
- public void setUrl(@NotNull String url) {
- myRemoteUrl = url;
- }
-
- public void fillAuthDataIfNotFilled(@NotNull String login, @Nullable String password) {
- if (myUserName == null) {
- myUserName = login;
- myPassword = password;
- } else if (myPassword != null) {
- myPassword = password;
- }
- }
-
- public void setAlwaysShowDialog(boolean showDialog) {
- myShowDialog = showDialog;
- }
-
- public boolean wasDialogShown() {
- return myDialogShown;
- }
-
- @Nullable
- private static String getUserNameFromUrl(@NotNull String url) {
- Matcher matcher = HTTP_URL_PATTERN.matcher(url);
- if (matcher.matches()) {
- return matcher.group(1);
- }
- return null;
- }
-
- public boolean wasCancelled() {
- return myCancelled;
- }
-}
diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java
deleted file mode 100644
index 3d2a9653440b..000000000000
--- a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package git4idea.jgit;
-
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
-import git4idea.push.GitSimplePushResult;
-import org.eclipse.jgit.api.CloneCommand;
-import org.eclipse.jgit.api.FetchCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.PushCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.InvalidRemoteException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.errors.NotSupportedException;
-import org.eclipse.jgit.errors.TransportException;
-import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.text.MessageFormat;
-import java.util.*;
-
-/**
- * @author Kirill Likhodedov
- */
-interface GitHttpRemoteCommand {
-
- String getUrl();
- void setUrl(String url);
- void run() throws GitAPIException, URISyntaxException, TransportException;
- void cleanup();
- GitHttpCredentialsProvider getCredentialsProvider();
- String getLogString();
- String getCommandString();
-
- class Fetch implements GitHttpRemoteCommand {
-
- private final Git myGit;
- private final GitHttpCredentialsProvider myCredentialsProvider;
- private String myUrl;
- private final List<RefSpec> myRefSpecs;
-
- Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url, @NotNull List<RefSpec> refSpecs) {
- myGit = git;
- myCredentialsProvider = credentialsProvider;
- myUrl = url;
- myRefSpecs = refSpecs;
- }
-
- @Override
- public void run() throws GitAPIException {
- FetchCommand fetchCommand = myGit.fetch();
- fetchCommand.setRemote(myUrl);
- fetchCommand.setRefSpecs(myRefSpecs);
- fetchCommand.setCredentialsProvider(myCredentialsProvider);
- fetchCommand.call();
- }
-
- @Override
- public void setUrl(@NotNull String url) {
- myUrl = url;
- }
-
- @Override
- public String getUrl() {
- return myUrl;
- }
-
- @Override
- public GitHttpCredentialsProvider getCredentialsProvider() {
- return myCredentialsProvider;
- }
-
- @Override
- public String getLogString() {
- return getCommandString();
- }
-
- @Override
- public String getCommandString() {
- return String.format("git fetch %s %s", myUrl, getRefspecsAsString(myRefSpecs));
- }
-
- static String getRefspecsAsString(@NotNull List<RefSpec> refSpecs) {
- return StringUtil.join(refSpecs, new Function<RefSpec, String>() {
- @Override
- public String fun(RefSpec spec) {
- return spec.toString();
- }
- }, " ");
- }
-
- @Override
- public void cleanup() {
- }
- }
-
- class Clone implements GitHttpRemoteCommand {
-
- private final File myTargetDirectory;
- private final GitHttpCredentialsProvider myCredentialsProvider;
- private String myUrl;
- @Nullable private Git myGit;
-
- Clone(@NotNull File targetDirectory, @NotNull GitHttpCredentialsProvider credentialsProvider, String url) {
- myTargetDirectory = targetDirectory;
- myCredentialsProvider = credentialsProvider;
- myUrl = url;
- }
-
- @Override
- public void run() throws GitAPIException {
- CloneCommand cloneCommand = Git.cloneRepository();
- cloneCommand.setDirectory(myTargetDirectory);
- cloneCommand.setURI(myUrl);
- cloneCommand.setCredentialsProvider(myCredentialsProvider);
- myGit = cloneCommand.call();
- }
-
- @Override
- public void setUrl(@NotNull String url) {
- myUrl = url;
- }
-
- @Override
- public String getUrl() {
- return myUrl;
- }
-
- @Override
- public GitHttpCredentialsProvider getCredentialsProvider() {
- return myCredentialsProvider;
- }
-
- @Override
- public String getLogString() {
- return getCommandString();
- }
-
- @Override
- public String getCommandString() {
- return String.format("git clone %s %s", myUrl, myTargetDirectory.getPath());
- }
-
- @Override
- public void cleanup() {
- if (myTargetDirectory.exists()) {
- FileUtil.delete(myTargetDirectory);
- }
- }
-
- @Nullable
- public Git getGit() {
- return myGit;
- }
- }
-
- class Push implements GitHttpRemoteCommand {
-
- private final Git myGit;
- private final GitHttpCredentialsProvider myCredentialsProvider;
- private GitSimplePushResult myPushResult;
- private String myRemoteName;
- private String myUrl;
- private final List<RefSpec> myPushSpecs;
-
- Push(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String remoteName, @NotNull String url, @NotNull List<RefSpec> pushSpecs) {
- myGit = git;
- myCredentialsProvider = credentialsProvider;
- myRemoteName = remoteName;
- myUrl = url;
- myPushSpecs = pushSpecs;
- }
-
- @Override
- public void run() throws InvalidRemoteException, URISyntaxException, org.eclipse.jgit.api.errors.TransportException {
- PushCommand pushCommand = myGit.push();
- pushCommand.setRemote(myRemoteName);
- pushCommand.setRefSpecs(myPushSpecs);
- pushCommand.setCredentialsProvider(myCredentialsProvider);
-
- /*
- Need to push to remote NAME (to let push update the remote reference), but to probably another URL.
- So constructing RemoteConfig based on the original config for the remote, but with other url.
- No need in fetch urls => just removing them.
- Remove all push urls (we don't support pushing to multiple urls anyway yet), leaving only single correct url.
- Then pass the url to the push command.
- */
- RemoteConfig rc = new RemoteConfig(myGit.getRepository().getConfig(), myRemoteName);
- List<URIish> uris = new ArrayList<URIish>(rc.getURIs());
- for (URIish uri : uris) {
- rc.removeURI(uri);
- }
- uris = new ArrayList<URIish>(rc.getPushURIs());
- for (URIish uri : uris) {
- rc.removePushURI(uri);
- }
- rc.addPushURI(new URIish(myUrl));
-
- Iterable<PushResult> results = call(pushCommand, rc);
- myPushResult = analyzeResults(results);
- }
-
- @Override
- public void setUrl(@NotNull String url) {
- myUrl = url;
- }
-
- @Override
- public String getUrl() {
- return myUrl;
- }
-
- @Override
- public GitHttpCredentialsProvider getCredentialsProvider() {
- return myCredentialsProvider;
- }
-
- @Override
- public String getLogString() {
- return String.format("git push %s (%s) %s", myRemoteName, myUrl, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs));
- }
-
- @Override
- public String getCommandString() {
- return String.format("git push %s %s", myRemoteName, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs));
- }
-
- @Override
- public void cleanup() {
- }
-
- @Nullable
- GitSimplePushResult getResult() {
- return myPushResult;
- }
-
- @NotNull
- private static GitSimplePushResult analyzeResults(@NotNull Iterable<PushResult> results) {
- Collection<String> rejectedBranches = new ArrayList<String>();
- StringBuilder errorReport = new StringBuilder();
-
- for (PushResult result : results) {
- for (RemoteRefUpdate update : result.getRemoteUpdates()) {
- switch (update.getStatus()) {
- case REJECTED_NONFASTFORWARD:
- rejectedBranches.add(update.getSrcRef());
- // no break: add reject to the output
- case NON_EXISTING:
- case REJECTED_NODELETE:
- case REJECTED_OTHER_REASON:
- case REJECTED_REMOTE_CHANGED:
- errorReport.append(update.getSrcRef() + ": " + update.getStatus() + "<br/>");
- default:
- // on success do nothing
- }
- }
- }
-
- if (!rejectedBranches.isEmpty()) {
- return GitSimplePushResult.reject(rejectedBranches);
- }
- else if (errorReport.toString().isEmpty()) {
- return GitSimplePushResult.success();
- }
- else {
- return GitSimplePushResult.error(errorReport.toString());
- }
- }
-
-
- /*
- A copy-paste from org.eclipse.jgit.api.PushCommand#call with the following differences:
- 1. Fields are not accessible, so they are substituted by getters, except for credentialsProvider, which we have stored as an instance field.
- 2. checkCallable() won't fail (according to the PushCommand code), so it's safe to remove it.
- 3. Actual push is performed via
- Transport.openAll(repo, remoteConfig, Transport.Operation.PUSH)
- instead of
- Transport.openAll(repo, remote, Transport.Operation.PUSH)
- where remoteConfig is passed to the method.
- Original code constructs the remoteConfig based on .git/config.
- */
- @NotNull
- private Iterable<PushResult> call(PushCommand pushCommand, RemoteConfig remoteConfig)
- throws JGitInternalException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException
- {
- ArrayList<PushResult> pushResults = new ArrayList<PushResult>(3);
-
- List<RefSpec> refSpecs = pushCommand.getRefSpecs();
- Repository repo = pushCommand.getRepository();
- boolean force = pushCommand.isForce();
- int timeout = pushCommand.getTimeout();
- CredentialsProvider credentialsProvider = myCredentialsProvider;
- String receivePack = pushCommand.getReceivePack();
- boolean thin = pushCommand.isThin();
- boolean dryRun = pushCommand.isDryRun();
- String remote = pushCommand.getRemote();
- ProgressMonitor monitor = pushCommand.getProgressMonitor();
-
- try {
- if (refSpecs.isEmpty()) {
- RemoteConfig config = new RemoteConfig(repo.getConfig(), pushCommand.getRemote());
- refSpecs.addAll(config.getPushRefSpecs());
- }
- if (refSpecs.isEmpty()) {
- Ref head = repo.getRef(Constants.HEAD);
- if (head != null && head.isSymbolic()) {
- refSpecs.add(new RefSpec(head.getLeaf().getName()));
- }
- }
-
- if (force) {
- for (int i = 0; i < refSpecs.size(); i++) {
- refSpecs.set(i, refSpecs.get(i).setForceUpdate(true));
- }
- }
-
- final List<Transport> transports;
- transports = Transport.openAll(repo, remoteConfig, Transport.Operation.PUSH);
- for (final Transport transport : transports) {
- if (0 <= timeout) {
- transport.setTimeout(timeout);
- }
- transport.setPushThin(thin);
- if (receivePack != null) {
- transport.setOptionReceivePack(receivePack);
- }
- transport.setDryRun(dryRun);
- if (credentialsProvider != null) {
- transport.setCredentialsProvider(credentialsProvider);
- }
-
- final Collection<RemoteRefUpdate> toPush = transport
- .findRemoteRefUpdatesFor(refSpecs);
-
- try {
- PushResult result = transport.push(monitor, toPush);
- pushResults.add(result);
- }
- catch (TransportException e) {
- throw new org.eclipse.jgit.api.errors.TransportException(e.getMessage(), e);
- }
- finally {
- transport.close();
- }
- }
- }
- catch (URISyntaxException e) {
- throw new InvalidRemoteException(MessageFormat.format(
- JGitText.get().invalidRemote, remote));
- } catch (TransportException e) {
- throw new org.eclipse.jgit.api.errors.TransportException(
- e.getMessage(), e);
- }
- catch (NotSupportedException e) {
- throw new JGitInternalException(
- JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
- e);
- }
- catch (IOException e) {
- throw new JGitInternalException(
- JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
- e);
- }
-
- return pushResults;
- }
- }
-
- class LsRemote implements GitHttpRemoteCommand {
-
- private final Git myGit;
- private final GitHttpCredentialsProvider myCredentialsProvider;
- private String myUrl;
- private Collection<Ref> myResultRefs;
-
- public LsRemote(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url) {
- myGit = git;
- myCredentialsProvider = credentialsProvider;
- myUrl = url;
- }
-
- @Override
- public void run() throws InvalidRemoteException, TransportException {
- myResultRefs = call();
- }
-
- @Override
- public void cleanup() {
- }
-
- @Override
- public GitHttpCredentialsProvider getCredentialsProvider() {
- return myCredentialsProvider;
- }
-
- @Override
- public String getLogString() {
- return getCommandString();
- }
-
- @Override
- public String getCommandString() {
- return String.format("git ls-remote --heads %s ", myUrl);
- }
-
- @Override
- public String getUrl() {
- return myUrl;
- }
-
- @Override
- public void setUrl(@NotNull String url) {
- myUrl = url;
- }
-
- @NotNull
- public Collection<Ref> getRefs() {
- return myResultRefs == null ? Collections.<Ref>emptyList() : myResultRefs;
- }
-
- /*
- Copy-paste of org.eclipse.jgit.api.LsRemote#call with the following changes:
- 1. More specific exceptions declaration.
- 2. Use CredentialsProvider.
- 3. We don't need --tags, we always need --heads.
- */
- private Collection<Ref> call() throws TransportException, InvalidRemoteException {
- try {
- Transport transport = Transport.open(myGit.getRepository(), myUrl);
-
- try {
- Collection<RefSpec> refSpecs = new ArrayList<RefSpec>(1);
- refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*"));
- Collection<Ref> refs;
- Map<String, Ref> refmap = new HashMap<String, Ref>();
- transport.setCredentialsProvider(myCredentialsProvider);
- FetchConnection fc = transport.openFetch();
- try {
- refs = fc.getRefs();
- if (refSpecs.isEmpty()) {
- for (Ref r : refs) {
- refmap.put(r.getName(), r);
- }
- }
- else {
- for (Ref r : refs) {
- for (RefSpec rs : refSpecs) {
- if (rs.matchSource(r)) {
- refmap.put(r.getName(), r);
- break;
- }
- }
- }
- }
- }
- finally {
- fc.close();
- }
- return refmap.values();
- }
- catch (TransportException e) {
- throw new JGitInternalException(
- JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
- e);
- }
- finally {
- transport.close();
- }
- }
- catch (URISyntaxException e) {
- throw new InvalidRemoteException(MessageFormat.format(
- JGitText.get().invalidRemote, myUrl));
- }
- catch (NotSupportedException e) {
- throw new JGitInternalException(
- JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
- e);
- }
- }
- }
-}
-
-
diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeDialog.java b/plugins/git4idea/src/git4idea/merge/GitMergeDialog.java
index 294227718670..f8a05816ce26 100644
--- a/plugins/git4idea/src/git4idea/merge/GitMergeDialog.java
+++ b/plugins/git4idea/src/git4idea/merge/GitMergeDialog.java
@@ -27,6 +27,7 @@ import git4idea.commands.GitSimpleHandler;
import git4idea.i18n.GitBundle;
import git4idea.util.GitUIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -88,15 +89,6 @@ public class GitMergeDialog extends DialogWrapper {
@NotNull private final Project myProject;
private final GitVcs myVcs;
-
-
- /**
- * A constructor
- *
- * @param project a project to select
- * @param roots a git repository roots for the project
- * @param defaultRoot a guessed default root
- */
public GitMergeDialog(@NotNull Project project, List<VirtualFile> roots, VirtualFile defaultRoot) {
super(project, true);
setTitle(GitBundle.getString("merge.branch.title"));
@@ -125,9 +117,6 @@ public class GitMergeDialog extends DialogWrapper {
init();
}
- /**
- * Initialize {@link #myBranchChooser} component
- */
private void initBranchChooser() {
myBranchChooser = new ElementsChooser<String>(true);
myBranchChooser.setToolTipText(GitBundle.getString("merge.branches.tooltip"));
@@ -149,6 +138,11 @@ public class GitMergeDialog extends DialogWrapper {
myBranchChooser.addElementsMarkListener(listener);
}
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myBranchChooser.getComponent();
+ }
/**
* Setup branches for git root, this method should be called when root is changed.
@@ -204,32 +198,20 @@ public class GitMergeDialog extends DialogWrapper {
}
- /**
- * {@inheritDoc}
- */
protected JComponent createCenterPanel() {
return myPanel;
}
- /**
- * {@inheritDoc}
- */
@Override
protected String getDimensionServiceKey() {
return getClass().getName();
}
- /**
- * {@inheritDoc}
- */
@Override
protected String getHelpId() {
return "reference.VersionControl.Git.MergeBranches";
}
- /**
- * @return selected root
- */
public VirtualFile getSelectedRoot() {
return (VirtualFile)myGitRoot.getSelectedItem();
}
diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java
index 31e289dba806..778d2dcd0033 100644
--- a/plugins/git4idea/src/git4idea/push/GitPusher.java
+++ b/plugins/git4idea/src/git4idea/push/GitPusher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +36,6 @@ import git4idea.config.GitConfigUtil;
import git4idea.config.GitVcsSettings;
import git4idea.config.UpdateMethod;
import git4idea.history.GitHistoryUtils;
-import git4idea.jgit.GitHttpAdapter;
import git4idea.repo.GitBranchTrackInfo;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
@@ -48,7 +47,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Collects information to push and performs the push.
@@ -321,13 +320,8 @@ public final class GitPusher {
}
String url = pushUrls.iterator().next();
GitSimplePushResult pushResult;
- if (GitHttpAdapter.shouldUseJGit(url)) {
- pushResult = GitHttpAdapter.push(repository, remote.getName(), url, formPushSpec(pushSpec, remote));
- }
- else {
- pushResult = pushNatively(repository, pushSpec, url);
- }
-
+ pushResult = pushNatively(repository, pushSpec, url);
+
if (pushResult.getType() == GitSimplePushResult.Type.SUCCESS) {
setUpstream(repository, pushSpec.getSource(), pushSpec.getRemote(), pushSpec.getDest());
}
@@ -478,9 +472,7 @@ public final class GitPusher {
// and don't show the dialog again if user has chosen not to ask again
updateSettings = readUpdateSettings();
if (!mySettings.autoUpdateIfPushRejected()) {
- final GitRejectedPushUpdateDialog dialog = new GitRejectedPushUpdateDialog(myProject, rejectedPushesForCurrentBranch.keySet(), updateSettings);
- final int exitCode = showDialogAndGetExitCode(dialog);
- updateSettings = new UpdateSettings(dialog.shouldUpdateAll(), getUpdateMethodFromDialogExitCode(exitCode));
+ updateSettings = showDialogAndGetExitCode(rejectedPushesForCurrentBranch, updateSettings);
saveUpdateSettings(updateSettings);
}
}
@@ -519,20 +511,23 @@ public final class GitPusher {
return new UpdateSettings(updateAllRoots, updateMethod);
}
- private int showDialogAndGetExitCode(@NotNull final GitRejectedPushUpdateDialog dialog) {
- final AtomicInteger exitCode = new AtomicInteger();
+ private UpdateSettings showDialogAndGetExitCode(final Map<GitRepository, GitBranch> rejectedPushesForCurrentBranch,
+ final UpdateSettings initialSettings) {
+ final AtomicReference<UpdateSettings> updateSettings = new AtomicReference<UpdateSettings>();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
+ final GitRejectedPushUpdateDialog dialog = new GitRejectedPushUpdateDialog(myProject, rejectedPushesForCurrentBranch.keySet(), initialSettings);
dialog.show();
- exitCode.set(dialog.getExitCode());
- }
+ final int exitCode = dialog.getExitCode();
+ if (exitCode != DialogWrapper.CANCEL_EXIT_CODE) {
+ mySettings.setAutoUpdateIfPushRejected(dialog.shouldAutoUpdateInFuture());
+ }
+ updateSettings.set(new UpdateSettings(dialog.shouldUpdateAll(), getUpdateMethodFromDialogExitCode(exitCode)));
+
+ }
});
- int code = exitCode.get();
- if (code != DialogWrapper.CANCEL_EXIT_CODE) {
- mySettings.setAutoUpdateIfPushRejected(dialog.shouldAutoUpdateInFuture());
- }
- return code;
+ return updateSettings.get();
}
/**
diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java
index e0421b7bf67e..a85a328fc114 100644
--- a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java
+++ b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java
@@ -128,8 +128,8 @@ public class GitRebaser {
return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE;
} else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) {
LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout");
- UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject,
- untrackedWouldBeOverwrittenDetector.getFiles(), "rebase", null);
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root,
+ untrackedWouldBeOverwrittenDetector.getRelativeFilePaths(), "rebase", null);
return GitUpdateResult.ERROR;
} else {
LOG.info("handleRebaseFailure error " + pullHandler.errors());
@@ -382,8 +382,8 @@ public class GitRebaser {
return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE;
} else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) {
LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout");
- UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject,
- untrackedWouldBeOverwrittenDetector.getFiles(), "rebase", null);
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root,
+ untrackedWouldBeOverwrittenDetector.getRelativeFilePaths(), "rebase", null);
return GitUpdateResult.ERROR;
} else {
LOG.info("handleRebaseFailure error " + handler.errors());
diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpAuthDataProvider.java b/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java
index af4229d3ac25..6c0860ccf20a 100644
--- a/plugins/git4idea/src/git4idea/jgit/GitHttpAuthDataProvider.java
+++ b/plugins/git4idea/src/git4idea/remote/GitHttpAuthDataProvider.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package git4idea.jgit;
+package git4idea.remote;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.util.AuthData;
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
- * Provides authentication information to the {@link GitHttpAdapter} on attempt to connect an HTTP remote.
+ * Provides authentication information to the {@link git4idea.commands.GitHttpAuthenticator} on attempt to connect an HTTP remote.
* Useful for reusing Github credentials stored in the settings to connect the github remote (IDEA-87530).
*
* @author Kirill Likhodedov
diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java
index a88e7754b78e..4b0bdeadc8f9 100644
--- a/plugins/git4idea/src/git4idea/repo/GitConfig.java
+++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java
@@ -149,7 +149,7 @@ public class GitConfig {
ini.load(configFile);
}
catch (IOException e) {
- LOG.error(new RepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e));
+ LOG.warn(new RepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e));
return emptyConfig;
}
diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java
index 366bbde88050..5109d0600b69 100644
--- a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java
+++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java
@@ -221,7 +221,8 @@ class GitRepositoryReader {
return hashAndName.name.endsWith(ref);
}
});
- return hashAndNames.get(0).hash;
+ HashAndName item = ContainerUtil.getFirstItem(hashAndNames);
+ return item == null ? null : item.hash;
}
/**
diff --git a/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java
index a0ae58667c70..6bfa7aa090eb 100644
--- a/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java
+++ b/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java
@@ -107,7 +107,7 @@ public class GitShelveChangesSaver extends GitChangesSaver {
@Override
protected boolean wereChangesSaved() {
- return myShelvedLists != null;
+ return myShelvedLists != null && !myShelvedLists.isEmpty();
}
@Override
diff --git a/plugins/git4idea/src/git4idea/ui/ChangesBrowserWithRollback.java b/plugins/git4idea/src/git4idea/ui/ChangesBrowserWithRollback.java
new file mode 100644
index 000000000000..a33a7d13704a
--- /dev/null
+++ b/plugins/git4idea/src/git4idea/ui/ChangesBrowserWithRollback.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.ui;
+
+import com.intellij.openapi.actionSystem.EmptyAction;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangeListManager;
+import com.intellij.openapi.vcs.changes.actions.RollbackDialogAction;
+import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * {@link ChangesBrowser} extension with Rollback/Revert action added to the toolbar.
+ * After the revert completes, the changes list is automatically refreshed according to the actual changes
+ * retrieved from the {@link ChangeListManager}.
+ */
+public class ChangesBrowserWithRollback extends ChangesBrowser {
+ private final List<Change> myOriginalChanges;
+
+ public ChangesBrowserWithRollback(@NotNull Project project, @NotNull List<Change> changes) {
+ super(project, null, changes, null, false, true, null, MyUseCase.LOCAL_CHANGES, null);
+ myOriginalChanges = changes;
+ RollbackDialogAction rollback = new RollbackDialogAction();
+ EmptyAction.setupAction(rollback, IdeActions.CHANGES_VIEW_ROLLBACK, this);
+ addToolbarAction(rollback);
+ setChangesToDisplay(changes);
+ }
+
+ @Override
+ public void rebuildList() {
+ if (myOriginalChanges != null) { // null is possible because rebuildList is called during initialization
+ myChangesToDisplay = filterActualChanges(myProject, myOriginalChanges);
+ }
+ super.rebuildList();
+ }
+
+ @NotNull
+ private static List<Change> filterActualChanges(@NotNull Project project, @NotNull List<Change> originalChanges) {
+ final Collection<Change> allChanges = ChangeListManager.getInstance(project).getAllChanges();
+ return ContainerUtil.filter(originalChanges, new Condition<Change>() {
+ @Override
+ public boolean value(Change change) {
+ return allChanges.contains(change);
+ }
+ });
+ }
+}
diff --git a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java
index 63b51a8c4b56..3c8d7100c50c 100644
--- a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java
+++ b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java
@@ -29,7 +29,9 @@ import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
@@ -49,6 +51,7 @@ import git4idea.merge.GitConflictResolver;
import git4idea.repo.GitRepository;
import git4idea.stash.GitStashUtils;
import git4idea.util.GitUIUtil;
+import git4idea.util.UntrackedFilesNotifier;
import git4idea.validators.GitBranchNameValidator;
import org.jetbrains.annotations.NotNull;
@@ -397,7 +400,7 @@ public class GitUnstashDialog extends DialogWrapper {
@Override
protected void doOKAction() {
VirtualFile root = getGitRoot();
- GitLineHandler h = handler();
+ final GitLineHandler h = handler();
final AtomicBoolean conflict = new AtomicBoolean();
h.addLineListener(new GitLineHandlerAdapter() {
@@ -407,13 +410,27 @@ public class GitUnstashDialog extends DialogWrapper {
}
}
});
- int rc = GitHandlerUtil.doSynchronously(h, GitBundle.getString("unstash.unstashing"), h.printableCommandLine(), false);
- ServiceManager.getService(myProject, GitPlatformFacade.class).hardRefresh(root);
+ GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(root);
+ h.addLineListener(untrackedFilesDetector);
+ final Ref<GitCommandResult> result = Ref.create();
+ ProgressManager.getInstance().run(new Task.Modal(h.project(), GitBundle.getString("unstash.unstashing"), false) {
+ public void run(@NotNull final ProgressIndicator indicator) {
+ h.addLineListener(new GitHandlerUtil.GitLineHandlerListenerProgress(indicator, h, "stash", false));
+ Git git = ServiceManager.getService(Git.class);
+ result.set(git.runCommand(new Computable.PredefinedValueComputable<GitLineHandler>(h)));
+ }
+ });
+
+ ServiceManager.getService(myProject, GitPlatformFacade.class).hardRefresh(root);
+ GitCommandResult res = result.get();
if (conflict.get()) {
boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge();
LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved);
- } else if (rc != 0) {
+ } else if (untrackedFilesDetector.wasMessageDetected()) {
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, root, untrackedFilesDetector.getRelativeFilePaths(),
+ "unstash", null);
+ } else if (!res.success()) {
GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine());
}
super.doOKAction();
diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java
index 645fb24bcd1e..bd9c8fb3a1b3 100644
--- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java
+++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java
@@ -29,6 +29,8 @@ import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.util.containers.ContainerUtil;
+import git4idea.GitLocalBranch;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.branch.GitBranchUtil;
@@ -184,7 +186,7 @@ class GitBranchPopup {
GitRepositoryManager repositoryManager = myRepositoryManager;
if (repositoryManager.moreThanOneRoot()) {
- if (!myMultiRootBranchConfig.diverged() && userWantsSyncControl()) {
+ if (userWantsSyncControl()) {
fillWithCommonRepositoryActions(popupGroup, repositoryManager);
}
else {
@@ -204,26 +206,37 @@ class GitBranchPopup {
}
private void fillWithCommonRepositoryActions(DefaultActionGroup popupGroup, GitRepositoryManager repositoryManager) {
- List<GitRepository> repositories = repositoryManager.getRepositories();
- String currentBranch = myMultiRootBranchConfig.getCurrentBranch();
- assert currentBranch != null : "Current branch can't be null if branches have not diverged";
- popupGroup.add(new GitBranchPopupActions.GitNewBranchAction(myProject, repositories));
+ List<GitRepository> allRepositories = repositoryManager.getRepositories();
+ popupGroup.add(new GitBranchPopupActions.GitNewBranchAction(myProject, allRepositories));
popupGroup.addAll(createRepositoriesActions());
popupGroup.addSeparator("Common Local Branches");
for (String branch : myMultiRootBranchConfig.getLocalBranches()) {
- if (!branch.equals(currentBranch)) {
+ List<GitRepository> repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
+ if (!repositories.isEmpty()) {
popupGroup.add(new GitBranchPopupActions.LocalBranchActions(myProject, repositories, branch, myCurrentRepository));
}
}
popupGroup.addSeparator("Common Remote Branches");
for (String branch : myMultiRootBranchConfig.getRemoteBranches()) {
- popupGroup.add(new GitBranchPopupActions.RemoteBranchActions(myProject, repositories, branch, myCurrentRepository));
+ popupGroup.add(new GitBranchPopupActions.RemoteBranchActions(myProject, allRepositories, branch, myCurrentRepository));
}
}
+ @NotNull
+ private static List<GitRepository> filterRepositoriesNotOnThisBranch(@NotNull final String branch,
+ @NotNull List<GitRepository> allRepositories) {
+ return ContainerUtil.filter(allRepositories, new Condition<GitRepository>() {
+ @Override
+ public boolean value(GitRepository repository) {
+ GitLocalBranch currentBranch = repository.getCurrentBranch();
+ return currentBranch == null || !branch.equals(currentBranch.getName());
+ }
+ });
+ }
+
private void warnThatBranchesDivergedIfNeeded() {
if (myRepositoryManager.moreThanOneRoot() && myMultiRootBranchConfig.diverged() && userWantsSyncControl()) {
myPopup.setWarning("Branches have diverged");
diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesDialog.java b/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesDialog.java
index d9cbbd781f1c..89ff9f47268f 100644
--- a/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesDialog.java
+++ b/plugins/git4idea/src/git4idea/ui/branch/GitCompareBranchesDialog.java
@@ -18,7 +18,7 @@ package git4idea.ui.branch;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.FrameWrapper;
import com.intellij.ui.TabbedPaneImpl;
import git4idea.GitUtil;
import git4idea.repo.GitRepository;
@@ -30,25 +30,22 @@ import javax.swing.*;
/**
* Dialog for comparing two Git branches.
- * @author Kirill Likhodedov
*/
-public class GitCompareBranchesDialog extends DialogWrapper {
+public class GitCompareBranchesDialog extends FrameWrapper {
- private final Project myProject;
- private final String myBranchName;
- private final String myCurrentBranchName;
- private final GitCommitCompareInfo myCompareInfo;
- private final GitRepository myInitialRepo;
- private JPanel myLogPanel;
+ @NotNull private final Project myProject;
+ @NotNull private final String myBranchName;
+ @NotNull private final String myCurrentBranchName;
+ @NotNull private final GitCommitCompareInfo myCompareInfo;
+ @NotNull private final JPanel myLogPanel;
public GitCompareBranchesDialog(@NotNull Project project, @NotNull String branchName, @NotNull String currentBranchName,
@NotNull GitCommitCompareInfo compareInfo, @NotNull GitRepository initialRepo) {
- super(project, false);
+ super(project, GitCompareBranchesDialog.class.getName());
myCurrentBranchName = currentBranchName;
myCompareInfo = compareInfo;
myProject = project;
myBranchName = branchName;
- myInitialRepo = initialRepo;
String rootString;
if (compareInfo.getRepositories().size() == 1 && GitUtil.getRepositoryManager(myProject).moreThanOneRoot()) {
@@ -58,13 +55,15 @@ public class GitCompareBranchesDialog extends DialogWrapper {
rootString = "";
}
setTitle(String.format("Comparing %s with %s%s", currentBranchName, branchName, rootString));
- setModal(false);
- init();
+
+ myLogPanel = new GitCompareBranchesLogPanel(myProject, myBranchName, myCurrentBranchName, myCompareInfo, initialRepo);
+ setPreferredFocusedComponent(myLogPanel);
+ setComponent(createCenterPanel());
+ closeOnEsc();
}
- @Override
+ @NotNull
protected JComponent createCenterPanel() {
- myLogPanel = new GitCompareBranchesLogPanel(myProject, myBranchName, myCurrentBranchName, myCompareInfo, myInitialRepo);
JPanel diffPanel = new GitCompareBranchesDiffPanel(myProject, myBranchName, myCurrentBranchName, myCompareInfo);
TabbedPaneImpl tabbedPane = new TabbedPaneImpl(SwingConstants.TOP);
@@ -74,20 +73,4 @@ public class GitCompareBranchesDialog extends DialogWrapper {
return tabbedPane;
}
- // it is information dialog - no need to OK or Cancel. Close the dialog by clicking the cross button or pressing Esc.
- @NotNull
- @Override
- protected Action[] createActions() {
- return new Action[0];
- }
-
- @Override
- protected String getDimensionServiceKey() {
- return GitCompareBranchesDialog.class.getName();
- }
-
- @Override
- public JComponent getPreferredFocusedComponent() {
- return myLogPanel;
- }
}
diff --git a/plugins/git4idea/src/git4idea/update/GitFetcher.java b/plugins/git4idea/src/git4idea/update/GitFetcher.java
index 44dbb54343a3..f9c65632d9be 100644
--- a/plugins/git4idea/src/git4idea/update/GitFetcher.java
+++ b/plugins/git4idea/src/git4idea/update/GitFetcher.java
@@ -34,7 +34,6 @@ import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitLineHandlerAdapter;
import git4idea.commands.GitLineHandlerListener;
-import git4idea.jgit.GitHttpAdapter;
import git4idea.repo.GitBranchTrackInfo;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
@@ -132,9 +131,6 @@ public class GitFetcher {
@NotNull GitRemote remote,
@NotNull String url,
@Nullable String branch) {
- if (GitHttpAdapter.shouldUseJGit(url)) {
- return GitHttpAdapter.fetch(repository, remote, url, branch);
- }
return fetchNatively(repository, remote, url, branch);
}
@@ -150,9 +146,6 @@ public class GitFetcher {
GitRemote remote = fetchParams.getRemote();
String remoteBranch = fetchParams.getRemoteBranch().getNameForRemoteOperations();
String url = fetchParams.getUrl();
- if (GitHttpAdapter.shouldUseJGit(url)) {
- return GitHttpAdapter.fetch(repository, remote, url, remoteBranch);
- }
return fetchNatively(repository, remote, url, remoteBranch);
}
@@ -191,22 +184,11 @@ public class GitFetcher {
LOG.error("URL is null for remote " + remote.getName());
continue;
}
- if (GitHttpAdapter.shouldUseJGit(url)) {
- GitFetchResult res = GitHttpAdapter.fetch(repository, remote, url, null);
- res.addPruneInfo(fetchResult.getPrunedRefs());
- fetchResult = res;
- myErrors.addAll(fetchResult.getErrors());
- if (!fetchResult.isSuccess()) {
- break;
- }
- }
- else {
- GitFetchResult res = fetchNatively(repository, remote, url, null);
- res.addPruneInfo(fetchResult.getPrunedRefs());
- fetchResult = res;
- if (!fetchResult.isSuccess()) {
- break;
- }
+ GitFetchResult res = fetchNatively(repository, remote, url, null);
+ res.addPruneInfo(fetchResult.getPrunedRefs());
+ fetchResult = res;
+ if (!fetchResult.isSuccess()) {
+ break;
}
}
return fetchResult;
diff --git a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java
index 4815eb781fce..4315e65227a3 100644
--- a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java
+++ b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java
@@ -119,15 +119,15 @@ public class GitMergeUpdater extends GitUpdater {
LOG.info("Local changes would be overwritten by merge");
final List<FilePath> paths = getFilesOverwrittenByMerge(mergeLineListener.getOutput());
final Collection<Change> changes = getLocalChangesFilteredByFiles(paths);
- final ChangeListViewerDialog dialog = new ChangeListViewerDialog(myProject, changes, false) {
- @Override protected String getDescription() {
- return "Your local changes to the following files would be overwritten by merge.<br/>" +
- "Please, commit your changes or stash them before you can merge.";
- }
- };
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
+ ChangeListViewerDialog dialog = new ChangeListViewerDialog(myProject, changes, false) {
+ @Override protected String getDescription() {
+ return "Your local changes to the following files would be overwritten by merge.<br/>" +
+ "Please, commit your changes or stash them before you can merge.";
+ }
+ };
dialog.show();
}
});
@@ -135,8 +135,9 @@ public class GitMergeUpdater extends GitUpdater {
}
else if (untrackedFilesWouldBeOverwrittenByMergeDetector.wasMessageDetected()) {
LOG.info("handleMergeFailure: untracked files would be overwritten by merge");
- UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject,
- untrackedFilesWouldBeOverwrittenByMergeDetector.getFiles(), "merge", null);
+ UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, myRoot,
+ untrackedFilesWouldBeOverwrittenByMergeDetector.getRelativeFilePaths(),
+ "merge", null);
return GitUpdateResult.ERROR;
}
else {
diff --git a/plugins/git4idea/src/git4idea/util/GitSimplePathsBrowser.java b/plugins/git4idea/src/git4idea/util/GitSimplePathsBrowser.java
new file mode 100644
index 000000000000..fc37dcce3cd7
--- /dev/null
+++ b/plugins/git4idea/src/git4idea/util/GitSimplePathsBrowser.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.util;
+
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.ActionToolbar;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.FilePathImpl;
+import com.intellij.openapi.vcs.changes.ui.FilePathChangesTreeList;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+public class GitSimplePathsBrowser extends JPanel {
+
+ public GitSimplePathsBrowser(@NotNull Project project, @NotNull Collection<String> absolutePaths) {
+ super(new BorderLayout());
+
+ FilePathChangesTreeList browser = createBrowser(project, absolutePaths);
+ ActionToolbar toolbar = createToolbar(browser);
+
+ add(toolbar.getComponent(), BorderLayout.NORTH);
+ add(browser);
+ }
+
+ @NotNull
+ private static FilePathChangesTreeList createBrowser(@NotNull Project project, @NotNull Collection<String> absolutePaths) {
+ List<FilePath> filePaths = toFilePaths(absolutePaths);
+ FilePathChangesTreeList browser = new FilePathChangesTreeList(project, filePaths, false, false, null, null);
+ browser.setChangesToDisplay(filePaths);
+ return browser;
+ }
+
+ @NotNull
+ private static ActionToolbar createToolbar(@NotNull FilePathChangesTreeList browser) {
+ DefaultActionGroup actionGroup = new DefaultActionGroup(browser.getTreeActions());
+ return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, true);
+ }
+
+ @NotNull
+ private static List<FilePath> toFilePaths(@NotNull Collection<String> absolutePaths) {
+ return ContainerUtil.map(absolutePaths, new Function<String, FilePath>() {
+ @Override
+ public FilePath fun(String path) {
+ return new FilePathImpl(new File(path), false);
+ }
+ });
+ }
+}
diff --git a/plugins/git4idea/src/git4idea/util/LocalChangesWouldBeOverwrittenHelper.java b/plugins/git4idea/src/git4idea/util/LocalChangesWouldBeOverwrittenHelper.java
new file mode 100644
index 000000000000..021ce824b9a7
--- /dev/null
+++ b/plugins/git4idea/src/git4idea/util/LocalChangesWouldBeOverwrittenHelper.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.util;
+
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.ex.MultiLineLabel;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsNotifier;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vfs.VirtualFile;
+import git4idea.GitUtil;
+import git4idea.ui.ChangesBrowserWithRollback;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.event.HyperlinkEvent;
+import java.util.Collection;
+import java.util.List;
+
+public class LocalChangesWouldBeOverwrittenHelper {
+
+ @NotNull
+ public static String getErrorNotificationDescription() {
+ return getErrorDescription(true);
+ }
+
+ @NotNull
+ public static String getErrorDialogDescription() {
+ return getErrorDescription(false);
+ }
+
+ @NotNull
+ private static String getErrorDescription(boolean forNotification) {
+ String line1 = "Your local changes would be overwritten by merge.";
+ String line2 = "Commit, stash or revert them to proceed.";
+ if (forNotification) {
+ return line1 + "<br/>" + line2 + " <a href='view'>View them</a>";
+ }
+ else {
+ return line1 + "\n" + line2;
+ }
+ }
+
+ public static void showErrorNotification(@NotNull final Project project, @NotNull VirtualFile root, @NotNull final String operationName,
+ @NotNull final Collection<String> relativeFilePaths) {
+ final Collection<String> absolutePaths = GitUtil.toAbsolute(root, relativeFilePaths);
+ final List<Change> changes = GitUtil.findLocalChangesForPaths(project, root, absolutePaths, false);
+ String notificationTitle = "Git " + StringUtil.capitalize(operationName) + " Failed";
+ VcsNotifier.getInstance(project).notifyError(notificationTitle, getErrorNotificationDescription(),
+ new NotificationListener.Adapter() {
+ @Override
+ protected void hyperlinkActivated(@NotNull Notification notification,
+ @NotNull HyperlinkEvent e) {
+ String title = "Local Changes Prevent from " + StringUtil.capitalize(operationName);
+ String description = getErrorDialogDescription();
+ if (changes.isEmpty()) {
+ GitUtil.showPathsInDialog(project, absolutePaths, title, description);
+ }
+ else {
+ DialogBuilder builder = new DialogBuilder(project);
+ builder.setNorthPanel(new MultiLineLabel(description));
+ builder.setCenterPanel(new ChangesBrowserWithRollback(project, changes));
+ builder.addOkAction();
+ builder.setTitle(title);
+ builder.show();
+ }
+ }
+ });
+ }
+}
diff --git a/plugins/git4idea/src/git4idea/util/UntrackedFilesNotifier.java b/plugins/git4idea/src/git4idea/util/UntrackedFilesNotifier.java
index 6a867933e6aa..382d51b42032 100644
--- a/plugins/git4idea/src/git4idea/util/UntrackedFilesNotifier.java
+++ b/plugins/git4idea/src/git4idea/util/UntrackedFilesNotifier.java
@@ -18,10 +18,14 @@ package git4idea.util;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.changes.ui.SelectFilesDialog;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import git4idea.GitUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,6 +33,7 @@ import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
public class UntrackedFilesNotifier {
@@ -38,24 +43,40 @@ public class UntrackedFilesNotifier {
/**
* Displays notification about {@code untracked files would be overwritten by checkout} error.
* Clicking on the link in the notification opens a simple dialog with the list of these files.
+ * @param root
+ * @param relativePaths
* @param operation the name of the Git operation that caused the error: {@code rebase, merge, checkout}.
* @param description the content of the notification or null if the deafult content is to be used.
*/
public static void notifyUntrackedFilesOverwrittenBy(@NotNull final Project project,
- @NotNull final Collection<VirtualFile> untrackedFiles,
+ @NotNull final VirtualFile root, @NotNull Collection<String> relativePaths,
@NotNull final String operation, @Nullable String description) {
final String notificationTitle = StringUtil.capitalize(operation) + " failed";
final String notificationDesc = description == null ? createUntrackedFilesOverwrittenDescription(operation, true) : description;
- VcsNotifier.getInstance(project).notifyError(notificationTitle, notificationDesc,
- new NotificationListener() {
+ final Collection<String> absolutePaths = GitUtil.toAbsolute(root, relativePaths);
+ final List<VirtualFile> untrackedFiles = ContainerUtil.mapNotNull(absolutePaths, new Function<String, VirtualFile>() {
+ @Override
+ public VirtualFile fun(String absolutePath) {
+ return GitUtil.findRefreshFileOrLog(absolutePath);
+ }
+ });
+
+ VcsNotifier.getInstance(project).notifyError(notificationTitle, notificationDesc, new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
final String dialogDesc = createUntrackedFilesOverwrittenDescription(operation, false);
- SelectFilesDialog dlg = new UntrackedFilesDialog(project, untrackedFiles, dialogDesc);
- dlg.setTitle("Untracked Files Preventing " + StringUtil.capitalize(operation));
- dlg.show();
+ String title = "Untracked Files Preventing " + StringUtil.capitalize(operation);
+ if (untrackedFiles.isEmpty()) {
+ GitUtil.showPathsInDialog(project, absolutePaths, title, dialogDesc);
+ }
+ else {
+ DialogWrapper dialog;
+ dialog = new UntrackedFilesDialog(project, untrackedFiles, dialogDesc);
+ dialog.setTitle(title);
+ dialog.show();
+ }
}
}
});
diff --git a/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java b/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java
deleted file mode 100644
index fae6082502c9..000000000000
--- a/plugins/git4idea/src/org/hanuna/gitalk/git/reader/util/GitException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.hanuna.gitalk.git.reader.util;
-
-/**
- * @author erokhins
- */
-public class GitException extends RuntimeException {
- public GitException(String message) {
- super(message);
- }
-
-}
diff --git a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy
index e00f0ddafe19..35acc41fc3cc 100644
--- a/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy
+++ b/plugins/git4idea/tests/git4idea/branch/GitBranchWorkerTest.groovy
@@ -75,10 +75,6 @@ class GitBranchWorkerTest extends GitPlatformTest {
}
}
- public void tearDown() {
- super.tearDown();
- }
-
public void "test create new branch without problems"() {
checkoutNewBranch "feature", [ ]
@@ -205,7 +201,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
boolean notificationShown = false;
checkoutOrMerge operation, "feature", [
- showUntrackedFilesNotification : { String s, Collection c -> notificationShown = true }
+ showUntrackedFilesNotification: { String s, VirtualFile root, Collection c -> notificationShown = true }
]
assertTrue "Untracked files notification was not shown", notificationShown
@@ -224,15 +220,15 @@ class GitBranchWorkerTest extends GitPlatformTest {
def untracked = ["untracked.txt"]
untrackedFileOverwrittenBy(myCommunity, "feature", untracked)
- Collection<VirtualFile> untrackedFiles = null;
+ Collection<String> untrackedPaths = null;
checkoutOrMerge operation, "feature", [
- showUntrackedFilesDialogWithRollback : { String s, String p, Collection files -> untrackedFiles = files; false }
+ showUntrackedFilesDialogWithRollback: {
+ String s, String p, VirtualFile root, Collection<String> files -> untrackedPaths = files; false
+ }
]
- assertTrue "Untracked files dialog was not shown", untrackedFiles != null
- assertEquals "Incorrect set of untracked files was shown in the dialog",
- untracked,
- untrackedFiles.collect { FileUtil.getRelativePath(myCommunity.root.path, it.path, '/'.toCharacter()) }
+ assertTrue "Untracked files dialog was not shown", untrackedPaths != null
+ assertEquals "Incorrect set of untracked files was shown in the dialog", untracked.asList(), untrackedPaths.asList()
}
public void "test checkout with local changes overwritten by checkout should show smart checkout dialog"() {
@@ -252,7 +248,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
List<Change> changes = null;
checkoutOrMerge(operation, "feature", [
- showSmartOperationDialog: { Project p, List<Change> cs, String op, boolean force ->
+ showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean force ->
changes = cs
DialogWrapper.CANCEL_EXIT_CODE
}
@@ -349,7 +345,9 @@ class GitBranchWorkerTest extends GitPlatformTest {
prepareLocalChangesOverwrittenBy(myUltimate)
checkoutOrMerge(operation, "feature", [
- showSmartOperationDialog : { Project p, List<Change> cs, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE },
+ showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean f
+ -> GitSmartOperationDialog.CANCEL_EXIT_CODE
+ },
] as GitBranchUiHandler )
assertNull "Notification was unexpectedly shown:" + myVcsNotifier.lastNotification, myVcsNotifier.lastNotification
@@ -372,8 +370,10 @@ class GitBranchWorkerTest extends GitPlatformTest {
def rollbackMsg = null
checkoutOrMerge(operation, "feature", [
- showSmartOperationDialog : { Project p, List<Change> cs, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE },
- notifyErrorWithRollbackProposal: { String t, String m, String rp -> rollbackMsg = m ; false }
+ showSmartOperationDialog : {
+ Project p, List<Change> cs, Collection<String> paths, String op, boolean f -> GitSmartOperationDialog.CANCEL_EXIT_CODE
+ },
+ notifyErrorWithRollbackProposal: { String t, String m, String rp -> rollbackMsg = m; false }
] as GitBranchUiHandler )
assertNotNull "Rollback proposal was not shown", rollbackMsg
@@ -384,7 +384,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
prepareLocalChangesOverwrittenBy(myUltimate)
def uiHandler = [
- showSmartOperationDialog: { Project p, List<Change> cs, String op, boolean force ->
+ showSmartOperationDialog: { Project p, List<Change> cs, Collection<String> paths, String op, boolean force ->
GitSmartOperationDialog.FORCE_EXIT_CODE;
},
] as GitBranchUiHandler
@@ -711,7 +711,12 @@ class GitBranchWorkerTest extends GitPlatformTest {
}
@Override
- int showSmartOperationDialog(@NotNull Project project, @NotNull List<Change> changes, @NotNull String operation, boolean force) {
+ int showSmartOperationDialog(
+ @NotNull Project project,
+ @NotNull List<Change> changes,
+ @NotNull Collection<String> paths,
+ @NotNull String operation,
+ boolean isForcePossible) {
GitSmartOperationDialog.SMART_EXIT_CODE
}
@@ -741,12 +746,13 @@ class GitBranchWorkerTest extends GitPlatformTest {
}
@Override
- void showUntrackedFilesNotification(@NotNull String operationName, @NotNull Collection<VirtualFile> untrackedFiles) {
+ void showUntrackedFilesNotification(@NotNull String operationName, @NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
throw new UnsupportedOperationException()
}
@Override
- boolean showUntrackedFilesDialogWithRollback(@NotNull String operationName, @NotNull String rollbackProposal, @NotNull Collection<VirtualFile> untrackedFiles) {
+ boolean showUntrackedFilesDialogWithRollback(
+ @NotNull String operationName, @NotNull String rollbackProposal, @NotNull VirtualFile root, @NotNull Collection<String> relativePaths) {
throw new UnsupportedOperationException()
}
diff --git a/plugins/git4idea/tests/git4idea/checkin/GitCommitAuthorCorrectorTest.java b/plugins/git4idea/tests/git4idea/checkin/GitCommitAuthorCorrectorTest.java
new file mode 100644
index 000000000000..9b0789d21809
--- /dev/null
+++ b/plugins/git4idea/tests/git4idea/checkin/GitCommitAuthorCorrectorTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package git4idea.checkin;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class GitCommitAuthorCorrectorTest {
+
+ @Test
+ public void add_space_before_email_in_brackets() {
+ assertCorrection("foo<foo@email.com>", "foo <foo@email.com>");
+ }
+
+ @Test
+ public void add_brackets() {
+ String expected = "John Smith <john.smith@email.com>";
+ assertCorrection("John Smith john.smith@email.com", expected);
+ assertCorrection("John Smith <john.smith@email.com", expected);
+ assertCorrection("John Smith john.smith@email.com>", expected);
+ }
+
+ @Test
+ public void no_correction_needed() {
+ assertDoNothing("John Smith <john.smith@email.com>");
+ }
+
+ @Test
+ public void correction_not_possible() {
+ assertDoNothing("foo");
+ assertDoNothing("foo bar");
+ }
+
+ private static void assertCorrection(String source, String expected) {
+ assertEquals(expected, GitCommitAuthorCorrector.correct(source));
+ }
+
+ private static void assertDoNothing(String source) {
+ assertCorrection(source, source);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
index a073ceda0c96..ecef2b2cdcf5 100644
--- a/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
+++ b/plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
@@ -125,6 +125,10 @@ public abstract class GitPlatformTest extends UsefulTestCase {
myDialogManager.cleanup();
myVcsNotifier.cleanup();
myProjectFixture.tearDown();
+
+ String tempTestIndicator = myTestStartedIndicator;
+ clearFields(this);
+ myTestStartedIndicator = tempTestIndicator;
}
finally {
super.tearDown();
diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
index 078f2f77ad64..43753142a5b2 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java
@@ -254,18 +254,29 @@ public class GithubCreateGistAction extends DumbAwareAction {
}
@NotNull
- private static List<FileContent> getContentFromFile(@NotNull VirtualFile file, @NotNull Project project, @Nullable String prefix) {
+ private static List<FileContent> getContentFromFile(@NotNull final VirtualFile file, @NotNull Project project, @Nullable String prefix) {
if (file.isDirectory()) {
return getContentFromDirectory(file, project, prefix);
}
- Document document = FileDocumentManager.getInstance().getDocument(file);
- String content;
- if (document != null) {
- content = document.getText();
- }
- else {
- content = readFile(file);
- }
+ String content = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ @Nullable
+ @Override
+ public String compute() {
+ try {
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document != null) {
+ return document.getText();
+ }
+ else {
+ return new String(file.contentsToByteArray(), file.getCharset());
+ }
+ }
+ catch (IOException e) {
+ LOG.info("Couldn't read contents of the file " + file, e);
+ return null;
+ }
+ }
+ });
if (content == null) {
GithubNotifications.showWarning(project, FAILED_TO_CREATE_GIST, "Couldn't read the contents of the file " + file);
return Collections.emptyList();
@@ -289,23 +300,6 @@ public class GithubCreateGistAction extends DumbAwareAction {
return contents;
}
- @Nullable
- private static String readFile(@NotNull final VirtualFile file) {
- return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
- @Nullable
- @Override
- public String compute() {
- try {
- return new String(file.contentsToByteArray(), file.getCharset());
- }
- catch (IOException e) {
- LOG.info("Couldn't read contents of the file " + file, e);
- return null;
- }
- }
- });
- }
-
private static String addPrefix(@NotNull String name, @Nullable String prefix, boolean addTrailingSlash) {
String pref = prefix == null ? "" : prefix;
pref += name;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java
index fb8e381f7282..5a7daf94a9fd 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/extensions/GithubHttpAuthDataProvider.java
@@ -17,7 +17,7 @@ package org.jetbrains.plugins.github.extensions;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.AuthData;
-import git4idea.jgit.GitHttpAuthDataProvider;
+import git4idea.remote.GitHttpAuthDataProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.util.GithubAuthData;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java
index 004e13c505d6..edd12ab85ab6 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/util/GithubUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -150,20 +150,25 @@ public class GithubUtil {
@Override
@NotNull
public GithubAuthData compute() throws GithubOperationCanceledException {
- final GithubLoginDialog dialog = new GithubLoginDialog(project, oldAuth);
+ final GithubAuthData[] authData = new GithubAuthData[1];
+ final boolean[] ok = new boolean[1];
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
+ final GithubLoginDialog dialog = new GithubLoginDialog(project, oldAuth);
DialogManager.show(dialog);
+ ok[0] = dialog.isOK();
+
+ if (ok[0]) {
+ authData[0] = dialog.getAuthData();
+ GithubSettings.getInstance().setAuthData(authData[0], dialog.isSavePasswordSelected());
+ }
}
}, indicator.getModalityState());
- if (!dialog.isOK()) {
+ if (!ok[0]) {
throw new GithubOperationCanceledException("Can't get valid credentials");
}
- GithubAuthData authData = dialog.getAuthData();
-
- GithubSettings.getInstance().setAuthData(authData, dialog.isSavePasswordSelected());
- return authData;
+ return authData[0];
}
});
}
@@ -177,23 +182,28 @@ public class GithubUtil {
@Override
@NotNull
public GithubAuthData compute() throws GithubOperationCanceledException {
- final GithubLoginDialog dialog = new GithubBasicLoginDialog(project, oldAuth, host);
+ final GithubAuthData[] authData = new GithubAuthData[1];
+ final boolean[] ok = new boolean[1];
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
+ final GithubLoginDialog dialog = new GithubBasicLoginDialog(project, oldAuth, host);
DialogManager.show(dialog);
+ ok[0] = dialog.isOK();
+ if (ok[0]) {
+ authData[0] = dialog.getAuthData();
+
+ final GithubSettings settings = GithubSettings.getInstance();
+ if (settings.getAuthType() != GithubAuthData.AuthType.TOKEN) {
+ GithubSettings.getInstance().setAuthData(authData[0], dialog.isSavePasswordSelected());
+ }
+ }
}
}, indicator.getModalityState());
- if (!dialog.isOK()) {
+ if (!ok[0]) {
throw new GithubOperationCanceledException("Can't get valid credentials");
}
- GithubAuthData authData = dialog.getAuthData();
-
- final GithubSettings settings = GithubSettings.getInstance();
- if (settings.getAuthType() != GithubAuthData.AuthType.TOKEN) {
- GithubSettings.getInstance().setAuthData(authData, dialog.isSavePasswordSelected());
- }
- return authData;
+ return authData[0];
}
});
}
diff --git a/plugins/gradle/gradle.iml b/plugins/gradle/gradle.iml
index a46a4870d7a1..878ec399b87c 100644
--- a/plugins/gradle/gradle.iml
+++ b/plugins/gradle/gradle.iml
@@ -29,29 +29,25 @@
<orderEntry type="module-library" exported="">
<library name="Gradle">
<CLASSES>
- <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-core-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-messaging-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-base-services-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-native-1.12.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-tooling-api-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-core-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-messaging-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-wrapper-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-base-services-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-base-services-groovy-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-native-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-resources-2.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/native/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/java" />
- <root url="jar://$MODULE_DIR$/lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/test/groovy" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/tooling-api/src/main/java" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/core/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/messaging/src/main/java" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/wrapper/src/main/java" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services/src/main/java" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services-groovy/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/native/src/main/java" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/resources/src/main/java" />
</SOURCES>
</library>
</orderEntry>
@@ -67,7 +63,7 @@
<orderEntry type="module-library" exported="">
<library name="GradleGuava">
<CLASSES>
- <root url="jar://$MODULE_DIR$/lib/guava-jdk5-14.0.1.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/guava-jdk5-17.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -97,7 +93,6 @@
<library name="GradleJnaPosix">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jna-3.2.7.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/jna-posix-1.0.3.jar!/" />
<root url="jar://$MODULE_DIR$/lib/native-platform-0.10.jar!/" />
</CLASSES>
<JAVADOC />
diff --git a/plugins/gradle/lib/gradle-1.12-src.zip b/plugins/gradle/lib/gradle-2.0-src.zip
index c5801211c812..1b8ad58457e5 100644
--- a/plugins/gradle/lib/gradle-1.12-src.zip
+++ b/plugins/gradle/lib/gradle-2.0-src.zip
Binary files differ
diff --git a/plugins/gradle/lib/gradle-base-services-1.12.jar b/plugins/gradle/lib/gradle-base-services-2.0.jar
index cb3c815d443f..25c3038a1321 100644
--- a/plugins/gradle/lib/gradle-base-services-1.12.jar
+++ b/plugins/gradle/lib/gradle-base-services-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-base-services-groovy-2.0.jar b/plugins/gradle/lib/gradle-base-services-groovy-2.0.jar
new file mode 100644
index 000000000000..e66a65037875
--- /dev/null
+++ b/plugins/gradle/lib/gradle-base-services-groovy-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-core-1.12.jar b/plugins/gradle/lib/gradle-core-2.0.jar
index 8762c10401b5..9b9bf0ac1799 100644
--- a/plugins/gradle/lib/gradle-core-1.12.jar
+++ b/plugins/gradle/lib/gradle-core-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-messaging-1.12.jar b/plugins/gradle/lib/gradle-messaging-2.0.jar
index 99893927e2fe..e0c617f77d48 100644
--- a/plugins/gradle/lib/gradle-messaging-1.12.jar
+++ b/plugins/gradle/lib/gradle-messaging-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-native-1.12.jar b/plugins/gradle/lib/gradle-native-1.12.jar
deleted file mode 100644
index 8c4e18282dee..000000000000
--- a/plugins/gradle/lib/gradle-native-1.12.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/gradle-native-2.0.jar b/plugins/gradle/lib/gradle-native-2.0.jar
new file mode 100644
index 000000000000..78c73dea6a7a
--- /dev/null
+++ b/plugins/gradle/lib/gradle-native-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-resources-2.0.jar b/plugins/gradle/lib/gradle-resources-2.0.jar
new file mode 100644
index 000000000000..93fe22532831
--- /dev/null
+++ b/plugins/gradle/lib/gradle-resources-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-tooling-api-1.12.jar b/plugins/gradle/lib/gradle-tooling-api-2.0.jar
index 4b61b12835fc..25c62857fb91 100644
--- a/plugins/gradle/lib/gradle-tooling-api-1.12.jar
+++ b/plugins/gradle/lib/gradle-tooling-api-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/gradle-wrapper-1.12.jar b/plugins/gradle/lib/gradle-wrapper-2.0.jar
index d19566480191..43b7b749039b 100644
--- a/plugins/gradle/lib/gradle-wrapper-1.12.jar
+++ b/plugins/gradle/lib/gradle-wrapper-2.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/guava-jdk5-14.0.1.jar b/plugins/gradle/lib/guava-jdk5-14.0.1.jar
deleted file mode 100644
index af66ab0d348f..000000000000
--- a/plugins/gradle/lib/guava-jdk5-14.0.1.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/lib/guava-jdk5-17.0.jar b/plugins/gradle/lib/guava-jdk5-17.0.jar
new file mode 100644
index 000000000000..e70cc2e9186a
--- /dev/null
+++ b/plugins/gradle/lib/guava-jdk5-17.0.jar
Binary files differ
diff --git a/plugins/gradle/lib/jna-posix-1.0.3.jar b/plugins/gradle/lib/jna-posix-1.0.3.jar
deleted file mode 100644
index 1baa07ad8efd..000000000000
--- a/plugins/gradle/lib/jna-posix-1.0.3.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml b/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml
deleted file mode 100644
index 1bb578f4b2eb..000000000000
--- a/plugins/gradle/src/META-INF/gradle-javaee-plugin.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<idea-plugin>
- <extensions defaultExtensionNs="com.intellij">
- <externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.javaee.WebModuleGradleDataService"/>
- <externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.javaee.WebDetectionExclusionModuleDataService"/>
- </extensions>
- <extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
- <projectResolve implementation="org.jetbrains.plugins.gradle.integrations.javaee.JavaEEGradleProjectResolverExtension"/>
- </extensions>
-</idea-plugin>
diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index eb1196fa5395..67ca15f5d679 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -40,7 +40,6 @@
<depends>com.intellij.modules.lang</depends>
<depends>org.intellij.groovy</depends>
<depends>JUnit</depends>
- <depends optional="true" config-file="gradle-javaee-plugin.xml">com.intellij.javaee</depends>
<depends optional="true" config-file="gradle-maven-integration.xml">org.jetbrains.idea.maven</depends>
<extensionPoints>
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
index b011f2d90016..4f4ceeeb3c7a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/GradleManager.java
@@ -30,9 +30,7 @@ import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecution
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
-import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType;
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
-import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager;
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
import com.intellij.openapi.externalSystem.service.project.autoimport.CachingExternalSystemAutoImportAware;
@@ -51,8 +49,11 @@ import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
+import com.intellij.util.PathUtil;
+import com.intellij.util.PathsList;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.messages.MessageBusConnection;
import icons.GradleIcons;
@@ -74,11 +75,7 @@ import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
+import java.util.*;
/**
* @author Denis Zhdanov
@@ -198,9 +195,20 @@ public class GradleManager
@Override
public void enhanceRemoteProcessing(@NotNull SimpleJavaParameters parameters) throws ExecutionException {
+ final Set<String> additionalEntries = ContainerUtilRt.newHashSet();
for (GradleProjectResolverExtension extension : RESOLVER_EXTENSIONS.getValue()) {
+ ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(extension.getClass()));
+ for (Class aClass : extension.getExtraProjectModelClasses()) {
+ ContainerUtilRt.addIfNotNull(additionalEntries, PathUtil.getJarPathForClass(aClass));
+ }
extension.enhanceRemoteProcessing(parameters);
}
+
+ final PathsList classPath = parameters.getClassPath();
+ for (String entry : additionalEntries) {
+ classPath.add(entry);
+ }
+
parameters.getVMParametersList().addProperty(
ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, GradleConstants.SYSTEM_ID.getId());
}
@@ -342,7 +350,7 @@ public class GradleManager
Map<String/* old path */, String/* new path */> adjustedPaths = ContainerUtilRt.newHashMap();
for (GradleProjectSettings projectSettings : settings.getLinkedProjectsSettings()) {
String oldPath = projectSettings.getExternalProjectPath();
- if (!new File(oldPath).isDirectory()) {
+ if (oldPath != null && new File(oldPath).isFile() && FileUtilRt.extensionEquals(oldPath, GradleConstants.EXTENSION)) {
try {
String newPath = new File(oldPath).getParentFile().getCanonicalPath();
projectSettings.setExternalProjectPath(newPath);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
index 7ac99066d74f..7b06640f6234 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/codeInsight/UseDistributionWithSourcesNotificationProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -85,13 +85,14 @@ public class UseDistributionWithSourcesNotificationProvider extends EditorNotifi
});
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
- public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
try {
if (GradleConstants.DEFAULT_SCRIPT_NAME.equals(file.getName()) ||
GradleConstants.SETTINGS_FILE_NAME.equals(file.getName())) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleBuildClasspathResolveScopeEnlarger.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleBuildClasspathResolveScopeEnlarger.java
index ccfd32c62da8..1b0bb8f19f7b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleBuildClasspathResolveScopeEnlarger.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleBuildClasspathResolveScopeEnlarger.java
@@ -21,7 +21,7 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElementFinder;
import com.intellij.psi.ResolveScopeEnlarger;
-import com.intellij.psi.search.NonClasspathDirectoryScope;
+import com.intellij.psi.search.NonClasspathDirectoriesScope;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyFileType;
@@ -42,7 +42,7 @@ public class GradleBuildClasspathResolveScopeEnlarger extends ResolveScopeEnlarg
final List<VirtualFile> roots = gradleClassFinder.getClassRoots();
for (VirtualFile root : roots) {
if (VfsUtilCore.isAncestor(root, file, true)) {
- return NonClasspathDirectoryScope.compose(roots);
+ return NonClasspathDirectoriesScope.compose(roots);
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
index 8219ec08a932..e7795a0621d2 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
@@ -41,7 +41,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.NonClasspathDirectoryScope;
+import com.intellij.psi.search.NonClasspathDirectoriesScope;
import icons.GradleIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,7 +52,6 @@ import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.extensions.GroovyRunnableScriptType;
-import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
@@ -79,7 +78,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
private static final Pattern MAIN_CLASS_NAME_PATTERN = Pattern.compile("\nSTARTER_MAIN_CLASS=(.*)\n");
- public static final GroovyScriptType INSTANCE = new GradleScriptType();
+ public static final GradleScriptType INSTANCE = new GradleScriptType();
private GradleScriptType() {
super(GradleConstants.EXTENSION);
@@ -264,7 +263,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
if (scriptPath == null) {
throw new CantRunException("Target script is undefined");
}
- params.getProgramParametersList().add("--build-file");
+ params.getProgramParametersList().add("--project-dir");
params.getProgramParametersList().add(FileUtil.toSystemDependentName(scriptPath));
params.getProgramParametersList().addParametersString(configuration.getProgramParameters());
params.getProgramParametersList().addParametersString(scriptParameters);
@@ -273,7 +272,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
}
@NotNull
- private static String findMainClass(VirtualFile gradleHome, VirtualFile script, Project project) {
+ private static String findMainClass(VirtualFile gradleHome, @Nullable VirtualFile script, Project project) {
final String userDefined = System.getProperty("gradle.launcher.class");
if (StringUtil.isNotEmpty(userDefined)) {
return userDefined;
@@ -298,9 +297,12 @@ public class GradleScriptType extends GroovyRunnableScriptType {
}
}
- final PsiFile grFile = PsiManager.getInstance(project).findFile(script);
- if (grFile != null && JavaPsiFacade.getInstance(project).findClass("org.gradle.BootstrapMain", grFile.getResolveScope()) != null) {
- return "org.gradle.BootstrapMain";
+ final PsiFile grFile;
+ if (script != null) {
+ grFile = PsiManager.getInstance(project).findFile(script);
+ if (grFile != null && JavaPsiFacade.getInstance(project).findClass("org.gradle.BootstrapMain", grFile.getResolveScope()) != null) {
+ return "org.gradle.BootstrapMain";
+ }
}
return "org.gradle.launcher.GradleMain";
@@ -333,10 +335,7 @@ public class GradleScriptType extends GroovyRunnableScriptType {
files = GradleBuildClasspathManager.getInstance(file.getProject()).getModuleClasspathEntries(modulePath);
- for (final VirtualFile root : files) {
- result = result.uniteWith(new NonClasspathDirectoryScope(root));
- }
- result = new ExternalModuleBuildGlobalSearchScope(module.getProject(), result, modulePath);
+ result = new ExternalModuleBuildGlobalSearchScope(module.getProject(), result.uniteWith(new NonClasspathDirectoriesScope(files)), modulePath);
}
return result;
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/GradleTestsExecutionConsoleManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/GradleTestsExecutionConsoleManager.java
index 77e6333ba019..4fd22407f7f8 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/GradleTestsExecutionConsoleManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/GradleTestsExecutionConsoleManager.java
@@ -27,6 +27,7 @@ import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView;
import com.intellij.execution.testframework.sm.runner.ui.TestTreeRenderer;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
@@ -193,4 +194,9 @@ public class GradleTestsExecutionConsoleManager implements ExternalSystemExecuti
}
return false;
}
+
+ @Override
+ public AnAction[] getRestartActions() {
+ return new AnAction[0];
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/OpenGradleTestResultActionProvider.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/OpenGradleTestResultActionProvider.java
index 6ae3a2cfb8b6..522c6057b9eb 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/OpenGradleTestResultActionProvider.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/execution/test/runner/OpenGradleTestResultActionProvider.java
@@ -15,17 +15,21 @@
*/
package org.jetbrains.plugins.gradle.execution.test.runner;
+import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.execution.testframework.ToggleModelAction;
import com.intellij.execution.testframework.ToggleModelActionProvider;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
import com.intellij.util.config.AbstractProperty;
import com.intellij.util.config.BooleanProperty;
import icons.GradleIcons;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleBundle;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
import java.io.File;
@@ -42,6 +46,9 @@ public class OpenGradleTestResultActionProvider implements ToggleModelActionProv
}
private static class MyToggleModelAction extends ToggleModelAction {
+ @Nullable
+ private ProjectSystemId mySystemId;
+
public MyToggleModelAction(TestConsoleProperties properties) {
super(GradleBundle.message("gradle.test.runner.ui.tests.actions.open.gradle.report.text"),
GradleBundle.message("gradle.test.runner.ui.tests.actions.open.gradle.report.desc"),
@@ -50,6 +57,10 @@ public class OpenGradleTestResultActionProvider implements ToggleModelActionProv
@Override
public void setModel(TestFrameworkRunningModel model) {
+ final RunConfiguration runConfiguration = model.getProperties().getConfiguration();
+ if(runConfiguration instanceof ExternalSystemRunConfiguration) {
+ mySystemId = ((ExternalSystemRunConfiguration)runConfiguration).getSettings().getExternalSystemId();
+ }
}
@Override
@@ -66,6 +77,11 @@ public class OpenGradleTestResultActionProvider implements ToggleModelActionProv
return reportFilePath != null;
}
+ @Override
+ protected boolean isVisible() {
+ return GradleConstants.SYSTEM_ID.equals(mySystemId);
+ }
+
@Nullable
private String getReportFilePath() {
final AbstractProperty.AbstractPropertyContainer properties = getProperties();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java
index f1230b81a85c..1c11d7f6f3f0 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/javaee/JavaEEGradleProjectResolverExtension.java
@@ -24,11 +24,11 @@ import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.model.idea.IdeaModule;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.gradle.model.web.WebConfiguration;
import org.jetbrains.plugins.gradle.model.data.War;
import org.jetbrains.plugins.gradle.model.data.WarDirectory;
import org.jetbrains.plugins.gradle.model.data.WebConfigurationModelData;
import org.jetbrains.plugins.gradle.model.data.WebResource;
+import org.jetbrains.plugins.gradle.model.web.WebConfiguration;
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -82,9 +82,7 @@ public class JavaEEGradleProjectResolverExtension extends AbstractProjectResolve
public WebResource fun(WebConfiguration.WebResource resource) {
if (resource == null) return null;
- final WarDirectory warDirectory =
- WarDirectory.fromPath(resource.getWarDirectory());
- if (warDirectory == null) return null;
+ final WarDirectory warDirectory = WarDirectory.fromPath(resource.getWarDirectory());
return new WebResource(warDirectory, resource.getRelativePath(), resource.getFile());
}
});
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
index 9a1c7fbc83c9..889fc1a73cb2 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.integrations.maven;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -75,6 +76,7 @@ public class ImportMavenRepositoriesTask implements Runnable {
@Override
public void run() {
if(myProject.isDisposed()) return;
+ if (ApplicationManager.getApplication().isUnitTestMode()) return;
final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
final List<PsiFile> psiFileList = ContainerUtil.newArrayList();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarDirectory.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarDirectory.java
index b59dcbb12d57..050f6eec128e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarDirectory.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WarDirectory.java
@@ -17,44 +17,48 @@ package org.jetbrains.plugins.gradle.model.data;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+
+import java.io.Serializable;
/**
* @author Vladislav.Soroka
* @since 2/10/14
*/
-public enum WarDirectory {
+public class WarDirectory implements Serializable {
/**
* Public files typically include the following:
* HTML files.
* JSP files.
* Image files and other multimedia files -- it is a common convention to store image files in an images subdirectory.
*/
- WAR_ROOT("/"),
+ public static final WarDirectory WAR_ROOT = new WarDirectory("/");
/**
* directory can contain the following file:
* META-INF/MANIFEST.MF -- an optional file that can be used to specify additional meta-information for the WAR.
*/
- META_INF("/META-INF"),
+ public static final WarDirectory META_INF = new WarDirectory("/META-INF");
/**
* Directory contains a Web archive's private files and directories.
* That is, when the Web archive is deployed, the files and directories under the WEB-INF/ directory cannot be accessed directly by Web clients.
*/
- WEB_INF("/WEB-INF"),
+ public static final WarDirectory WEB_INF = new WarDirectory("/WEB-INF");
/**
* Subdirectory can store JAR files used by the Web module.
* The JAR files in this directory are automatically accessible to the Web module without needing to be added to the class path.
*/
- WEB_INF_LIB("/WEB-INF/lib"),
+ public static final WarDirectory WEB_INF_LIB = new WarDirectory("/WEB-INF/lib");
/**
* Subdirectory contains the compiled Java code for the Web module.
*/
- WEB_INF_CLASSES("/WEB-INF/classes");
+ public static final WarDirectory WEB_INF_CLASSES = new WarDirectory("/WEB-INF/classes");
+
+ private static final WarDirectory[] WAR_DIRECTORIES = new WarDirectory[]{WAR_ROOT, META_INF, WEB_INF, WEB_INF_LIB, WEB_INF_CLASSES};
+
@NotNull
private final String myRelativePath;
WarDirectory(@NotNull final String relativePath) {
- myRelativePath = relativePath;
+ myRelativePath = getAdjustedPath(relativePath);
}
@NotNull
@@ -62,14 +66,44 @@ public enum WarDirectory {
return myRelativePath;
}
- @Nullable
+ public boolean isCustomDirectory() {
+ for (WarDirectory warDirectory : WAR_DIRECTORIES) {
+ if (myRelativePath.equals(warDirectory.getRelativePath())) return false;
+ }
+ return true;
+ }
+
+ @NotNull
public static WarDirectory fromPath(final @NotNull String path) {
if (StringUtil.isEmpty(path)) return WAR_ROOT;
- final String adjustedPath = path.charAt(0) != '/' ? '/' + path : path;
- for (WarDirectory warDirectory : values()) {
+ final String adjustedPath = getAdjustedPath(path);
+ for (WarDirectory warDirectory : WAR_DIRECTORIES) {
if (warDirectory.myRelativePath.equals(adjustedPath)) return warDirectory;
}
- return null;
+ return new WarDirectory(adjustedPath);
+ }
+
+ private static String getAdjustedPath(final @NotNull String path) {
+ return path.isEmpty() || path.charAt(0) != '/' ? '/' + path : path;
+ }
+
+ @Override
+ public String toString() {
+ return myRelativePath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ WarDirectory directory = (WarDirectory)o;
+ if (!myRelativePath.equals(directory.myRelativePath)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myRelativePath.hashCode();
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WebResource.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WebResource.java
index a33bb7e1a097..53566dbbe205 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WebResource.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/WebResource.java
@@ -36,7 +36,7 @@ public class WebResource implements Serializable {
public WebResource(@NotNull WarDirectory warDirectory, @NotNull String warRelativePath, @NotNull File file) {
myWarDirectory = warDirectory;
- this.warRelativePath = warRelativePath;
+ this.warRelativePath = getAdjustedPath(warRelativePath);
this.file = file;
}
@@ -55,6 +55,10 @@ public class WebResource implements Serializable {
return file;
}
+ private static String getAdjustedPath(final @NotNull String path) {
+ return path.isEmpty() || path.charAt(0) != '/' ? '/' + path : path;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
index 946b00b1f126..1d8addd31369 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.util.KeyValue;
+import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +55,7 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
}
@Override
- public void setNext(@Nullable GradleProjectResolverExtension next) {
+ public void setNext(@NotNull GradleProjectResolverExtension next) {
// there always should be at least gradle basic resolver further in the chain
//noinspection ConstantConditions
assert next != null;
@@ -133,6 +134,12 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
@NotNull
@Override
+ public Set<Class> getToolingExtensionsClasses() {
+ return Collections.emptySet();
+ }
+
+ @NotNull
+ @Override
public List<KeyValue<String, String>> getExtraJvmArgs() {
return Collections.emptyList();
}
@@ -162,4 +169,10 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
@Override
public void preImportCheck() {
}
+
+ @Override
+ public void enhanceTaskProcessing(@NotNull List<String> taskNames,
+ @Nullable String debuggerSetup,
+ @NotNull Consumer<String> initScriptConsumer) {
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
index 8873f25c4157..6f43559f7a11 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
@@ -37,10 +37,7 @@ import com.intellij.openapi.util.KeyValue;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
-import com.intellij.util.BooleanFunction;
-import com.intellij.util.Function;
-import com.intellij.util.PathUtil;
-import com.intellij.util.PathsList;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.net.HttpConfigurable;
@@ -59,6 +56,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
+import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
import org.jetbrains.plugins.gradle.tooling.internal.init.Init;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -91,7 +89,7 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
}
@Override
- public void setNext(@Nullable GradleProjectResolverExtension next) {
+ public void setNext(@NotNull GradleProjectResolverExtension next) {
// should be the last extension in the chain
}
@@ -326,6 +324,17 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
@NotNull
@Override
+ public Set<Class> getToolingExtensionsClasses() {
+ return ContainerUtil.<Class>set(
+ // gradle-tooling-extension-api jar
+ ProjectImportAction.class,
+ // gradle-tooling-extension-impl jar
+ ModelBuildScriptClasspathBuilderImpl.class
+ );
+ }
+
+ @NotNull
+ @Override
public List<KeyValue<String, String>> getExtraJvmArgs() {
if (ExternalSystemApiUtil.isInProcessMode(GradleConstants.SYSTEM_ID)) {
final List<KeyValue<String, String>> extraJvmArgs = ContainerUtil.newArrayList();
@@ -361,6 +370,23 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
}
@Override
+ public void enhanceTaskProcessing(@NotNull List<String> taskNames,
+ @Nullable String debuggerSetup,
+ @NotNull Consumer<String> initScriptConsumer) {
+ if (!StringUtil.isEmpty(debuggerSetup)) {
+ final String[] lines = {
+ "gradle.taskGraph.beforeTask { Task task ->",
+ " if (task instanceof JavaForkOptions) {",
+ " task.jvmArgs '" + debuggerSetup.trim() + '\'',
+ " }" +
+ "}",
+ };
+ final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
+ initScriptConsumer.consume(script);
+ }
+ }
+
+ @Override
public void enhanceRemoteProcessing(@NotNull SimpleJavaParameters parameters) throws ExecutionException {
PathsList classPath = parameters.getClassPath();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
index 3a761b550192..e44c2f937264 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
@@ -47,7 +47,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
-import java.util.*;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
@@ -382,14 +385,15 @@ public class GradleExecutionHelper {
}
@Nullable
- public static File generateInitScript(boolean isBuildSrcProject) {
+ public static File generateInitScript(boolean isBuildSrcProject, @NotNull Set<Class> toolingExtensionClasses) {
InputStream stream = Init.class.getResourceAsStream("/org/jetbrains/plugins/gradle/tooling/internal/init/init.gradle");
try {
if (stream == null) {
LOG.warn("Can't get init script template");
return null;
}
- String s = FileUtil.loadTextAndClose(stream).replaceFirst(Pattern.quote("${EXTENSIONS_JARS_PATH}"), getToolingExtensionsJarPaths());
+ final String toolingExtensionsJarPaths = getToolingExtensionsJarPaths(toolingExtensionClasses);
+ String s = FileUtil.loadTextAndClose(stream).replaceFirst(Pattern.quote("${EXTENSIONS_JARS_PATH}"), toolingExtensionsJarPaths);
if (isBuildSrcProject) {
String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript();
if (buildSrcDefaultInitScript == null) return null;
@@ -482,17 +486,10 @@ public class GradleExecutionHelper {
}
@NotNull
- private static String getToolingExtensionsJarPaths() throws ClassNotFoundException {
- final ArrayList<Class<?>> list = ContainerUtil.newArrayList(
- // add gradle-tooling-extension-api jar
- Class.forName("org.jetbrains.plugins.gradle.model.ProjectImportAction"),
- // add gradle-tooling-extension-impl jar
- Class.forName("org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl")
- );
-
+ private static String getToolingExtensionsJarPaths(@NotNull Set<Class> toolingExtensionClasses) {
StringBuilder buf = new StringBuilder();
buf.append('[');
- for (Iterator<Class<?>> it = list.iterator(); it.hasNext(); ) {
+ for (Iterator<Class> it = toolingExtensionClasses.iterator(); it.hasNext(); ) {
Class<?> aClass = it.next();
String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(aClass));
buf.append('\"').append(jarPath).append('\"');
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectImportNotificationListener.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectImportNotificationListener.java
index 959d0f052d87..6f0674d790df 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectImportNotificationListener.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectImportNotificationListener.java
@@ -27,10 +27,13 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;
+import java.io.File;
+
import static org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder.*;
/**
@@ -64,9 +67,8 @@ public class GradleProjectImportNotificationListener extends ExternalSystemTaskN
NotificationData notification = new NotificationData(
group, errorMessage, NotificationCategory.WARNING, NotificationSource.PROJECT_SYNC);
- final VirtualFile virtualFile = ExternalSystemUtil.waitForTheFile(path);
- if (virtualFile != null) {
- notification.setNavigatable(new OpenFileDescriptor(project, virtualFile));
+ if (path != null) {
+ notification.setNavigatable(new MyNavigatable(new File(path), project));
}
ExternalSystemNotificationManager.getInstance(project).showNotification(id.getProjectSystemId(), notification);
@@ -82,4 +84,40 @@ public class GradleProjectImportNotificationListener extends ExternalSystemTaskN
int end = str.indexOf(close, start + open.length());
return end != -1 ? str.substring(start + open.length(), end) : null;
}
+
+ private static class MyNavigatable implements Navigatable {
+
+ private final @NotNull File myFile;
+ private final @NotNull Project myProject;
+ private volatile OpenFileDescriptor openFileDescriptor;
+
+ public MyNavigatable(@NotNull File file, @NotNull Project project) {
+ myFile = file;
+ myProject = project;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ OpenFileDescriptor fileDescriptor = openFileDescriptor;
+ if (fileDescriptor == null) {
+ final VirtualFile virtualFile = ExternalSystemUtil.waitForTheFile(myFile.getPath());
+ if (virtualFile != null) {
+ openFileDescriptor = fileDescriptor = new OpenFileDescriptor(myProject, virtualFile);
+ }
+ }
+ if (fileDescriptor != null && fileDescriptor.canNavigate()) {
+ fileDescriptor.navigate(requestFocus);
+ }
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return myFile.exists();
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return canNavigate();
+ }
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
index 1df5e1e2ef9e..8a2ffaae36c9 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
@@ -87,33 +87,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
@Nullable final GradleExecutionSettings settings,
@NotNull final ExternalSystemTaskNotificationListener listener)
throws ExternalSystemException, IllegalArgumentException, IllegalStateException {
- final GradleProjectResolverExtension projectResolverChain;
if (settings != null) {
myHelper.ensureInstalledWrapper(id, projectPath, settings, listener);
- List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions();
-
- Deque<GradleProjectResolverExtension> extensions = new ArrayDeque<GradleProjectResolverExtension>();
- for (ClassHolder<? extends GradleProjectResolverExtension> holder : extensionClasses) {
- final GradleProjectResolverExtension extension;
- try {
- extension = holder.getTargetClass().newInstance();
- }
- catch (Throwable e) {
- throw new IllegalArgumentException(
- String.format("Can't instantiate project resolve extension for class '%s'", holder.getTargetClassName()), e);
- }
- final GradleProjectResolverExtension previous = extensions.peekLast();
- if (previous != null) {
- previous.setNext(extension);
- }
- extensions.add(extension);
- }
- projectResolverChain = extensions.peekFirst();
- }
- else {
- projectResolverChain = new BaseGradleProjectResolverExtension();
}
+ final GradleProjectResolverExtension projectResolverChain = createProjectResolverChain(settings);
final DataNode<ProjectData> resultProjectDataNode = myHelper.execute(
projectPath, settings,
new ProjectConnectionDataNodeFunction(
@@ -145,6 +123,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
final List<KeyValue<String, String>> extraJvmArgs = new ArrayList<KeyValue<String, String>>();
final List<String> commandLineArgs = ContainerUtil.newArrayList();
+ final Set<Class> toolingExtensionClasses = ContainerUtil.newHashSet();
for (GradleProjectResolverExtension resolverExtension = projectResolverChain;
resolverExtension != null;
@@ -159,6 +138,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
extraJvmArgs.addAll(resolverExtension.getExtraJvmArgs());
// collect extra command-line arguments
commandLineArgs.addAll(resolverExtension.getExtraCommandLineArgs());
+ // collect tooling extensions classes
+ toolingExtensionClasses.addAll(resolverExtension.getToolingExtensionsClasses());
}
final ParametersList parametersList = new ParametersList();
@@ -171,7 +152,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
// TODO [vlad] remove the check
if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) {
- File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject);
+ File initScript = GradleExecutionHelper.generateInitScript(isBuildSrcProject, toolingExtensionClasses);
if (initScript != null) {
ContainerUtil.addAll(commandLineArgs, GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
}
@@ -260,7 +241,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode);
projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode);
projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode);
- if(!isBuildSrcProject) {
+ if (!isBuildSrcProject) {
final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
allTasks.addAll(moduleTasks);
}
@@ -299,8 +280,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
private void handleBuildSrcProject(@NotNull final DataNode<ProjectData> resultProjectDataNode,
@NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
- if (projectConnectionDataNodeFunction.myIsPreviewMode || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API ||
- !new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) return;
+ if (projectConnectionDataNodeFunction.myIsPreviewMode
+ || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API
+ || !new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) {
+ return;
+ }
final DataNode<ModuleData> buildSrcModuleDataNode =
ExternalSystemApiUtil.find(resultProjectDataNode, ProjectKeys.MODULE, new BooleanFunction<DataNode<ModuleData>>() {
@@ -369,4 +353,48 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
}
}
}
+
+
+ @NotNull
+ public static GradleProjectResolverExtension createProjectResolverChain(@Nullable final GradleExecutionSettings settings) {
+ GradleProjectResolverExtension projectResolverChain;
+ if (settings != null) {
+ List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions();
+
+ Deque<GradleProjectResolverExtension> extensions = new ArrayDeque<GradleProjectResolverExtension>();
+ for (ClassHolder<? extends GradleProjectResolverExtension> holder : extensionClasses) {
+ final GradleProjectResolverExtension extension;
+ try {
+ extension = holder.getTargetClass().newInstance();
+ }
+ catch (Throwable e) {
+ throw new IllegalArgumentException(
+ String.format("Can't instantiate project resolve extension for class '%s'", holder.getTargetClassName()), e);
+ }
+ final GradleProjectResolverExtension previous = extensions.peekLast();
+ if (previous != null) {
+ previous.setNext(extension);
+ if (previous.getNext() != extension) {
+ throw new AssertionError("Illegal next resolver got, current resolver class is " + previous.getClass().getName());
+ }
+ }
+ extensions.add(extension);
+ }
+ projectResolverChain = extensions.peekFirst();
+
+ GradleProjectResolverExtension resolverExtension = projectResolverChain;
+ assert resolverExtension != null;
+ while (resolverExtension.getNext() != null) {
+ resolverExtension = resolverExtension.getNext();
+ }
+ if (!(resolverExtension instanceof BaseGradleProjectResolverExtension)) {
+ throw new AssertionError("Illegal last resolver got of class " + resolverExtension.getClass().getName());
+ }
+ }
+ else {
+ projectResolverChain = new BaseGradleProjectResolverExtension();
+ }
+
+ return projectResolverChain;
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
index 145225ce45d4..b727005db845 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
import com.intellij.openapi.util.KeyValue;
+import com.intellij.util.Consumer;
import org.gradle.tooling.model.idea.IdeaModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -50,7 +51,7 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
void setProjectResolverContext(@NotNull ProjectResolverContext projectResolverContext);
- void setNext(@Nullable GradleProjectResolverExtension projectResolverExtension);
+ void setNext(@NotNull GradleProjectResolverExtension projectResolverExtension);
@Nullable
GradleProjectResolverExtension getNext();
@@ -98,6 +99,14 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
@NotNull
Set<Class> getExtraProjectModelClasses();
+ /**
+ * add paths containing these classes to classpath of gradle tooling extension
+ *
+ * @return classes to be available for gradle
+ */
+ @NotNull
+ Set<Class> getToolingExtensionsClasses();
+
@NotNull
List<KeyValue<String, String>> getExtraJvmArgs();
@@ -111,4 +120,6 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
* Performs project configuration and other checks before the actual project import (before invocation of gradle tooling API).
*/
void preImportCheck();
+
+ void enhanceTaskProcessing(@NotNull List<String> taskNames, @Nullable String debuggerSetup, @NotNull Consumer<String> initScriptConsumer);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
index cf9a5fc90768..4a917ad70443 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
@@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
@@ -120,7 +121,7 @@ public class GradleImplicitContributor implements GradleMethodContextContributor
if (psiType != null) {
final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
GradleResolverUtil.processDeclarations(
- psiManager, processor, state, place, psiType.getCanonicalText());
+ psiManager, processor, state, place, TypesUtil.getQualifiedName(psiType));
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
index cf7474b35744..cbe6a60279c0 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
@@ -198,6 +198,7 @@ public class GradleResolverUtil {
@NotNull PsiElement place,
@NotNull String... fqNames) {
for (String fqName : fqNames) {
+ if(fqName == null) continue;
PsiClass psiClass = psiManager.findClassWithCache(fqName, place.getResolveScope());
if (psiClass != null) {
psiClass.processDeclarations(processor, state, null, place);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
index f0c4e74b4dc6..050e754776e8 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
@@ -21,16 +21,15 @@ import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
@@ -99,7 +98,7 @@ public class GradleTaskContributor implements GradleMethodContextContributor {
PsiImmediateClassType immediateClassType = (PsiImmediateClassType)psiType;
for (PsiType type : immediateClassType.getParameters()) {
GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(methodCall, psiManager, processor, state, place, type.getCanonicalText());
+ GradleResolverUtil.processDeclarations(methodCall, psiManager, processor, state, place, TypesUtil.getQualifiedName(type));
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java
index 3f2084a6083f..4aff47d4b5a3 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleUnresolvedReferenceFilter.java
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import java.util.Set;
@@ -38,6 +39,6 @@ public class GradleUnresolvedReferenceFilter extends GroovyUnresolvedHighlightFi
@Override
public boolean isReject(@NotNull GrReferenceExpression expression) {
final PsiType psiType = GradleResolverUtil.getTypeOf(expression);
- return psiType != null && IGNORE_SET.contains(psiType.getCanonicalText());
+ return psiType != null && IGNORE_SET.contains(TypesUtil.getQualifiedName(psiType));
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java
index 0180eb6e482a..11b1a3e25b85 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/NamedDomainObjectCollectionTypeEnhancer.java
@@ -24,6 +24,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer;
/**
@@ -68,7 +69,7 @@ public class NamedDomainObjectCollectionTypeEnhancer extends GrReferenceTypeEnha
if (namedDomainCollectionType instanceof PsiClassReferenceType) {
final PsiClassReferenceType referenceType = (PsiClassReferenceType)namedDomainCollectionType;
- final String fqName = referenceType.getCanonicalText();
+ final String fqName = TypesUtil.getQualifiedName(referenceType);
if (GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER.equals(fqName)) {
final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(ref.getProject());
return psiManager.createTypeByFQClassName(GradleCommonClassNames.GRADLE_API_SOURCE_SET, ref.getResolveScope());
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java
index afa46a709f91..2248b69a02c3 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleDslAnnotator.java
@@ -27,6 +27,7 @@ import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -54,7 +55,9 @@ public class GradleDslAnnotator implements Annotator {
psiManager.findClassWithCache(GroovyCommonClassNames.DEFAULT_GROOVY_METHODS, element.getResolveScope());
if (canBeMethodOf(referenceExpression.getReferenceName(), defaultGroovyMethodsClass)) return;
- PsiClass containerClass = psiManager.findClassWithCache(psiType.getCanonicalText(), element.getResolveScope());
+ final String qualifiedName = TypesUtil.getQualifiedName(psiType);
+ final PsiClass containerClass =
+ qualifiedName != null ? psiManager.findClassWithCache(qualifiedName, element.getResolveScope()) : null;
if (canBeMethodOf(referenceExpression.getReferenceName(), containerClass)) return;
PsiElement nameElement = referenceExpression.getReferenceNameElement();
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
index 5837c5c103ce..ad8bfea8d856 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
@@ -33,6 +34,8 @@ import org.gradle.tooling.ProjectConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
+import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver;
+import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension;
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -75,18 +78,32 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleE
Function<ProjectConnection, Void> f = new Function<ProjectConnection, Void>() {
@Override
public Void fun(ProjectConnection connection) {
- if (!StringUtil.isEmpty(debuggerSetup)) {
+
+ final List<String> initScripts = ContainerUtil.newArrayList();
+ final GradleProjectResolverExtension projectResolverChain = GradleProjectResolver.createProjectResolverChain(settings);
+ for (GradleProjectResolverExtension resolverExtension = projectResolverChain;
+ resolverExtension != null;
+ resolverExtension = resolverExtension.getNext()) {
+ final String resolverClassName = resolverExtension.getClass().getName();
+ resolverExtension.enhanceTaskProcessing(taskNames, debuggerSetup, new Consumer<String>() {
+ @Override
+ public void consume(String script) {
+ if (StringUtil.isNotEmpty(script)) {
+ ContainerUtil.addAllNotNull(
+ initScripts,
+ "//-- Generated by " + resolverClassName,
+ script,
+ "//");
+ }
+ }
+ });
+ }
+
+ if (!initScripts.isEmpty()) {
try {
final File tempFile = FileUtil.createTempFile("init", ".gradle");
tempFile.deleteOnExit();
- final String[] lines = {
- "gradle.taskGraph.beforeTask { Task task ->",
- " if (task instanceof JavaForkOptions) {",
- " task.jvmArgs '" + debuggerSetup.trim() + '\'',
- "}}",
- };
- FileUtil.writeToFile(tempFile, StringUtil.join(lines, SystemProperties.getLineSeparator()));
-
+ FileUtil.writeToFile(tempFile, StringUtil.join(initScripts, SystemProperties.getLineSeparator()));
ContainerUtil.addAll(scriptParameters, GradleConstants.INIT_SCRIPT_CMD_OPTION, tempFile.getAbsolutePath());
}
catch (IOException e) {
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleDependenciesImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleDependenciesImportingTest.java
new file mode 100644
index 000000000000..41bcbeffc8b5
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleDependenciesImportingTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.importing;
+
+import com.intellij.openapi.roots.DependencyScope;
+import org.gradle.util.GradleVersion;
+import org.junit.Test;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/30/2014
+ */
+@SuppressWarnings("JUnit4AnnotatedMethodInJUnit3TestCase")
+public class GradleDependenciesImportingTest extends GradleImportingTestCase {
+
+ @Test
+ public void testDependencyScopeMerge() throws Exception {
+ createSettingsFile("include 'api', 'impl' ");
+
+ importProject(
+ "allprojects {\n" +
+ " apply plugin: 'java'\n" +
+ "\n" +
+ " sourceCompatibility = 1.5\n" +
+ " version = '1.0'\n" +
+ "\n" +
+ " repositories {\n" +
+ " mavenCentral()\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "dependencies {\n" +
+ " compile project(':api')\n" +
+ " testCompile project(':impl'), 'junit:junit:4.11'\n" +
+ " runtime project(':impl')\n" +
+ "}"
+ );
+
+ assertModules("project", "api", "impl");
+ assertModuleModuleDepScope("project", "api", DependencyScope.COMPILE);
+
+ // scope merge works incorrectly in Gradle lower than 1.12 version
+ if (GradleVersion.version(gradleVersion).compareTo(GradleVersion.version("1.12")) >= 0) {
+ assertModuleModuleDepScope("project", "impl", DependencyScope.RUNTIME, DependencyScope.TEST);
+ }
+
+ assertModuleLibDepScope("project", "Gradle: org.hamcrest:hamcrest-core:1.3", DependencyScope.TEST);
+ assertModuleLibDepScope("project", "Gradle: junit:junit:4.11", DependencyScope.TEST);
+ }
+}
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java
new file mode 100644
index 000000000000..8c57ebb57d29
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleFoldersImportingTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.importing;
+
+import org.junit.Test;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/30/2014
+ */
+@SuppressWarnings("JUnit4AnnotatedMethodInJUnit3TestCase")
+public class GradleFoldersImportingTest extends GradleImportingTestCase {
+
+ @Test
+ public void testBaseJavaProject() throws Exception {
+
+ importProject(
+ "apply plugin: 'java'"
+ );
+
+ assertModules("project");
+ assertContentRoots("project", getProjectPath());
+
+ assertSources("project", "src/main/java");
+ assertResources("project", "src/main/resources");
+ assertTestSources("project", "src/test/java");
+ assertTestResources("project", "src/test/resources");
+ assertExcludes("project", ".gradle", "build");
+
+ assertModuleOutput("project",
+ getProjectPath() + "/build/classes/main",
+ getProjectPath() + "/build/classes/test");
+ }
+}
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java
new file mode 100644
index 000000000000..dd723557b37e
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/importing/GradleImportingTestCase.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.importing;
+
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
+import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
+import com.intellij.openapi.externalSystem.test.ExternalSystemImportingTestCase;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TestDialog;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.gradle.util.GradleVersion;
+import org.gradle.wrapper.GradleWrapperMain;
+import org.intellij.lang.annotations.Language;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.remote.GradleJavaHelper;
+import org.jetbrains.plugins.gradle.settings.DistributionType;
+import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.jetbrains.plugins.gradle.tooling.builder.AbstractModelBuilderTest.DistributionLocator;
+import static org.jetbrains.plugins.gradle.tooling.builder.AbstractModelBuilderTest.SUPPORTED_GRADLE_VERSIONS;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/30/2014
+ */
+@RunWith(value = Parameterized.class)
+public abstract class GradleImportingTestCase extends ExternalSystemImportingTestCase {
+
+ private static final int GRADLE_DAEMON_TTL_MS = 10000;
+
+ public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
+ @Rule public TestName name = new TestName();
+
+ @NotNull
+ @org.junit.runners.Parameterized.Parameter(0)
+ public String gradleVersion;
+ private GradleProjectSettings myProjectSettings;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ myProjectSettings = new GradleProjectSettings();
+ System.setProperty(ExternalSystemExecutionSettings.REMOTE_PROCESS_IDLE_TTL_IN_MS_KEY, String.valueOf(GRADLE_DAEMON_TTL_MS));
+ configureWrapper();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ Messages.setTestDialog(TestDialog.DEFAULT);
+ FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory());
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+
+ @Override
+ public String getName() {
+ String methodName = name.getMethodName();
+ Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
+ if (m.matches()) {
+ methodName = m.group(1);
+ }
+ return methodName;
+ }
+
+ @Parameterized.Parameters(name = "{index}: with Gradle-{0}")
+ public static Collection<Object[]> data() throws Throwable {
+ return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
+ }
+
+ @Override
+ protected String getTestsTempDir() {
+ return "gradleImportTests";
+ }
+
+ @Override
+ protected String getExternalSystemConfigFileName() {
+ return "build.gradle";
+ }
+
+ @Override
+ protected void importProject(@NonNls @Language("Groovy") String config) throws IOException {
+ super.importProject(config);
+ }
+
+ @Override
+ protected ExternalProjectSettings getCurrentExternalProjectSettings() {
+ return myProjectSettings;
+ }
+
+ @Override
+ protected ProjectSystemId getExternalSystemId() {
+ return GradleConstants.SYSTEM_ID;
+ }
+
+ protected VirtualFile createSettingsFile(@NonNls @Language("Groovy") String content) throws IOException {
+ return createProjectSubFile("settings.gradle", content);
+ }
+
+ private void configureWrapper() throws IOException, URISyntaxException {
+
+ final URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
+
+ myProjectSettings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
+ final VirtualFile wrapperJarFrom = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(wrapperJar());
+ assert wrapperJarFrom != null;
+
+ final VirtualFile wrapperJarFromTo = createProjectSubFile("gradle/wrapper/gradle-wrapper.jar");
+ wrapperJarFromTo.setBinaryContent(wrapperJarFrom.contentsToByteArray());
+
+ Properties properties = new Properties();
+ properties.setProperty("distributionBase", "GRADLE_USER_HOME");
+ properties.setProperty("distributionPath", "wrapper/dists");
+ properties.setProperty("zipStoreBase", "GRADLE_USER_HOME");
+ properties.setProperty("zipStorePath", "wrapper/dists");
+ properties.setProperty("distributionUrl", distributionUri.toString());
+
+ StringWriter writer = new StringWriter();
+ properties.store(writer, null);
+
+ createProjectSubFile("gradle/wrapper/gradle-wrapper.properties", writer.toString());
+ }
+
+ private static File wrapperJar() {
+ URI location;
+ try {
+ location = GradleWrapperMain.class.getProtectionDomain().getCodeSource().getLocation().toURI();
+ }
+ catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ if (!location.getScheme().equals("file")) {
+ throw new RuntimeException(String.format("Cannot determine classpath for wrapper Jar from codebase '%s'.", location));
+ }
+ return new File(location.getPath());
+ }
+}
diff --git a/plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml b/plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml
index 898ae3d4e65c..e388edf90249 100644
--- a/plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml
+++ b/plugins/gradle/tooling-extension-api/gradle-tooling-extension-api.iml
@@ -11,108 +11,33 @@
<orderEntry type="module" module-name="annotations" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
- <orderEntry type="module-library">
+ <orderEntry type="module-library" exported="">
<library name="Gradle">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-core-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-messaging-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-native-1.12.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-core-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-messaging-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-groovy-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-native-2.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/buildSrc/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/buildSrc/src/test/resources" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cli/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cpp/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cpp/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ear/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/resources" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/osgi/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/osgi/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/antlr/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/jetty/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/maven/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/maven/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/scala/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/scala/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/jacoco/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/native/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/publish/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/announce/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/open-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/open-api/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core-impl/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core-impl/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/reporting/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/resources/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/javascript/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/performance/src/configPlugin" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/performance/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/code-quality/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-base/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/internal-testing/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services-groovy/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services-groovy/src/test/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/tooling-api/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/core/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/messaging/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/wrapper/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services-groovy/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/native/src/main/java" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library" scope="PROVIDED">
<library name="GradleGuava">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../lib/guava-jdk5-14.0.1.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/guava-jdk5-17.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-build-init-1.12.jar b/plugins/gradle/tooling-extension-api/lib/gradle-build-init-1.12.jar
deleted file mode 100644
index f5437c5c7be1..000000000000
--- a/plugins/gradle/tooling-extension-api/lib/gradle-build-init-1.12.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.0.jar b/plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.0.jar
new file mode 100644
index 000000000000..e2cfa7d8de16
--- /dev/null
+++ b/plugins/gradle/tooling-extension-api/lib/gradle-build-init-2.0.jar
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-ide-1.12.jar b/plugins/gradle/tooling-extension-api/lib/gradle-ide-1.12.jar
deleted file mode 100644
index fa1cb4f86b7c..000000000000
--- a/plugins/gradle/tooling-extension-api/lib/gradle-ide-1.12.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-ide-2.0.jar b/plugins/gradle/tooling-extension-api/lib/gradle-ide-2.0.jar
new file mode 100644
index 000000000000..53bc41aa1c81
--- /dev/null
+++ b/plugins/gradle/tooling-extension-api/lib/gradle-ide-2.0.jar
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-plugins-1.12.jar b/plugins/gradle/tooling-extension-api/lib/gradle-plugins-1.12.jar
deleted file mode 100644
index 61c6f623ceef..000000000000
--- a/plugins/gradle/tooling-extension-api/lib/gradle-plugins-1.12.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.0.jar b/plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.0.jar
new file mode 100644
index 000000000000..ad6f1c80664d
--- /dev/null
+++ b/plugins/gradle/tooling-extension-api/lib/gradle-plugins-2.0.jar
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-scala-1.12.jar b/plugins/gradle/tooling-extension-api/lib/gradle-scala-1.12.jar
deleted file mode 100644
index 986e707fd60a..000000000000
--- a/plugins/gradle/tooling-extension-api/lib/gradle-scala-1.12.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/lib/gradle-scala-2.0.jar b/plugins/gradle/tooling-extension-api/lib/gradle-scala-2.0.jar
new file mode 100644
index 000000000000..60f8f0e56a72
--- /dev/null
+++ b/plugins/gradle/tooling-extension-api/lib/gradle-scala-2.0.jar
Binary files differ
diff --git a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java b/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java
index cd29943a4b0b..7254a916c5a2 100644
--- a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java
+++ b/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java
@@ -18,11 +18,13 @@ package org.jetbrains.plugins.gradle.tooling;
import org.gradle.api.Project;
import org.jetbrains.annotations.NotNull;
+import java.io.Serializable;
+
/**
* @author Vladislav.Soroka
* @since 11/5/13
*/
-public interface ModelBuilderService {
+public interface ModelBuilderService extends Serializable {
boolean canBuild(String modelName);
Object buildAll(String modelName, Project project);
diff --git a/plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml b/plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml
index fbdb344069c2..1bcde5e35b79 100644
--- a/plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml
+++ b/plugins/gradle/tooling-extension-impl/gradle-tooling-extension-impl.iml
@@ -18,112 +18,40 @@
<orderEntry type="module-library">
<library name="Gradle">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-core-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-messaging-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-native-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-build-init-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-plugins-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-ide-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-scala-1.12.jar!/" />
- <root url="jar://$MODULE_DIR$/lib/gradle-reporting-1.12.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-tooling-api-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-core-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-messaging-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-base-services-groovy-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-native-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-build-init-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-plugins-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-ide-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../tooling-extension-api/lib/gradle-scala-2.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/lib/gradle-reporting-2.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/buildSrc/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/buildSrc/src/test/resources" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ui/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cli/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cpp/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/cpp/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ear/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/resources" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/tasks" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java/org/gradle/api/publish/ivy/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ivy/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/osgi/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/osgi/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/antlr/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/jetty/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/maven/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/maven/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/scala/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/scala/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/jacoco/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/native/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/plugins/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/publish/src/main/groovy/org/gradle/api/publish/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/publish/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/wrapper/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/announce/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/launcher/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/open-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/open-api/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core-impl/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/core-impl/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/messaging/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/reporting/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/resources/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/javascript/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/testjar/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/multiModule/webinar-impl/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/singleModule/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/enforcerplugin/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-init/src/integTest/resources/org/gradle/buildinit/plugins/MavenConversionIntegrationTest/flatmultimodule/webinar-impl/src/test/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/diagnostics/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/performance/src/configPlugin" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/performance/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/integTest/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/tooling-api/src/testFixtures/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/code-quality/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/tasks" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy/org/gradle/language/jvm/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-jvm/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-base/src/main/groovy/org/gradle/language/base/plugins" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/language-base/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/source/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/build-comparison/src/integTest/resources/org/gradle/api/plugins/buildcomparison/gradle/BuildComparisonIntegrationSpec/compareArchives/target/src/main/java" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/internal-testing/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services-groovy/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/base-services-groovy/src/test/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/groovy" />
- <root url="jar://$MODULE_DIR$/../lib/gradle-1.12-src.zip!/gradle-1.12/subprojects/ide/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/tooling-api/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/core/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/messaging/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/wrapper/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/base-services-groovy/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/build-init/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/plugins/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/ide/src/main/java" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/ide/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/scala/src/main/groovy" />
+ <root url="jar://$MODULE_DIR$/../lib/gradle-2.0-src.zip!/gradle-2.0/subprojects/reporting/src/main/groovy" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="GradleGuava">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../lib/guava-jdk5-14.0.1.jar!/" />
+ <root url="jar://$MODULE_DIR$/../lib/guava-jdk5-17.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
diff --git a/plugins/gradle/tooling-extension-impl/lib/gradle-reporting-1.12.jar b/plugins/gradle/tooling-extension-impl/lib/gradle-reporting-2.0.jar
index 2e08fccad73e..7b10bf4f89db 100644
--- a/plugins/gradle/tooling-extension-impl/lib/gradle-reporting-1.12.jar
+++ b/plugins/gradle/tooling-extension-impl/lib/gradle-reporting-2.0.jar
Binary files differ
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java
index 71fcdeb482c4..64a3805223d7 100644
--- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java
+++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java
@@ -17,9 +17,10 @@ package org.jetbrains.plugins.gradle.tooling.builder;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
-import org.gradle.api.artifacts.ResolutionStrategy;
+import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.plugins.ide.idea.IdeaPlugin;
import org.gradle.plugins.ide.idea.model.Dependency;
+import org.gradle.plugins.ide.idea.model.IdeaModule;
import org.gradle.plugins.ide.idea.model.ModuleLibrary;
import org.gradle.plugins.ide.idea.model.Path;
import org.gradle.util.GradleVersion;
@@ -31,7 +32,6 @@ import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder;
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService;
import org.jetbrains.plugins.gradle.tooling.internal.BuildScriptClasspathModelImpl;
import org.jetbrains.plugins.gradle.tooling.internal.ClasspathEntryModelImpl;
-import org.jetbrains.plugins.gradle.tooling.internal.ConfigurationDelegate;
import java.io.File;
import java.util.*;
@@ -43,6 +43,10 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class ModelBuildScriptClasspathBuilderImpl implements ModelBuilderService {
+ private static final String COMPILE_SCOPE = "COMPILE";
+ private static final String PLUS_CONFIGURATION = "plus";
+ private static final String MINUS_CONFIGURATION = "minus";
+ private static final String CLASSPATH_CONFIGURATION_NAME = "classpath";
private final Map<String, BuildScriptClasspathModelImpl> cache = new ConcurrentHashMap<String, BuildScriptClasspathModelImpl>();
@Override
@@ -72,44 +76,49 @@ public class ModelBuildScriptClasspathBuilderImpl implements ModelBuilderService
}
}
}
- Configuration configuration = project.getBuildscript().getConfigurations().findByName("classpath");
- if (configuration == null) return null;
-
- final ResolutionStrategy resolutionStrategy = configuration.getResolutionStrategy();
- configuration = new ConfigurationDelegate(configuration.copy()) {
- @Override
- public ResolutionStrategy getResolutionStrategy() {
- return resolutionStrategy;
- }
- };
+ Configuration classpathConfiguration = project.getBuildscript().getConfigurations().findByName(CLASSPATH_CONFIGURATION_NAME);
+ if (classpathConfiguration == null) return null;
+
+ final Configuration configuration;
+ final IdeaModule ideaModule = ideaPlugin.getModel().getModule();
+ final ConfigurationContainer configurations = ideaModule.getProject().getConfigurations();
+
+ if (classpathConfiguration.getState() == Configuration.State.UNRESOLVED) {
+ configuration = classpathConfiguration;
+ configurations.add(configuration);
+ }
+ else {
+ configuration = configurations.maybeCreate(UUID.randomUUID().toString());
+ configuration.getDependencies().addAll(classpathConfiguration.getAllDependencies());
+ configuration.getArtifacts().addAll(classpathConfiguration.getAllArtifacts());
+ }
Collection<Configuration> plusConfigurations = Collections.singletonList(configuration);
final Map<String, Map<String, Collection<Configuration>>> scopes =
- new HashMap<String, Map<String, Collection<Configuration>>>(ideaPlugin.getModel().getModule().getScopes());
+ new HashMap<String, Map<String, Collection<Configuration>>>(ideaModule.getScopes());
Map<String, Map<String, Collection<Configuration>>> buildScriptScope = new HashMap<String, Map<String, Collection<Configuration>>>();
Map<String, Collection<Configuration>> plusConfiguration = new HashMap<String, Collection<Configuration>>();
- plusConfiguration.put("plus", plusConfigurations);
- if (scopes.get("COMPILE") != null) {
- plusConfiguration.put("minus", scopes.get("COMPILE").get("plus"));
+ plusConfiguration.put(PLUS_CONFIGURATION, plusConfigurations);
+ if (scopes.get(COMPILE_SCOPE) != null) {
+ plusConfiguration.put(MINUS_CONFIGURATION, scopes.get(COMPILE_SCOPE).get(PLUS_CONFIGURATION));
}
- buildScriptScope.put("COMPILE", plusConfiguration);
- ideaPlugin.getModel().getModule().setScopes(buildScriptScope);
- ideaPlugin.getModel().getModule().getProject().getConfigurations().add(configuration);
- final Set<Dependency> buildScriptDependencies = ideaPlugin.getModel().getModule().resolveDependencies();
+ buildScriptScope.put(COMPILE_SCOPE, plusConfiguration);
+ ideaModule.setScopes(buildScriptScope);
+ final Set<Dependency> buildScriptDependencies = ideaModule.resolveDependencies();
for (Dependency dependency : buildScriptDependencies) {
if (dependency instanceof ModuleLibrary) {
ModuleLibrary moduleLibrary = (ModuleLibrary)dependency;
- if ("COMPILE".equals(moduleLibrary.getScope())) {
+ if (COMPILE_SCOPE.equals(moduleLibrary.getScope())) {
buildScriptClasspath.add(new ClasspathEntryModelImpl(
convert(moduleLibrary.getClasses()), convert(moduleLibrary.getSources()), convert(moduleLibrary.getJavadoc())));
}
}
}
- ideaPlugin.getModel().getModule().setScopes(scopes);
- ideaPlugin.getModel().getModule().getProject().getConfigurations().remove(configuration);
+ ideaModule.setScopes(scopes);
+ configurations.remove(configuration);
}
cache.put(project.getPath(), buildScriptClasspath);
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.groovy b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.groovy
new file mode 100644
index 000000000000..00f4c8bb0b6e
--- /dev/null
+++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.groovy
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.tooling.builder
+
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.file.FileVisitDetails
+import org.gradle.api.file.FileVisitor
+import org.gradle.api.java.archives.Manifest
+import org.gradle.api.plugins.WarPlugin
+import org.gradle.api.tasks.bundling.War
+import org.gradle.util.GradleVersion
+import org.jetbrains.annotations.NotNull
+import org.jetbrains.annotations.Nullable
+import org.jetbrains.plugins.gradle.model.web.WebConfiguration
+import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
+import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
+import org.jetbrains.plugins.gradle.tooling.internal.web.WarModelImpl
+import org.jetbrains.plugins.gradle.tooling.internal.web.WebConfigurationImpl
+import org.jetbrains.plugins.gradle.tooling.internal.web.WebResourceImpl
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/25/2014
+ */
+class WarModelBuilderImpl implements ModelBuilderService {
+
+ private static final String WEB_APP_DIR_PROPERTY = "webAppDir"
+ private static final String WEB_APP_DIR_NAME_PROPERTY = "webAppDirName"
+
+ @Override
+ public boolean canBuild(String modelName) {
+ return WebConfiguration.name.equals(modelName)
+ }
+
+ @Nullable
+ @Override
+ public Object buildAll(String modelName, Project project) {
+ final WarPlugin warPlugin = project.plugins.findPlugin(WarPlugin)
+ if (warPlugin == null) return null
+
+ final String webAppDirName = !project.hasProperty(WEB_APP_DIR_NAME_PROPERTY) ?
+ "src/main/webapp" : String.valueOf(project.property(WEB_APP_DIR_NAME_PROPERTY))
+
+ final File webAppDir = !project.hasProperty(WEB_APP_DIR_PROPERTY) ? new File(project.projectDir, webAppDirName) :
+ (File)project.property(WEB_APP_DIR_PROPERTY)
+
+ def warModels = []
+
+ project.tasks.each { Task task ->
+ if (task instanceof War) {
+ final WarModelImpl warModel =
+ new WarModelImpl((task as War).archiveName, webAppDirName, webAppDir)
+
+ final List<WebConfiguration.WebResource> webResources = []
+ final War warTask = task as War
+ warModel.webXml = warTask.webXml
+ warTask.rootSpec.setIncludeEmptyDirs(true)
+
+ warTask.rootSpec.walk({ def resolver ->
+ // def resolver ->
+ // in Gradle v1.x - org.gradle.api.internal.file.copy.CopySpecInternal
+ // in Gradle v2.x - org.gradle.api.internal.file.copy.CopySpecResolver
+
+ if (resolver.metaClass.respondsTo(resolver, 'setIncludeEmptyDirs', boolean)) {
+ resolver.setIncludeEmptyDirs(true)
+ }
+ if (!resolver.metaClass.respondsTo(resolver, 'getDestPath') ||
+ !resolver.metaClass.respondsTo(resolver, 'getSource')) {
+ throw new RuntimeException("${GradleVersion.current()} is not supported by web artifact importer")
+ }
+
+ final String relativePath = resolver.destPath.pathString
+ final def sourcePaths
+
+ if (resolver.metaClass.respondsTo(resolver, 'getSourcePaths')) {
+ sourcePaths = resolver.getSourcePaths()
+ } else if (resolver.this$0.metaClass.respondsTo(resolver, 'getSourcePaths')) {
+ sourcePaths = resolver.this$0.getSourcePaths()
+ } else {
+ throw new RuntimeException("${GradleVersion.current()} is not supported by web artifact importer")
+ }
+
+ (sourcePaths.flatten() as List).each { def path ->
+ if (path instanceof String) {
+ def file = new File(warTask.project.projectDir, path)
+ addPath(webResources, relativePath, "", file)
+ }
+ }
+
+
+ resolver.source.visit(new FileVisitor() {
+ @Override
+ public void visitDir(FileVisitDetails dirDetails) {
+ try {
+ addPath(webResources, relativePath, dirDetails.path, dirDetails.file)
+ }
+ catch (Exception ignore) {
+ }
+ }
+
+ @Override
+ public void visitFile(FileVisitDetails fileDetails) {
+ try {
+ if (warTask.webXml == null ||
+ !fileDetails.file.canonicalPath.equals(warTask.webXml.canonicalPath)) {
+ addPath(webResources, relativePath, fileDetails.path, fileDetails.file)
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+ })
+ })
+
+ warModel.webResources = webResources
+ warModel.classpath = warTask.classpath.files
+
+ Manifest manifest = warTask.manifest
+ if (manifest != null) {
+ def writer = new StringWriter()
+ manifest.writeTo(writer)
+ warModel.manifestContent = writer.toString()
+ }
+ warModels.add(warModel)
+ }
+ }
+
+ new WebConfigurationImpl(warModels)
+ }
+
+ @NotNull
+ @Override
+ public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
+ ErrorMessageBuilder.create(
+ project, e, "Web project import errors"
+ ).withDescription("Web Facets/Artifacts will not be configured")
+ }
+
+ private static addPath(List<WebConfiguration.WebResource> webResources, String warRelativePath, String fileRelativePath, File file) {
+ warRelativePath = warRelativePath == null ? "" : warRelativePath
+
+ WebConfiguration.WebResource webResource = new WebResourceImpl(warRelativePath, fileRelativePath, file)
+ webResources.add(webResource)
+ }
+}
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java
deleted file mode 100644
index 62e02eeffc17..000000000000
--- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.gradle.tooling.builder;
-
-import org.gradle.api.Action;
-import org.gradle.api.Project;
-import org.gradle.api.Task;
-import org.gradle.api.file.FileVisitDetails;
-import org.gradle.api.file.FileVisitor;
-import org.gradle.api.internal.file.copy.CopySpecInternal;
-import org.gradle.api.java.archives.Manifest;
-import org.gradle.api.plugins.WarPlugin;
-import org.gradle.api.tasks.bundling.War;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.model.web.WebConfiguration;
-import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder;
-import org.jetbrains.plugins.gradle.tooling.ModelBuilderService;
-import org.jetbrains.plugins.gradle.tooling.internal.web.WarModelImpl;
-import org.jetbrains.plugins.gradle.tooling.internal.web.WebConfigurationImpl;
-import org.jetbrains.plugins.gradle.tooling.internal.web.WebResourceImpl;
-
-import java.io.File;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Vladislav.Soroka
- * @since 11/5/13
- */
-public class WarModelBuilderImpl implements ModelBuilderService {
-
- private static final String WEB_APP_DIR_PROPERTY = "webAppDir";
- private static final String WEB_APP_DIR_NAME_PROPERTY = "webAppDirName";
-
- @Override
- public boolean canBuild(String modelName) {
- return WebConfiguration.class.getName().equals(modelName);
- }
-
- @Nullable
- @Override
- public Object buildAll(String modelName, Project project) {
- final WarPlugin warPlugin = project.getPlugins().findPlugin(WarPlugin.class);
- if (warPlugin == null) return null;
-
- final String webAppDirName = !project.hasProperty(WEB_APP_DIR_NAME_PROPERTY) ?
- "src/main/webapp" : String.valueOf(project.property(WEB_APP_DIR_NAME_PROPERTY));
-
- final File webAppDir = !project.hasProperty(WEB_APP_DIR_PROPERTY)
- ? new File(project.getProjectDir(), webAppDirName)
- : (File)project.property(WEB_APP_DIR_PROPERTY);
-
-
- List<WebConfiguration.WarModel> warModels = new ArrayList<WebConfiguration.WarModel>();
-
-
- for (Task task : project.getTasks()) {
- if (task instanceof War) {
- final WarModelImpl warModel =
- new WarModelImpl(((War)task).getArchiveName(), webAppDirName, webAppDir);
- final List<WebConfiguration.WebResource> webResources = new ArrayList<WebConfiguration.WebResource>();
-
- final War warTask = (War)task;
- warModel.setWebXml(warTask.getWebXml());
-
- warTask.getRootSpec().walk(new Action<CopySpecInternal>() {
- @Override
- public void execute(CopySpecInternal internal) {
- final String relativePath = internal.getDestPath().getPathString();
- internal.getSource().visit(new FileVisitor() {
- @Override
- public void visitDir(FileVisitDetails dirDetails) {
- try {
- addPath(webResources, relativePath, dirDetails.getPath(), dirDetails.getFile());
- }
- catch (Exception ignore) {
- }
- }
-
- @Override
- public void visitFile(FileVisitDetails fileDetails) {
- try {
- if (warTask.getWebXml() == null ||
- !fileDetails.getFile().getCanonicalPath().equals(warTask.getWebXml().getCanonicalPath())) {
- addPath(webResources, relativePath, fileDetails.getPath(), fileDetails.getFile());
- }
- }
- catch (Exception ignore) {
- }
- }
- });
- }
- });
-
- warModel.setWebResources(webResources);
- warModel.setClasspath(warTask.getClasspath().getFiles());
-
- Manifest manifest = warTask.getManifest();
- if (manifest != null) {
- StringWriter writer = new StringWriter();
- manifest.writeTo(writer);
- warModel.setManifestContent(writer.toString());
- }
- warModels.add(warModel);
- }
- }
-
- return new WebConfigurationImpl(warModels);
- }
-
- @NotNull
- @Override
- public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
- return ErrorMessageBuilder.create(
- project, e, "Web project import errors"
- ).withDescription("Web Facets/Artifacts will not be configured");
- }
-
- private static void addPath(List<WebConfiguration.WebResource> webResources, String warRelativePath, String fileRelativePath, File file) {
- warRelativePath = warRelativePath == null ? "" : warRelativePath;
-
- WebConfiguration.WebResource webResource = new WebResourceImpl(warRelativePath, fileRelativePath, file);
- webResources.add(webResource);
- }
-}
diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ConfigurationDelegate.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ConfigurationDelegate.java
deleted file mode 100644
index 39c087f48e91..000000000000
--- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ConfigurationDelegate.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.gradle.tooling.internal;
-
-import groovy.lang.Closure;
-import org.gradle.api.artifacts.*;
-import org.gradle.api.file.FileCollection;
-import org.gradle.api.file.FileTree;
-import org.gradle.api.specs.Spec;
-import org.gradle.api.tasks.StopExecutionException;
-import org.gradle.api.tasks.TaskDependency;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Vladislav.Soroka
- * @since 5/28/2014
- */
-public class ConfigurationDelegate implements Configuration {
- @NotNull
- private final Configuration delegate;
-
- public ConfigurationDelegate(@NotNull Configuration configuration) {
- delegate = configuration;
- }
-
- @Override
- public ResolutionStrategy getResolutionStrategy() {
- return delegate.getResolutionStrategy();
- }
-
- @Override
- public Configuration resolutionStrategy(Closure closure) {
- return delegate.resolutionStrategy(closure);
- }
-
- @Override
- public State getState() {
- return delegate.getState();
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public boolean isVisible() {
- return delegate.isVisible();
- }
-
- @Override
- public Configuration setVisible(boolean visible) {
- return delegate.setVisible(visible);
- }
-
- @Override
- public Set<Configuration> getExtendsFrom() {
- return delegate.getExtendsFrom();
- }
-
- @Override
- public Configuration setExtendsFrom(Set<Configuration> superConfigs) {
- return delegate.setExtendsFrom(superConfigs);
- }
-
- @Override
- public Configuration extendsFrom(Configuration... superConfigs) {
- return delegate.extendsFrom(superConfigs);
- }
-
- @Override
- public boolean isTransitive() {
- return delegate.isTransitive();
- }
-
- @Override
- public Configuration setTransitive(boolean t) {
- return delegate.setTransitive(t);
- }
-
- @Override
- public String getDescription() {
- return delegate.getDescription();
- }
-
- @Override
- public Configuration setDescription(String description) {
- return delegate.setDescription(description);
- }
-
- @Override
- public Set<Configuration> getHierarchy() {
- return delegate.getHierarchy();
- }
-
- @Override
- public Set<File> resolve() {
- return delegate.resolve();
- }
-
- @Override
- public Set<File> files(Closure dependencySpecClosure) {
- return delegate.files(dependencySpecClosure);
- }
-
- @Override
- public Set<File> files(Spec<? super Dependency> dependencySpec) {
- return delegate.files(dependencySpec);
- }
-
- @Override
- public Set<File> files(Dependency... dependencies) {
- return delegate.files(dependencies);
- }
-
- @Override
- public FileCollection fileCollection(Spec<? super Dependency> dependencySpec) {
- return delegate.fileCollection(dependencySpec);
- }
-
- @Override
- public FileCollection fileCollection(Closure dependencySpecClosure) {
- return delegate.fileCollection(dependencySpecClosure);
- }
-
- @Override
- public FileCollection fileCollection(Dependency... dependencies) {
- return delegate.fileCollection(dependencies);
- }
-
- @Override
- public ResolvedConfiguration getResolvedConfiguration() {
- return delegate.getResolvedConfiguration();
- }
-
- @Override
- public String getUploadTaskName() {
- return delegate.getUploadTaskName();
- }
-
- @Override
- public TaskDependency getBuildDependencies() {
- return delegate.getBuildDependencies();
- }
-
- @Override
- public TaskDependency getTaskDependencyFromProjectDependency(boolean useDependedOn, String taskName) {
- return delegate.getTaskDependencyFromProjectDependency(useDependedOn, taskName);
- }
-
- @Override
- public DependencySet getDependencies() {
- return delegate.getDependencies();
- }
-
- @Override
- public DependencySet getAllDependencies() {
- return delegate.getAllDependencies();
- }
-
- @Override
- public PublishArtifactSet getArtifacts() {
- return delegate.getArtifacts();
- }
-
- @Override
- public PublishArtifactSet getAllArtifacts() {
- return delegate.getAllArtifacts();
- }
-
- @Override
- public Set<ExcludeRule> getExcludeRules() {
- return delegate.getExcludeRules();
- }
-
- @Override
- public Configuration exclude(Map<String, String> excludeProperties) {
- return delegate.exclude(excludeProperties);
- }
-
- @Override
- public Set<Configuration> getAll() {
- return delegate.getAll();
- }
-
- @Override
- public ResolvableDependencies getIncoming() {
- return delegate.getIncoming();
- }
-
- @Override
- public Configuration copy() {
- return delegate.copy();
- }
-
- @Override
- public Configuration copyRecursive() {
- return delegate.copyRecursive();
- }
-
- @Override
- public Configuration copy(Spec<? super Dependency> dependencySpec) {
- return delegate.copy(dependencySpec);
- }
-
- @Override
- public Configuration copyRecursive(Spec<? super Dependency> dependencySpec) {
- return delegate.copyRecursive(dependencySpec);
- }
-
- @Override
- public Configuration copy(Closure dependencySpec) {
- return delegate.copy(dependencySpec);
- }
-
- @Override
- public Configuration copyRecursive(Closure dependencySpec) {
- return delegate.copyRecursive(dependencySpec);
- }
-
- @Override
- public File getSingleFile() throws IllegalStateException {
- return delegate.getSingleFile();
- }
-
- @Override
- public Set<File> getFiles() {
- return delegate.getFiles();
- }
-
- @Override
- public boolean contains(File file) {
- return delegate.contains(file);
- }
-
- @Override
- public String getAsPath() {
- return delegate.getAsPath();
- }
-
- @Override
- public FileCollection plus(FileCollection collection) {
- return delegate.plus(collection);
- }
-
- @Override
- public FileCollection minus(FileCollection collection) {
- return delegate.minus(collection);
- }
-
- @Override
- public FileCollection filter(Closure filterClosure) {
- return delegate.filter(filterClosure);
- }
-
- @Override
- public FileCollection filter(Spec<? super File> filterSpec) {
- return delegate.filter(filterSpec);
- }
-
- @Override
- public Object asType(Class<?> type) throws UnsupportedOperationException {
- return delegate.asType(type);
- }
-
- @Override
- public FileCollection add(FileCollection collection) throws UnsupportedOperationException {
- return delegate.add(collection);
- }
-
- @Override
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- @Override
- public FileCollection stopExecutionIfEmpty() throws StopExecutionException {
- return delegate.stopExecutionIfEmpty();
- }
-
- @Override
- public FileTree getAsFileTree() {
- return delegate.getAsFileTree();
- }
-
- @Override
- public void addToAntBuilder(Object builder, String nodeName, AntType type) {
- delegate.addToAntBuilder(builder, nodeName, type);
- }
-
- @Override
- public Object addToAntBuilder(Object builder, String nodeName) {
- return delegate.addToAntBuilder(builder, nodeName);
- }
-
- @Override
- public Iterator<File> iterator() {
- return delegate.iterator();
- }
-}
diff --git a/plugins/gradle/tooling-extension-impl/testData/testDefaultWarModel/build.gradle b/plugins/gradle/tooling-extension-impl/testData/testDefaultWarModel/build.gradle
index f66f30f1c15e..890f46fe6832 100644
--- a/plugins/gradle/tooling-extension-impl/testData/testDefaultWarModel/build.gradle
+++ b/plugins/gradle/tooling-extension-impl/testData/testDefaultWarModel/build.gradle
@@ -1,3 +1,42 @@
//noinspection GrPackage
apply plugin: 'war'
+
+configurations {
+ moreLibs
+}
+
+//repositories {
+// flatDir { dirs "lib" }
+// mavenCentral()
+//}
+//
+//dependencies {
+// compile module(":compile:1.0") {
+// dependency ":compile-transitive-1.0@jar"
+// dependency ":providedCompile-transitive:1.0@jar"
+// }
+// providedCompile "javax.servlet:servlet-api:2.5"
+// providedCompile module(":providedCompile:1.0") {
+// dependency ":providedCompile-transitive:1.0@jar"
+// }
+// runtime ":runtime:1.0"
+// providedRuntime ":providedRuntime:1.0@jar"
+// testCompile "junit:junit:4.11"
+// moreLibs ":otherLib:1.0"
+//
+// runtime files('extras')
+//}
+
+
+war {
+ from('src/rootContent') {
+ into 'bar'
+ }
+ webInf { from 'src/additionalWebInf' } // adds a file-set to the WEB-INF dir.
+ exclude 'excl'
+ classpath fileTree('additionalLibs') // adds a file-set to the WEB-INF/lib dir.
+ classpath configurations.moreLibs // adds a configuration to the WEB-INF/lib dir.
+ webXml = file('src/someWeb.xml') // copies a file to WEB-INF/web.xml
+ classpath file('src/bbb')
+} \ No newline at end of file
diff --git a/plugins/gradle/tooling-extension-impl/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle b/plugins/gradle/tooling-extension-impl/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
index 83fcd7abb38a..93e11920b30f 100644
--- a/plugins/gradle/tooling-extension-impl/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
+++ b/plugins/gradle/tooling-extension-impl/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
@@ -20,7 +20,7 @@ allprojects {
idea {
module {
- scopes.PROVIDED.plus += configurations.provided
+ scopes.PROVIDED.plus += [configurations.provided]
}
}
}
diff --git a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/AbstractModelBuilderTest.java b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/AbstractModelBuilderTest.java
index e961117f7d2d..d09a9b7c5e3c 100644
--- a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/AbstractModelBuilderTest.java
+++ b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/AbstractModelBuilderTest.java
@@ -15,16 +15,21 @@
*/
package org.jetbrains.plugins.gradle.tooling.builder;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.UsefulTestCase;
-import com.intellij.util.ObjectUtils;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.BuildActionExecuter;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -39,13 +44,12 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
@@ -55,12 +59,12 @@ import static org.junit.Assert.assertNotNull;
@RunWith(value = Parameterized.class)
public abstract class AbstractModelBuilderTest {
- public static final String GRADLE_v1_9 = "1.9";
- public static final String GRADLE_v1_10 = "1.10";
- public static final String GRADLE_v1_11 = "1.11";
- public static final String GRADLE_v1_12 = "1.12-rc-1";
+ public static final Object[][] SUPPORTED_GRADLE_VERSIONS = {
+ {"1.9"}, {"1.10"}, {"1.11"}, {"1.12"},
+ {"2.0"}
+ };
- public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*)\\]");
+ public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
private static File ourTempDir;
@@ -75,15 +79,9 @@ public abstract class AbstractModelBuilderTest {
this.gradleVersion = gradleVersion;
}
- @Parameterized.Parameters
+ @Parameterized.Parameters(name = "{index}: with Gradle-{0}")
public static Collection<Object[]> data() {
- Object[][] data = {
- {AbstractModelBuilderTest.GRADLE_v1_9},
- {AbstractModelBuilderTest.GRADLE_v1_10},
- {AbstractModelBuilderTest.GRADLE_v1_11},
- {AbstractModelBuilderTest.GRADLE_v1_12}
- };
- return Arrays.asList(data);
+ return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
}
@@ -112,21 +110,12 @@ public abstract class AbstractModelBuilderTest {
GradleConnector connector = GradleConnector.newConnector();
- String releaseRepoUrl = DistributionLocator.getRepoUrl(false);
- String snapshotRepoUrl = DistributionLocator.getRepoUrl(true);
-
- if (releaseRepoUrl == null || snapshotRepoUrl == null) {
- connector.useGradleVersion(gradleVersion);
- }
- else {
- final URI distributionUri =
- new DistributionLocator(releaseRepoUrl, snapshotRepoUrl).getDistributionFor(GradleVersion.version(gradleVersion));
- connector.useDistribution(distributionUri);
- }
+ final URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
+ connector.useDistribution(distributionUri);
connector.forProjectDirectory(testDir);
- int daemonMaxIdleTime = 1;
+ int daemonMaxIdleTime = 10;
try {
- daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "1"));
+ daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
}
catch (NumberFormatException ignore) {}
@@ -136,13 +125,31 @@ public abstract class AbstractModelBuilderTest {
final ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
- File initScript = GradleExecutionHelper.generateInitScript(false);
+ File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
buildActionExecutor.withArguments(GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
allModels = buildActionExecutor.run();
assertNotNull(allModels);
}
+ @NotNull
+ private Set<Class> getToolingExtensionClasses() {
+ final Set<Class> classes = ContainerUtil.<Class>set(
+ // gradle-tooling-extension-api jar
+ ProjectImportAction.class,
+ // gradle-tooling-extension-impl jar
+ ModelBuildScriptClasspathBuilderImpl.class
+ );
+
+ ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
+ return classes;
+ }
+
+ @NotNull
+ protected Set<Class> doGetToolingExtensionClasses() {
+ return Collections.emptySet();
+ }
+
@After
public void tearDown() throws Exception {
if (testDir != null) {
@@ -152,6 +159,43 @@ public abstract class AbstractModelBuilderTest {
protected abstract Set<Class> getModels();
+
+ protected <T> Map<String, T> getModulesMap(final Class<T> aClass) {
+ final DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
+
+ final String filterKey = "to_filter";
+ final Map<String, T> map = ContainerUtil.map2Map(ideaModules, new Function<IdeaModule, Pair<String, T>>() {
+ @Override
+ public Pair<String, T> fun(IdeaModule module) {
+ final T value = allModels.getExtraProject(module, aClass);
+ final String key = value != null ? module.getGradleProject().getPath() : filterKey;
+ return Pair.create(key, value);
+ }
+ });
+
+ map.remove(filterKey);
+ return map;
+ }
+
+ protected void assertBuildClasspath(String projectPath, String... classpath) {
+ final Map<String, BuildScriptClasspathModel> classpathModelMap = getModulesMap(BuildScriptClasspathModel.class);
+ final BuildScriptClasspathModel classpathModel = classpathModelMap.get(projectPath);
+
+ assertNotNull(classpathModel);
+
+ final List<? extends ClasspathEntryModel> classpathEntryModels = classpathModel.getClasspath().getAll();
+ assertEquals(classpath.length, classpathEntryModels.size());
+
+ for (int i = 0, length = classpath.length; i < length; i++) {
+ String classpathEntry = classpath[i];
+ final ClasspathEntryModel classpathEntryModel = classpathEntryModels.get(i);
+ assertNotNull(classpathEntryModel);
+ assertEquals(1, classpathEntryModel.getClasses().size());
+ final String path = classpathEntryModel.getClasses().iterator().next();
+ assertEquals(classpathEntry, new File(path).getName());
+ }
+ }
+
private static void ensureTempDirCreated() throws IOException {
if (ourTempDir != null) return;
@@ -160,18 +204,24 @@ public abstract class AbstractModelBuilderTest {
FileUtil.ensureExists(ourTempDir);
}
- private static class DistributionLocator {
+ public static class DistributionLocator {
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
private static final String INTELLIJ_LABS_GRADLE_RELEASE_MIRROR =
"http://services.gradle.org-mirror.labs.intellij.net/distributions";
private static final String INTELLIJ_LABS_GRADLE_SNAPSHOT_MIRROR =
"http://services.gradle.org-mirror.labs.intellij.net/distributions-snapshots";
+ private static final String GRADLE_RELEASE_REPO = "http://services.gradle.org/distributions";
+ private static final String GRADLE_SNAPSHOT_REPO = "http://services.gradle.org/distributions-snapshots";
@NotNull private final String myReleaseRepoUrl;
@NotNull private final String mySnapshotRepoUrl;
- private DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
+ public DistributionLocator() {
+ this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
+ }
+
+ public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
myReleaseRepoUrl = releaseRepoUrl;
mySnapshotRepoUrl = snapshotRepoUrl;
}
@@ -193,12 +243,16 @@ public abstract class AbstractModelBuilderTest {
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
}
- @Nullable
- static String getRepoUrl(boolean isSnapshotUrl) {
- return ObjectUtils.chooseNotNull(
- System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV),
- UsefulTestCase.IS_UNDER_TEAMCITY ? isSnapshotUrl ? INTELLIJ_LABS_GRADLE_SNAPSHOT_MIRROR : INTELLIJ_LABS_GRADLE_RELEASE_MIRROR : null
- );
+ @NotNull
+ public static String getRepoUrl(boolean isSnapshotUrl) {
+ final String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
+ if (envRepoUrl != null) return envRepoUrl;
+
+ if (UsefulTestCase.IS_UNDER_TEAMCITY) {
+ return isSnapshotUrl ? INTELLIJ_LABS_GRADLE_SNAPSHOT_MIRROR : INTELLIJ_LABS_GRADLE_RELEASE_MIRROR;
+ }
+
+ return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
}
}
}
diff --git a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/WebConfigurationBuilderImplTest.java b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/WebConfigurationBuilderImplTest.java
index 69ff9052032f..b306168eb636 100644
--- a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/WebConfigurationBuilderImplTest.java
+++ b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/builder/WebConfigurationBuilderImplTest.java
@@ -26,6 +26,9 @@ import org.junit.Test;
import java.util.List;
import java.util.Set;
+import static org.jetbrains.plugins.gradle.model.web.WebConfiguration.WarModel;
+import static org.jetbrains.plugins.gradle.model.web.WebConfiguration.WebResource;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
@@ -53,8 +56,17 @@ public class WebConfigurationBuilderImplTest extends AbstractModelBuilderTest {
WebConfiguration webConfiguration = ideaModule.get(0);
assertEquals(1, webConfiguration.getWarModels().size());
- final WebConfiguration.WarModel warModel = webConfiguration.getWarModels().iterator().next();
+ final WarModel warModel = webConfiguration.getWarModels().iterator().next();
assertEquals("src/main/webapp", warModel.getWebAppDirName());
+
+ assertArrayEquals(
+ new String[]{"MANIFEST.MF", "additionalWebInf", "rootContent"},
+ ContainerUtil.map2Array(warModel.getWebResources(), new Function<WebResource, Object>() {
+ @Override
+ public String fun(WebResource resource) {
+ return resource.getFile().getName();
+ }
+ }));
}
@Override
diff --git a/plugins/groovy/groovy-psi/resources/inspectionDescriptions/ClashingTraitMethods.html b/plugins/groovy/groovy-psi/resources/inspectionDescriptions/ClashingTraitMethods.html
new file mode 100644
index 000000000000..1b42605e5013
--- /dev/null
+++ b/plugins/groovy/groovy-psi/resources/inspectionDescriptions/ClashingTraitMethods.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+<font face="verdana" size="-1">
+ Assume you have two traits which contains methods with the same signatures e.g. 'foo()' and you create a class 'MyImplementor' implementing both these traits. So the result of invoking
+ 'new MyImplementor().foo()' can be unexpected.
+ This inspection reports classes which have such a problem.
+</font>
+</body>
+</html>
diff --git a/plugins/groovy/groovy-psi/src/META-INF/GroovyPlugin.xml b/plugins/groovy/groovy-psi/src/META-INF/GroovyPlugin.xml
deleted file mode 100644
index 9dadde4b464a..000000000000
--- a/plugins/groovy/groovy-psi/src/META-INF/GroovyPlugin.xml
+++ /dev/null
@@ -1,1682 +0,0 @@
-<!--
- ~ Copyright 2000-2009 JetBrains s.r.o.
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- ~
- -->
-
-<idea-plugin>
- <id>org.intellij.groovy</id>
- <name>Groovy</name>
- <description>Plugin for Groovy language support, including Groovy++, Grape, Gant and Griffon</description>
- <version>9.0</version>
- <vendor>JetBrains</vendor>
- <depends>com.intellij.properties</depends>
-
- <depends optional="true" config-file="groovy-copyright.xml">com.intellij.copyright</depends>
- <depends optional="true" config-file="intellilang-groovy-support.xml">org.intellij.intelliLang</depends>
- <depends optional="true">AntSupport</depends>
- <depends optional="true">cucumber</depends>
- <depends optional="true">ByteCodeViewer</depends>
-
- <extensionPoints>
- <extensionPoint name="methodComparator" interface="org.jetbrains.plugins.groovy.lang.resolve.GrMethodComparator"/>
- <extensionPoint name="membersContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor"/>
- <extensionPoint name="defaultImportContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.DefaultImportContributor"/>
- <extensionPoint name="astTransformContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor"/>
- <extensionPoint name="closureMissingMethodContributor"
- interface="org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor"/>
- <extensionPoint name="variableEnhancer" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrVariableEnhancer"/>
- <extensionPoint name="referenceTypeEnhancer" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer"/>
- <extensionPoint name="typeConverter" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter"/>
- <extensionPoint name="expectedTypesContributor"
- interface="org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesContributor"/>
-
- <extensionPoint name="positionManagerDelegate"
- interface="org.jetbrains.plugins.groovy.extensions.debugger.ScriptPositionManagerHelper"/>
- <extensionPoint name="compilerExtension" interface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerExtension"/>
- <extensionPoint name="scriptTypeDetector" interface="org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector"/>
-
- <extensionPoint name="namedArgumentProvider" interface="org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider"/>
- <extensionPoint name="mapContentProvider" interface="org.jetbrains.plugins.groovy.extensions.GroovyMapContentProvider"/>
-
- <extensionPoint name="unresolvedHighlightFilter" interface="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter"/>
- <extensionPoint name="unresolvedHighlightFileFilter"
- interface="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFileFilter"/>
- <extensionPoint name="configSlurperSupport" interface="org.jetbrains.plugins.groovy.configSlurper.ConfigSlurperSupport"/>
-
- <extensionPoint name="callExpressionTypeCalculator"
- interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrCallExpressionTypeCalculator"/>
- <extensionPoint name="classDescriptor" beanClass="org.jetbrains.plugins.groovy.extensions.GroovyClassDescriptor"/>
- <extensionPoint name="methodDescriptor" beanClass="org.jetbrains.plugins.groovy.extensions.GroovyMethodDescriptorExtension"/>
-
- <extensionPoint name="groovyShellRunner" interface="org.jetbrains.plugins.groovy.console.GroovyShellRunner"/>
-
- <!-- Groovy DSL extension points -->
- <extensionPoint name="psiEnhancerCategory" interface="org.jetbrains.plugins.groovy.dsl.psi.PsiEnhancerCategory"/>
- <extensionPoint name="gdslTopLevelProvider" interface="org.jetbrains.plugins.groovy.dsl.dsltop.GdslMembersProvider"/>
-
- <extensionPoint name="groovyFrameworkConfigNotification"
- interface="org.jetbrains.plugins.groovy.annotator.GroovyFrameworkConfigNotification"/>
- <extensionPoint name="groovySourceFolderDetector" interface="org.jetbrains.plugins.groovy.actions.GroovySourceFolderDetector"/>
-
- <extensionPoint name="mvc.framework" interface="org.jetbrains.plugins.groovy.mvc.MvcFramework"/>
-
- <extensionPoint name="closureCompleter" interface="org.jetbrains.plugins.groovy.lang.completion.ClosureCompleter"/>
-
- <extensionPoint name="methodMayBeStaticInspectionFilter" interface="org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStaticInspectionFilter"/>
-
- <extensionPoint name="customAnnotationChecker" interface="org.jetbrains.plugins.groovy.annotator.checkers.CustomAnnotationChecker"/>
-
- <extensionPoint name="convertToJava.customMethodInvocator" interface="org.jetbrains.plugins.groovy.refactoring.convertToJava.invocators.CustomMethodInvocator"/>
-
- <extensionPoint name="signatureHintProcessor" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SignatureHintProcessor"/>
- </extensionPoints>
-
- <extensions defaultExtensionNs="org.intellij.groovy">
-
- <groovyFrameworkConfigNotification order="last"
- implementation="org.jetbrains.plugins.groovy.config.DefaultGroovyFrameworkConfigNotification"/>
-
- <membersContributor implementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicMembersContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.GrCollectionTypeMembersProvider"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.spock.SpockMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.swingBuilder.SwingBuilderNonCodeMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.dgm.DGMMemberContributor"/>
-
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebSpockTestMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebPageMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebModuleMemberContributor"/>
-
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebJUnitTestMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebTestNGTestMemberContributor"/>
- <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebBrowserMemberContributor"/>
-
- <membersContributor implementation="org.jetbrains.plugins.groovy.gant.GantMemberContributor"/>
-
- <membersContributor implementation="org.jetbrains.plugins.groovy.markup.XmlMarkupBuilderNonCodeMemberContributor"/>
-
- <closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
-
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.DelegatedMethodsContributor"/>
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoExternalizeContributor"/>
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoCloneContributor"/>
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.ConstructorAnnotationsProcessor"/>
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.GrInheritConstructorContributor"/>
- <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.LoggingContributor"/>
-
- <positionManagerDelegate implementation="org.jetbrains.plugins.groovy.gant.GantPositionManagerHelper"/>
-
- <methodDescriptor lightMethodKey="SwingBuilder_builder_method"
- namedArgsProvider="org.jetbrains.plugins.groovy.swingBuilder.SwingBuilderNamedArgumentProvider"/>
-
- <mapContentProvider implementation="org.jetbrains.plugins.groovy.configSlurper.ConfigSlurperMapContentProvider"/>
- <referenceTypeEnhancer implementation="org.jetbrains.plugins.groovy.configSlurper.GroovyMapValueTypeEnhancer"/>
-
- <unresolvedHighlightFilter implementation="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedReferenceFilterByFile"/>
-
- <callExpressionTypeCalculator
- implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.DefaultCallExpressionTypeCalculator"
- order="last"/>
- <callExpressionTypeCalculator
- implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDescriptorReturnTypeCalculator"/>
- <callExpressionTypeCalculator
- implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDGMTypeCalculator"/>
-
- <scriptTypeDetector implementation="org.jetbrains.plugins.groovy.gant.GantScriptTypeDetector"/>
-
- <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovySourceCodeNamedArgumentProvider" order="last"/>
- <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovyConstructorNamedArgumentProvider"/>
- <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovyMethodReturnNamedArgumentProvider" order="last"/>
-
-
-
- <!-- GroovyDSL extensions -->
- <gdslTopLevelProvider implementation="org.jetbrains.plugins.groovy.dsl.dsltop.GroovyDslDefaultMembers"/>
- <gdslTopLevelProvider implementation="org.jetbrains.plugins.groovy.lang.resolve.GdkMethodDslProvider"/>
- <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiClassCategory"/>
- <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiElementCategory"/>
- <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiMethodCategory"/>
- <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiExpressionCategory"/>
-
- <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer"/>
- <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureAsAnonymousParameterEnhancer"/>
- <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParamsEnhancer"/>
-
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FromStringHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SimpleTypeHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.MapEntryOrKeyValueHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FromAbstractTypeMethodsHintProcessor"/>
-
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$FirstGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$SecondGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$ThirdGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$Component"/>
-
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$FirstGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$SecondGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$ThirdGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$Component"/>
-
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$FirstGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$SecondGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$ThirdGeneric"/>
- <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$Component"/>
-
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerTypeConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrStringTypeConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrBooleanTypeConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrGenericTypeConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureToSamConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrStringConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.gpp.GppTypeConverter"/>
- <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrNumberConverter"/>
-
- <expectedTypesContributor implementation="org.jetbrains.plugins.groovy.gpp.GppExpectedTypesContributor"/>
- <variableEnhancer implementation="org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider"/>
-
- <mvc.framework implementation="org.jetbrains.plugins.groovy.griffon.GriffonFramework"/>
- <groovyFrameworkConfigNotification implementation="org.jetbrains.plugins.groovy.griffon.GriffonConfigureNotification"/>
- <defaultImportContributor implementation="org.jetbrains.plugins.groovy.griffon.GriffonDefaultImportContributor"/>
-
- <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.GroovyConsoleRunner" order="last"/>
-
- <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.GdslClosureCompleter"/>
- <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.EachWithIndexClosureCompleter"/>
-
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.FieldAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.NewifyAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.GrabAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.GrAliasAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.AnnotationCollectorChecker" order="first"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.DelegatesToAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.griffon.GriffonPropertyListenerAnnotationChecker"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.BaseScriptAnnotationChecker"/>
-
- <convertToJava.customMethodInvocator implementation="org.jetbrains.plugins.groovy.refactoring.convertToJava.invocators.MapGetterSetterInvocator"/>
- <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.TypeCheckedAnnotationChecker"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.intellij.properties">
- <implicitPropertyUsageProvider implementation="org.jetbrains.plugins.groovy.dgm.DGMImplicitPropertyUsageProvider"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.intellij">
- <navbar implementation="org.jetbrains.plugins.groovy.navbar.GrNavBarModelExtension" order="after defaultNavbar"/>
-
- <fileTypeDetector implementation="org.jetbrains.plugins.groovy.GroovyHashBangFileTypeDetector"/>
-
-
- <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod"
- implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrMethodDeclarationRangeHandler"/>
- <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition"
- implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrTypeDefinitionRangeHandler"/>
- <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer"
- implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrClassInitializerDeclarationRangeHandler"/>
-
-
- <psi.clsCustomNavigationPolicy implementation="org.jetbrains.plugins.groovy.codeInsight.GroovyClsCustomNavigationPolicy"/>
-
- <moduleBuilder builderClass="org.jetbrains.plugins.groovy.config.GroovyAwareModuleBuilder"/>
-
- <pom.declarationSearcher implementation="org.jetbrains.plugins.groovy.geb.GebContentDeclarationSearcher"/>
-
- <itemPresentationProvider forClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl"
- implementationClass="org.jetbrains.plugins.groovy.findUsages.GrFileItemPresentationProvider"/>
-
- <testFramework implementation="org.jetbrains.plugins.groovy.testIntegration.GroovyTestFramework" order="first"/>
- <testFramework implementation="org.jetbrains.plugins.groovy.spock.SpockTestFramework" order="first"/>
-
- <testCreator language="Groovy" implementationClass="com.intellij.testIntegration.JavaTestCreator"/>
- <testGenerator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.testIntegration.GroovyTestGenerator"/>
- <constructorBodyGenerator language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.GrConstructorBodyGenerator"/>
- <editorNotificationProvider implementation="org.jetbrains.plugins.groovy.config.ConfigureGroovyLibraryNotificationProvider"/>
- <refactoring.introduceParameterMethodUsagesProcessor
- implementation="org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor"/>
- <refactoring.changeSignatureUsageProcessor
- implementation="org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeSignatureUsageProcessor" id="groovyProcessor"
- order="before javaProcessor"/>
- <safeDelete.importSearcher implementation="org.jetbrains.plugins.groovy.refactoring.safeDelete.GroovyImportSearcher"/>
- <refactoring.safeDelete.JavaSafeDeleteDelegate implementationClass="org.jetbrains.plugins.groovy.refactoring.safeDelete.JavaSafeDeleteDelegateForGroovy" language="Groovy"/>
-
- <encapsulateFields.Helper language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.encapsulateFields.GroovyEncapsulateFieldHelper"/>
-
- <constantExpressionEvaluator language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator"/>
- <annotationSupport language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GroovyAnnotationSupport"/>
-
- <expressionConverter language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyExpressionConverter"/>
-
- <codeInsight.createFieldFromUsageHelper language="Groovy" implementationClass="org.jetbrains.plugins.groovy.annotator.intentions.GroovyCreateFieldFromUsageHelper"/>
-
- <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
- <fileTypeFactory implementation="org.jetbrains.plugins.groovy.GroovyFileTypeLoader"/>
- <fileTypeFactory implementation="org.jetbrains.plugins.groovy.dgm.DGMFileTypeFactory"/>
-
- <projectConfigurable instance="org.jetbrains.plugins.groovy.gant.GantConfigurable" id="reference.settingsdialog.project.gant"
- displayName="Gant"/>
-
- <library.presentationProvider implementation="org.jetbrains.plugins.groovy.config.GroovyLibraryPresentationProvider"/>
- <library.presentationProvider implementation="org.jetbrains.plugins.groovy.gpp.GppLibraryPresentationProvider" order="first"/>
- <library.presentationProvider implementation="org.jetbrains.plugins.groovy.gant.GantLibraryPresentationProvider" order="last"/>
-
- <projectService serviceInterface="org.jetbrains.plugins.groovy.gant.GantSettings"
- serviceImplementation="org.jetbrains.plugins.groovy.gant.GantSettings"/>
-
- <spellchecker.support language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.spellchecker.GroovySpellcheckingStrategy"/>
-
- <colorSettingsPage implementation="org.jetbrains.plugins.groovy.highlighter.GroovyColorsAndFontsPage"/>
- <framework.type implementation="org.jetbrains.plugins.groovy.config.GroovyFrameworkType"/>
- <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.PropertyRenameHandler"/>
- <renamePsiElementProcessor id="groovyFieldRenameProcessor"
- implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGrFieldProcessor"
- order="first"/>
- <renamePsiElementProcessor id="groovyPropertyRenameProcessor"
- implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGroovyPropertyProcessor"
- order="first"/>
- <renamePsiElementProcessor id="groovyLightElementRenamer"
- implementation="org.jetbrains.plugins.groovy.refactoring.rename.GrLightElementRenamer"
- order="first, after groovyPropertyRenameProcessor"/>
- <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedClassProcessor"
- order="first"/>
- <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedMethodProcessor"
- order="first"/>
- <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedFieldProcessor"
- order="first"/>
- <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGroovyScriptProcessor"/>
-
- <rename.inplace.resolveSnapshotProvider language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GroovyResolveSnapshotProvider"/>
-
- <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GrVariableInplaceRenameHandler"/>
- <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GrMethodInplaceRenameHandler"/>
-
- <nameSuggestionProvider implementation="org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionProvider"/>
-
- <statementUpDownMover implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyStatementMover"/>
-
- <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrVariableJoinLinesHandler"/>
- <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinBlockStatementHandler"/>
- <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinControlStatementHandler"/>
- <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinStatementsHandler"/>
-
- <applicationService serviceInterface="org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings"
- serviceImplementation="org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings"/>
- <applicationService serviceInterface="org.jetbrains.plugins.groovy.dsl.DslErrorReporter"
- serviceImplementation="org.jetbrains.plugins.groovy.dsl.DslErrorReporterImpl"/>
-
- <!-- Groovy language -->
- <syntaxHighlighter key="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovySyntaxHighlighter"/>
-
- <annotator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.annotator.GrAnnotatorImpl"/>
- <annotator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.dsl.GroovyDslAnnotator"/>
-
- <lang.psiStructureViewFactory language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.structure.GroovyStructureViewFactory"/>
- <lang.parserDefinition language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.parser.GroovyParserDefinition"/>
- <lang.commenter language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyCommenter"/>
- <lang.foldingBuilder language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.folding.GroovyFoldingBuilder"/>
- <lang.formatter language="Groovy" implementationClass="org.jetbrains.plugins.groovy.formatter.GroovyFormattingModelBuilder"/>
- <lang.whiteSpaceFormattingStrategy language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.formatter.GroovyWhiteSpaceFormattingStrategy"/>
- <postFormatProcessor implementation="org.jetbrains.plugins.groovy.formatter.GroovyBracePostFormatProcessor"/>
-
- <enterHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyEnterHandler"
- order="before EnterBetweenBracesHandler"/>
- <typedHandler implementation="org.jetbrains.plugins.groovy.editor.actions.GStringTypedActionHandler"/>
- <backspaceHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GStringBackspaceHandlerDelegate"/>
-
- <typedHandler implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyTypedHandler"/>
- <backspaceHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyBackspaceHandler"/>
-
- <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Generic"/>
- <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Expression"/>
- <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Statement"/>
- <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Declaration"/>
-
- <defaultLiveTemplatesProvider implementation="org.jetbrains.plugins.groovy.template.GroovyTemplatesProvider"/>
-
- <liveTemplateOptionalProcessor implementation="org.jetbrains.plugins.groovy.template.GroovyShortenFQNamesProcessor"/>
- <variableTypeCalculator implementation="org.jetbrains.plugins.groovy.template.GroovyVariableTypeCalculator"/>
-
- <gotoSymbolContributor implementation="org.jetbrains.plugins.groovy.gotoclass.GroovyGoToSymbolContributor"/>
- <lang.refactoringSupport language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringSupportProvider"/>
- <lang.surroundDescriptor language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.surroundWith.GroovySurroundDescriptor"/>
- <lang.findUsagesProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.findUsages.GroovyFindUsagesProvider"/>
- <importFilteringRule implementation="org.jetbrains.plugins.groovy.findUsages.GrImportFilteringRule"/>
-
- <readWriteAccessDetector implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReadWriteAccessDetector" order="before java"/>
- <findUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GroovyFieldFindUsagesHandlerFactory"/>
- <highlightUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GrHighlightHandlerFactory"/>
- <lang.braceMatcher language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyBraceMatcher"/>
- <lang.importOptimizer language="Groovy" implementationClass="org.jetbrains.plugins.groovy.editor.GroovyImportOptimizer"/>
- <lang.documentationProvider language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.documentation.GroovyDocumentationProvider"/>
- <lang.smartEnterProcessor language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.completion.smartEnter.GroovySmartEnterProcessor"/>
- <codeInsight.overrideMethod language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.overrideImplement.GroovyOverrideMethodsHandler"/>
- <codeInsight.implementMethod language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.overrideImplement.GroovyImplementMethodsHandler"/>
-
- <methodImplementor implementation="org.jetbrains.plugins.groovy.overrideImplement.GroovyMethodImplementor"/>
- <methodImplementor implementation="org.jetbrains.plugins.groovy.overrideImplement.TraitMethodImplementor"/>
- <codeInsight.parameterInfo language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyParameterInfoHandler"/>
- <codeInsight.parameterInfo language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyAnnotationAttributeInfoHandler"/>
- <codeInsight.parameterInfo language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyTypeParameterInfoHandler"/>
- <refactoring.inlineHandler language="Groovy" implementationClass="org.jetbrains.plugins.groovy.refactoring.inline.GroovyInlineHandler"/>
- <inlineActionHandler implementation="org.jetbrains.plugins.groovy.refactoring.inline.GroovyInlineLocalHandler"/>
-
- <refactoring.moveClassHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyClassHandler"/>
- <refactoring.moveClassToInnerHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.GroovyMoveClassToInnerHandler"/>
- <moveFileHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyFileHandler"/>
- <refactoring.moveMemberHandler language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyMemberHandler"/>
-
- <refactoring.helper implementation="org.jetbrains.plugins.groovy.refactoring.GroovyImportOptimizerRefactoringHelper"/>
- <codeInsight.lineMarkerProvider language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.codeInsight.GroovyLineMarkerProvider"/>
- <codeInsight.gotoSuper language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.codeInsight.navigation.actions.GroovyGotoSuperHandler"/>
- <lookup.charFilter implementation="org.jetbrains.plugins.groovy.lang.completion.GroovyReferenceCharFilter"/>
- <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyNoVariantsDelegator"
- id="groovyBasic2ClassName" order="first, after liveTemplates"/>
- <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor"
- id="groovyBasic" order="before javaClassName"/>
- <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.console.GroovyShellCompletionContributor"/>
-
- <completion.contributor language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovySmartCompletionContributor"/>
- <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GrMethodMergingContributor"
- id="grMethodMerger" order="before methodMerger"/>
-
- <completion.contributor language="Properties" implementationClass="org.jetbrains.plugins.groovy.dgm.DGMCompletionContributor"/>
-
- <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.UnfocusedNameIdentifier"
- id="groovyNameIdentifier"/>
- <completion.confidence language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionConfidence"
- id="groovyAdvanced" order="after groovyNameIdentifier"/>
- <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.UnfocusedComments"
- id="groovyComments"/>
- <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" id="groovyTrue"
- order="last"/>
- <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.geb.GebPageFieldNameCompletionContributor"/>
-
- <cantBeStatic implementation="org.jetbrains.plugins.groovy.codeInspection.declaration.GrCategoryMethodsCantBeStaticExtension" />
-
- <psi.referenceContributor language="Properties" implementation="org.jetbrains.plugins.groovy.dgm.DGMReferenceContributor"/>
-
- <psi.referenceContributor language="Groovy" implementation="org.jetbrains.plugins.groovy.lang.resolve.GroovyMethodArgumentReferenceContributor"/>
-
- <weigher key="completion" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrWithWeigher"
- id="groovyWithWeigher" order="after prefix"/>
- <weigher key="completion" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrKindWeigher"
- id="groovyKindWeigher" order="after groovyWithWeigher, before explicitProximity"/>
-
- <weigher key="proximity" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrReferenceListWeigher"
- id="groovyReferenceListWeigher" order="before openedInEditor"/>
-
- <debuggerClassFilterProvider implementation="org.jetbrains.plugins.groovy.debugger.filters.GroovyDebuggerClassFilterProvider"/>
-
- <useScopeEnlarger implementation="org.jetbrains.plugins.groovy.lang.psi.impl.search.GrPrivateFieldScopeEnlarger"/>
-
- <debuggerEditorTextProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.debugger.GroovyEditorTextProvider"/>
-
- <xdebugger.settings implementation="org.jetbrains.plugins.groovy.debugger.filters.GroovyDebuggerSettings"/>
- <langCodeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyLanguageCodeStyleSettingsProvider"/>
- <codeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettingsProvider"/>
-
- <typeHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.type.GroovyTypeHierarchyProvider"/>
- <callHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.call.GrCallHierarchyProvider"/>
-
- <lang.unwrapDescriptor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.unwrap.GroovyUnwrapDescriptor"/>
-
- <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral"
- implementationClass="org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator"/>
- <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel"
- implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.statements.arguments.GrArgumentLabelManipulator"/>
- <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringContent"
- implementationClass="org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator"/>
-
-
- <directClassInheritorsSearch implementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyDirectInheritorsSearcher"/>
-
- <pom.declarationSearcher implementation="org.jetbrains.plugins.groovy.spock.SpockPomDeclarationSearcher"/>
-
- <typeDeclarationProvider implementation="org.jetbrains.plugins.groovy.editor.GroovyTypeDeclarationProvider" order="first"/>
-
- <!--Run/debug-->
- <configurationType implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType"/>
- <configurationProducer implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationProducer"/>
-
- <quoteHandler fileType="Groovy" className="org.jetbrains.plugins.groovy.editor.GroovyQuoteHandler"/>
-
- <compileServer.plugin classpath="groovy-jps-plugin.jar"/>
-
- <indexPatternBuilder implementation="org.jetbrains.plugins.groovy.util.GroovyIndexPatternBuilder"/>
- <todoIndexer filetype="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyTodoIndexer"/>
-
- <basicWordSelectionFilter implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyWordSelectionFilter"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyLiteralSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyMembersWithDocSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyBlockStatementsSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeDefinitionBodySelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeCastSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyDocParamsSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyArgListSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyGStringSelectioner"
- order="before wordSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyParameterListSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyElseSelectioner"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyWordSelectionHandler"/>
- <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyStatementSelectioner"/>
-
-
- <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.AccessorMethodReferencesSearcher"/>
- <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.MethodLateBoundReferencesSearcher"/>
- <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyConstructorUsagesSearcher"/>
- <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReflectedMethodReferenceSearcher"/>
- <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GrLiteralMethodSearcher"/>
- <annotatedElementsSearch implementation="org.jetbrains.plugins.groovy.findUsages.AnnotatedMembersSearcher"/>
- <superMethodsSearch implementation="org.jetbrains.plugins.groovy.findUsages.GDKSuperMethodSearcher"/>
- <definitionsScopedSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyImplementationSearch"/>
-
- <targetElementEvaluator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyTargetElementEvaluator"/>
-
- <fileTemplateGroup implementation="org.jetbrains.plugins.groovy.actions.GroovyTemplatesFactory"/>
-
- <attachSourcesProvider implementation="org.jetbrains.plugins.groovy.ivy.IvyAttachSourceProvider"/>
-
- <projectConfigurable instance="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfigurable" id="Groovy compiler"
- displayName="Groovy Compiler" parentId="project.propCompiler"/>
-
- <vetoSPICondition implementation="org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider$GroovyExtensionVetoSPI"/>
-
- <stubElementTypeHolder class="org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes"/>
- <!--Stubs index-->
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFullClassNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFullScriptNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFieldNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrMethodNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnnotationMethodNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnnotatedMemberIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrScriptClassNameIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrDirectInheritorsIndex"/>
- <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnonymousClassIndex"/>
-
- <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.ConstructorReferencesSearcher"/>
- <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GrAliasedImportedElementSearcher"/>
- <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.AccessorReferencesSearcher"/>
- <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyTraitFieldSearcher"/>
-
- <antCustomCompiler implementation="org.jetbrains.plugins.groovy.ant.GroovyAntCustomCompilerProvider"/>
-
- <project.converterProvider implementation="org.jetbrains.plugins.groovy.config.GroovyModuleConverterProvider"/>
- <project.converterProvider implementation="org.jetbrains.plugins.groovy.config.GroovyRunConfigurationConverterProvider"/>
-
- <iconProvider implementation="org.jetbrains.plugins.groovy.GroovyIconProvider"/>
-
- <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory"
- serviceImplementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementFactoryImpl"/>
- <projectService serviceInterface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerWorkspaceConfiguration"
- serviceImplementation="org.jetbrains.plugins.groovy.compiler.GroovyCompilerWorkspaceConfiguration"/>
- <projectService serviceInterface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"
- serviceImplementation="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"/>
-
- <psi.referenceContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.providers.GroovyReferenceContributor"/>
-
- <resolveScopeProvider implementation="org.jetbrains.plugins.groovy.lang.resolve.GroovyResolveScopeProvider"/>
-
- <java.elementFinder implementation="org.jetbrains.plugins.groovy.lang.psi.impl.javaView.GroovyClassFinder"/>
- <java.elementFinder implementation="org.jetbrains.plugins.groovy.gant.GantClassFinder"/>
- <java.shortNamesCache implementation="org.jetbrains.plugins.groovy.lang.stubs.GroovyShortNamesCache"/>
-
- <projectService
- serviceImplementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager"/>
- <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyCodeStyleManager"
- serviceImplementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleManagerImpl"/>
- <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyCodeStyleSettingsFacade"
- serviceImplementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettingsFacadeImpl"/>
-
- <projectService
- serviceImplementation="org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider"/>
-
- <problemFileHighlightFilter implementation="org.jetbrains.plugins.groovy.GroovyProblemFileHighlightFilter"/>
-
- <renameInputValidator implementation="org.jetbrains.plugins.groovy.GroovyRenameInputValidator"/>
- <lang.namesValidator implementationClass="org.jetbrains.plugins.groovy.lang.GroovyNamesValidator" language="Groovy"/>
-
- <fileBasedIndex implementation="org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex"/>
-
- <patterns.patternClass className="org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns" alias="groovy"/>
-
- <stacktrace.fold substring="at org.codehaus.groovy."/>
- <stacktrace.fold substring="at groovy."/>
- <stacktrace.fold substring="at org.codehaus.groovy.runtime.DefaultGroovyMethods." negate="true"/>
- <stacktrace.fold substring="at org.codehaus.groovy.vmplugin.v5.PluginDefaultGroovyMethods." negate="true"/>
- <stacktrace.fold substring="at org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport." negate="true"/>
-
- <projectStructureDetector implementation="org.jetbrains.plugins.groovy.GroovySourceRootDetector" id="groovyDetector"/>
-
- <generation.topLevelFactory language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFactoryProvider"/>
-
- <postStartupActivity implementation="org.jetbrains.plugins.groovy.mvc.MvcProjectWithoutLibraryNotificator"/>
-
- <treeCopyHandler implementation="org.jetbrains.plugins.groovy.lang.GroovyChangeUtilSupport"/>
- <treeGenerator implementation="org.jetbrains.plugins.groovy.lang.psi.impl.source.impl.GroovyTreeGenerator" order="first"/>
-
- <copyPastePreProcessor implementation="org.jetbrains.plugins.groovy.editor.GroovyLiteralCopyPasteProcessor"/>
- <copyPastePostProcessor implementation="org.jetbrains.plugins.groovy.editor.GroovyReferenceCopyPasteProcessor"/>
-
- <localInspection shortName="GroovyUnusedDeclaration" displayName="Unused declaration"
- groupPath="Groovy"
- groupName="Declaration redundancy" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.GroovyUnusedDeclarationInspection" unfair="true"/>
-
- <localInspection language="Groovy" groupPath="Groovy" shortName="SecondUnsafeCall"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="second.unsafe.call" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.secondUnsafeCall.SecondUnsafeCallInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedAssignment"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="unused.assignment" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedIncOrDec"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="unused.inc.dec" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyVariableNotAssigned"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="unassigned.access" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.unassignedVariable.UnassignedVariableAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMissingReturnStatement"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="no.return.display.name" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="TypeCustomizer"
- displayName="Type customizer inspection"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- groupKey="other" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.resources.TypeCustomizerInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignabilityCheck" displayName="Incompatible type assignments"
- groupName="Assignment issues"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfAssignmentUsed" displayName="Result of assignment used"
- groupName="Assignment issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentCanBeOperatorAssignment"
- displayName="Assignment replaceable with operator assignment"
- groupName="Assignment issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentCanBeOperatorAssignmentInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentToForLoopParameter"
- displayName="Assignment to for-loop parameter"
- groupName="Assignment issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentToForLoopParameterInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentToMethodParameter"
- displayName="Assignment to method parameter"
- groupName="Assignment issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentToMethodParameterInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedAssignment" displayName="Nested assignment"
- groupName="Assignment issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyNestedAssignmentInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySillyAssignment" displayName="Silly assignment"
- groupName="Assignment issues" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovySillyAssignmentInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUncheckedAssignmentOfMemberOfRawType"
- displayName="Unchecked assignment from members of raw type"
- groupName="Assignment issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyUncheckedAssignmentOfMemberOfRawTypeInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyContinueOrBreakFromFinallyBlock"
- displayName="'continue' or 'break' inside 'finally' block"
- groupName="Error handling" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyContinueOrBreakFromFinallyBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrMethodMayBeStatic"
- displayName="Method may be static"
- groupName="Declaration" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStaticInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyReturnFromFinallyBlock"
- displayName="'return' inside 'finally' block" groupName="Error handling"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyReturnFromFinallyBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyThrowFromFinallyBlock"
- displayName="'throw' inside 'finally' block" groupName="Error handling"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyThrowFromFinallyBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyCatchBlock" displayName="Empty 'catch' block"
- groupName="Error handling" enabledByDefault="false"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyCatchBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyFinallyBlock" displayName="Empty 'finally' block"
- groupName="Error handling"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyFinallyBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyTryBlock" displayName="Empty 'try' block"
- groupName="Error handling" enabledByDefault="false"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyTryBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedCatchParameter" displayName="Unused catch parameter"
- groupName="Error handling"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyUnusedCatchParameterInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyBreak" displayName="Break statement" groupName="Control Flow"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyBreakInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyContinue" displayName="Continue statement"
- groupName="Control Flow" enabledByDefault="false"
- level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyContinueInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnreachableStatement" displayName="Unreachable Statement"
- groupName="Validity issues"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.validity.GroovyUnreachableStatementInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLoopStatementThatDoesntLoop"
- displayName="Loop statement that doesn't loop" groupName="Control Flow"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyLoopStatementThatDoesntLoopInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalWithIdenticalBranches"
- displayName="Conditional expression with identical branches"
- groupName="Control Flow" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalWithIdenticalBranchesInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalCanBeElvis"
- displayName="Conditional expression can be elvis" groupName="Control Flow"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalCanBeElvisInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalCanBeConditionalCall"
- displayName="Conditional expression can be conditional call"
- groupName="Control Flow" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalCanBeConditionalCallInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyIfStatementWithIdenticalBranches"
- displayName="If statement with identical branches"
- groupName="Control Flow" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyIfStatementWithIdenticalBranchesInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyIfStatementWithTooManyBranches"
- displayName="If statement with too many branches"
- groupName="Control Flow" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyIfStatementWithTooManyBranchesInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyFallthrough" displayName="Fallthrough in switch statement"
- groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyFallthroughInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnnecessaryContinue"
- displayName="Unnecessary 'continue' statement" groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryContinueInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnnecessaryReturn" displayName="Unnecessary 'return' statement"
- groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrFinalVariableAccess" displayName="Final variable access"
- groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.finalVar.GrFinalVariableAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySwitchStatementWithNoDefault"
- displayName="Switch statement with no default case"
- groupName="Control Flow" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovySwitchStatementWithNoDefaultInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyReturnFromClosureCanBeImplicit"
- displayName="'return' statement can be implicit"
- groupName="Control Flow" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyReturnFromClosureCanBeImplicitInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyTrivialConditional"
- displayName="Redundant conditional expression" groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantConditional"
- displayName="Constant conditional expression" groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConstantConditionalInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantIfStatement" displayName="Constant if statement"
- groupName="Control Flow"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConstantIfStatementInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyTrivialIf" displayName="Redundant 'if' statement"
- groupName="Control Flow" enabledByDefault="true"
- level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="JavaStylePropertiesInvocation"
- displayName="Java-style property access"
- groupName="Style" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.style.JavaStylePropertiesInvocationInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAccessToStaticFieldLockedOnInstance"
- displayName="Access to static field locked on instance data"
- groupName="Threading issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyAccessToStaticFieldLockedOnInstanceInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDoubleCheckedLocking" displayName="Double-checked locking"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyDoubleCheckedLockingInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnconditionalWait" displayName="Unconditional 'wait' call"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyUnconditionalWaitInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPublicFieldAccessedInSynchronizedContext"
- displayName="Non-private field accessed in synchronized context" groupName="Threading issues" enabledByDefault="false"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyPublicFieldAccessedInSynchronizedContextInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyBusyWait" displayName="Busy wait" groupName="Threading issues"
- enabledByDefault="false"
- level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyBusyWaitInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptySyncBlock" displayName="Empty 'synchronized' block"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyEmptySyncBlockInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnThis" displayName="Synchronization on 'this'"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnThisInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizedMethod" displayName="Synchronized method"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizedMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedSynchronizedStatement"
- displayName="Nested 'synchronized' statement"
- groupName="Threading issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyNestedSynchronizedStatementInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyThreadStopSuspendResume"
- displayName="Call to Thread.stop(), Thread.suspend(), or Thread.resume()"
- groupName="Threading issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyThreadStopSuspendResumeInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySystemRunFinalizersOnExit"
- displayName="Call to System.runFinalizersOnExit()"
- groupName="Threading issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySystemRunFinalizersOnExitInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNotifyWhileNotSynchronized"
- displayName="'notify()' or 'notifyAll()' while not synced"
- groupName="Threading issues" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyNotifyWhileNotSynchronizedInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWaitCallNotInLoop" displayName="'wait()' not in loop"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWaitCallNotInLoopInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWaitWhileNotSynchronized" displayName="'wait()' while not synced"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWaitWhileNotSynchronizedInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnNonFinalField"
- displayName="Synchronization on non-final field"
- groupName="Threading issues" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnNonFinalFieldInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnVariableInitializedWithLiteral"
- displayName="Synchronization on variable initialized with literal" groupName="Threading issues"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnVariableInitializedWithLiteralInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnsynchronizedMethodOverridesSynchronizedMethod"
- displayName="Unsynchronized method overrides synchronized method" groupName="Threading issues" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyUnsynchronizedMethodOverridesSynchronizedMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWhileLoopSpinsOnField" displayName="While loop spins on field"
- groupName="Threading issues"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWhileLoopSpinsOnFieldInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMethodParameterCount"
- displayName="Method with too many parameters" groupName="Method Metrics"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMethodParameterCountInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexMethod" displayName="Overly complex method"
- groupName="Method Metrics"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyComplexMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyLongMethod" displayName="Overly long method"
- groupName="Method Metrics" enabledByDefault="false"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyNestedMethod" displayName="Overly nested method"
- groupName="Method Metrics"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyNestedMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMethodWithMoreThanThreeNegations"
- displayName="Method with more than three negations"
- groupName="Method Metrics" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMethodWithMoreThanThreeNegationsInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMultipleReturnPointsPerMethod"
- displayName="Method with multiple return points"
- groupName="Method Metrics" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMultipleReturnPointsPerMethodInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedSwitch" displayName="Nested switch statement"
- groupName="Potentially confusing code constructs"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNestedSwitchInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditional" displayName="Conditional expression"
- groupName="Potentially confusing code constructs"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyConditionalInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrFieldAlreadyDefined"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="field.already.defined" groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrFieldAlreadyDefinedInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="ClashingGetters"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="clashing.getters" groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingGettersInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrPackage"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="gr.package" groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrPackageInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrDeprecatedAPIUsage"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="gr.deprecated.api.usage" groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrDeprecatedAPIUsageInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedConditional" displayName="Nested conditional expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNestedConditionalInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNegatedConditional" displayName="Negated conditional expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNegatedConditionalInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInArgumentCheck" displayName="Incompatible 'in' argument types"
- enabledByDefault="true" groupName="Probable bugs" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInArgumentCheckInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNegatedIf" displayName="Negated if condition expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNegatedIfInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfIncrementOrDecrementUsed"
- displayName="Result of increment or decrement used"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyResultOfIncrementOrDecrementUsedInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" enabledByDefault="true" level="WARNING"
- shortName="GrReassignedInClosureLocalVar"
- displayName="Local variable is reassigned in closure or anonymous class"
- groupName="Potentially confusing code constructs"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrReassignedInClosureLocalVarInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="UnnecessaryQualifiedReference"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="unnecessary.qualified.reference" groupName="Potentially confusing code constructs" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.UnnecessaryQualifiedReferenceInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyStatementBody" displayName="Statement with empty body"
- groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyEmptyStatementBodyInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPointlessBoolean"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="pointless.boolean.display.name" groupName="Potentially confusing code constructs" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyPointlessBooleanInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPointlessArithmetic"
- displayName="Pointless arithmetic expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyPointlessArithmeticInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDoubleNegation" displayName="Double negation"
- groupName="Potentially confusing code constructs"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyDoubleNegationInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexArithmeticExpression"
- displayName="Overly complex arithmetic expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOverlyComplexArithmeticExpressionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="ClashingTraitMethods"
- displayName="Clashing trait methods"
- groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingTraitMethodsInspection"/>
-
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexBooleanExpression"
- displayName="Overly complex boolean expression"
- groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOverlyComplexBooleanExpressionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOctalInteger" displayName="Octal integer"
- groupName="Potentially confusing code constructs"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOctalIntegerInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDuplicateSwitchBranch" displayName="Duplicate switch case"
- groupName="Validity issues"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.validity.GroovyDuplicateSwitchBranchInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNonShortCircuitBoolean" displayName="Non short-circuit boolean"
- groupName="Probable bugs"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyNonShortCircuitBooleanInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInfiniteLoopStatement" displayName="Infinite loop statement"
- groupName="Probable bugs"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInfiniteLoopStatementInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInfiniteRecursion" displayName="Infinite recursion"
- groupName="Probable bugs" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInfiniteRecursionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDivideByZero" displayName="Divide by zero"
- groupName="Probable bugs" enabledByDefault="true"
- level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyDivideByZeroInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfObjectAllocationIgnored"
- displayName="Result of object allocation ignored"
- groupName="Probable bugs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyResultOfObjectAllocationIgnoredInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAccessibility"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="access.to.inaccessible.element" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyAccessibilityInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstructorNamedArguments"
- displayName="Named arguments of constructor call" groupName="Probable bugs"
- enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyConstructorNamedArgumentsInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDocCheck" displayName="GroovyDoc issues"
- groupName="Probable bugs"
- enabledByDefault="true" level="ERROR"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyDocCheckInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyRangeTypeCheck"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="incorrect.range.argument" groupName="Probable bugs" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyRangeTypeCheckInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="NewInstanceOfSingleton"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="new.instance.of.singleton" groupName="Potentially confusing code constructs" enabledByDefault="true"
- level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.NewInstanceOfSingletonInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLabeledStatement"
- bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
- key="check.labeled.statement" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyLabeledStatementInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyClassNamingConvention" displayName="Class naming convention"
- groupName="Naming Conventions"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyClassNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInterfaceNamingConvention"
- displayName="Interface naming convention" groupName="Naming Conventions"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInterfaceNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAnnotationNamingConvention"
- displayName="Annotation naming convention" groupName="Naming Conventions"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyAnnotationNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEnumerationNamingConvention"
- displayName="Enumeration naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyEnumerationNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLocalVariableNamingConvention"
- displayName="Local variable naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyLocalVariableNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyStaticMethodNamingConvention"
- displayName="Static method naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyStaticMethodNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyStaticVariableNamingConvention"
- displayName="Static variable naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyStaticVariableNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInstanceMethodNamingConvention"
- displayName="Instance method naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInstanceMethodNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInstanceVariableNamingConvention"
- displayName="Instance variable naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInstanceVariableNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantNamingConvention"
- displayName="Constant naming convention" groupName="Naming Conventions"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyConstantNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyParameterNamingConvention"
- displayName="Method parameter naming convention"
- groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyParameterNamingConventionInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMapGetCanBeKeyedAccess"
- displayName="Call to Map.get can be keyed access"
- groupName="GPath inspections" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyMapGetCanBeKeyedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMapPutCanBeKeyedAccess"
- displayName="Call to Map.put can be keyed access"
- groupName="GPath inspections" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyMapPutCanBeKeyedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyListGetCanBeKeyedAccess"
- displayName="Call to List.get can be keyed access"
- groupName="GPath inspections" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyListGetCanBeKeyedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyListSetCanBeKeyedAccess"
- displayName="Call to List.set can be keyed access"
- groupName="GPath inspections" enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyListSetCanBeKeyedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUntypedAccess" displayName="Access to untyped expression"
- groupName="Probable bugs"
- enabledByDefault="false" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GrUnresolvedAccess" displayName="Access to unresolved expression"
- groupName="Probable bugs"
- enabledByDefault="true" level="WEAK WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection"/>
- <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySingletonAnnotation"
- displayName="Check '@Singleton' annotation conventions"
- groupName="Annotations verifying" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.annotator.inspections.GroovySingletonAnnotationInspection"/>
-
- <localInspection language="Groovy" groupPath="Groovy" shortName="DelegatesTo" displayName="@DelegatesTo inspection"
- groupName="Annotations verifying" enabledByDefault="true" level="WARNING"
- implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.DelegatesToInspection"/>
-
- <implicitUsageProvider implementation="org.jetbrains.plugins.groovy.gpp.GppImplicitUsageProvider"/>
- <implicitUsageProvider implementation="org.jetbrains.plugins.groovy.findUsages.GrImplicitUsageProvider"/>
-
- <!-- control flow -->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.DemorgansLawIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.SplitIfIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.InvertIfIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.GrRedundantElseIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.FlipIfIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.ReplaceTernaryWithIfElseIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.ReplaceIfWithTernaryIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.SimplifyTernaryOperatorIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.CreateParameterForFieldIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.MergeIfAndIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.ExpandBooleanIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.FlipConjunctionIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.FlipComparisonIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.NegateComparisonIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.MergeElseIfIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.SplitElseIfIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.control.flow</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.control.FlipConditionalIntention</className>
- </intentionAction>
-
- <!-- closures -->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.closures</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.closure.MakeClosureCallExplicitIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.closures</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.closure.MakeClosureCallImplicitIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.closures</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.closure.ForToEachIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.closures</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.closure.EachToForIntention</className>
- </intentionAction>
- <!--
- todo make this work
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.closures</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.closure.ConvertClosureArgToItIntention</className>
- </intentionAction>
- -->
-
-
- <!-- comments -->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.comments</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.comments.ChangeToCStyleCommentIntention</className>
- </intentionAction>
- <!--
- todo make this work
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.comments</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.comments.ChangeToEndOfLineCommentIntention</className>
- </intentionAction>
- -->
-
- <!-- conversions -->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertJavaStyleArrayIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToDecimalIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToHexIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToOctalIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToBinaryIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.IndexingMethodConversionIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.IndexedExpressionConversionIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertGStringToStringIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertMultilineStringToSingleLineIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertToRegexIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertToDollarSlashRegexIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.GrConvertStringToCharIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.RemoveUnnecessaryEscapeCharactersIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.GrBreakStringOnLineBreaksIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.GrSplitDeclarationIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.RemoveParenthesesFromMethodCallIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.RemoveUnnecessaryBracesInGStringIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertMapToClassIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertConcatenationToGstringIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.RenameFileWithClassIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.MoveClassToNewFileIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertMethodToClosureIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertStringToMultilineIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertClosureToMethodIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertSimpleGetterToPropertyIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.GrConvertTypeCastToSafeCastIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.conversions</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertJunitAssertionToAssertStatementIntention</className>
- </intentionAction>
-
- <!-- groovy style -->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.JavaStylePropertiesInvocationIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.RemoveUnnecessarySemicolonsIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.ImportStaticIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.ImportOnDemandIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.ConvertToGeeseBracesIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.RemoveRedundantClassPropertyIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.ConvertFromGeeseBracesIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.RemoveUnnecessaryReturnIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.AddReturnTypeFix</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.parameterToEntry.ConvertParameterToMapEntryIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.style</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.style.ReplaceAbstractClassInstanceByMapIntention</className>
- </intentionAction>
-
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy</categoryKey>
- <className>org.jetbrains.plugins.groovy.grape.GrabDependencies</className>
- </intentionAction>
-
- <!--declaration-->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrCreateSubclassAction</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrCreateFieldForParameterIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrSetStrongTypeIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberPublicIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberProtectedIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberPrivateIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrIntroduceLocalVariableIntention</className>
- </intentionAction>
-
- <!--other-->
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.other</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.other.GrCreateMissingSwitchBranchesIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.other</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.other.GrAliasImportIntention</className>
- </intentionAction>
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.other</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.other.GrCopyStringConcatenationContentIntention</className>
- </intentionAction>
-
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.other</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.other.GrSortMapKeysIntention</className>
- </intentionAction>
-
- <intentionAction>
- <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
- <categoryKey>intention.category.groovy.declaration</categoryKey>
- <className>org.jetbrains.plugins.groovy.intentions.declaration.GrRemoveExplicitTypeDeclarationIntention</className>
- </intentionAction>
-
- <projectService
- serviceImplementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"/>
-
- <projectService serviceInterface="org.jetbrains.plugins.groovy.griffon.GriffonProjectViewState"
- serviceImplementation="org.jetbrains.plugins.groovy.griffon.GriffonProjectViewState"/>
-
- <java.programPatcher implementation="org.jetbrains.plugins.groovy.debugger.GroovyHotSwapper"/>
- <psi.referenceContributor implementation="org.jetbrains.plugins.groovy.gpp.GppReferenceContributor"/>
-
- <library.presentationProvider implementation="org.jetbrains.plugins.groovy.griffon.GriffonLibraryPresentationProvider"/>
- <moduleBuilder builderClass="org.jetbrains.plugins.groovy.griffon.GriffonModuleBuilder" id="griffonModuleBuilder"/>
- <projectStructureDetector implementation="org.jetbrains.plugins.groovy.griffon.GriffonProjectStructureDetector" order="before groovyDetector"/>
- <programRunner implementation="org.jetbrains.plugins.groovy.griffon.GriffonDebuggerRunner"/>
- <configurationType implementation="org.jetbrains.plugins.groovy.griffon.GriffonRunConfigurationType"/>
- <toolWindow id="Griffon View" anchor="left" secondary="false" icon="JetgroovyIcons.Griffon.GriffonToolWindow"
- factoryClass="org.jetbrains.plugins.groovy.griffon.GriffonToolWindowFactory"
- conditionClass="org.jetbrains.plugins.groovy.griffon.GriffonToolWindowFactory"/>
-
- <roots.watchedRootsProvider implementation="org.jetbrains.plugins.groovy.mvc.MvcWatchedRootProvider"/>
- <projectService serviceInterface="org.jetbrains.plugins.groovy.mvc.MvcConsole"
- serviceImplementation="org.jetbrains.plugins.groovy.mvc.MvcConsole"/>
- <selectInTarget implementation="org.jetbrains.plugins.groovy.mvc.projectView.MvcProjectViewSelectInTarget"/>
- <applicationService serviceImplementation="org.jetbrains.plugins.groovy.mvc.MvcRunTargetHistoryService"
- serviceInterface="org.jetbrains.plugins.groovy.mvc.MvcRunTargetHistoryService"/>
- <applicationService serviceInterface="org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactory"
- serviceImplementation="org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactoryImpl"/>
-
- <debugger.positionManagerFactory id="groovyPositionManager"
- implementation="org.jetbrains.plugins.groovy.debugger.GroovyPositionManagerFactory"/>
- <debugger.positionManagerFactory order="after groovyPositionManager"
- implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
- <debugger.nodeRenderer implementation="org.jetbrains.plugins.groovy.debugger.GroovyRefRenderer"/>
- <codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
- <codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
- <lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
- <refactoring.pullUpHelperFactory language="Groovy"
- implementationClass="org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHelperFactory"/>
- <classTypePointerFactory implementation="org.jetbrains.plugins.groovy.lang.psi.impl.smartPointers.GrClassReferenceTypePointerFactory"/>
- <hierarchy.referenceProcessor implementation="org.jetbrains.plugins.groovy.hierarchy.call.GrCallReferenceProcessor"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.intellij.debugger">
- <codeFragmentFactory implementation="org.jetbrains.plugins.groovy.debugger.GroovyCodeFragmentFactory"/>
- </extensions>
-
- <extensions defaultExtensionNs="ByteCodeViewer">
- <classSearcher implementation="org.jetbrains.plugins.groovy.byteCodeViewer.GroovyScriptClassSearcher"/>
- </extensions>
-
- <actions>
- <action id="Groovy.Shell.Execute" class="com.intellij.openapi.actionSystem.EmptyAction" text="Execute Groovy Code"
- description="Execute Groovy code in console">
- <keyboard-shortcut first-keystroke="control ENTER" keymap="$default"/>
- </action>
-
- <action id="Groovy.NewClass" class="org.jetbrains.plugins.groovy.actions.NewGroovyClassAction"
- text="Groovy Class" description="Create new Groovy class">
- <add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewGroup1"/>
- </action>
- <action id="Groovy.NewScript" class="org.jetbrains.plugins.groovy.actions.NewScriptAction"
- text="Groovy Script" description="Create new Groovy script">
- <add-to-group group-id="NewGroup" anchor="last"/>
- </action>
-
- <action id="Gant.NewScript" class="org.jetbrains.plugins.groovy.gant.NewGantScriptAction"
- text="Gant Script" description="Create new Gant script">
- <add-to-group group-id="NewGroup" anchor="last"/>
- </action>
-
- <group id="Groovy.Dynamic.Toolbar">
- <action id="Groovy.Dynamic.Remove" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.RemoveDynamicAction"
- icon="AllIcons.General.Remove" text="Remove" description="Remove dynamic element"/>
- <separator/>
- <action id="Groovy.Dynamic.ExpandAll" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ExpandAllAction"
- icon="AllIcons.Actions.Expandall" text="Expand all" description="Collapse all"/>
- <action id="Groovy.Dynamic.CollapseAll" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.CollapseAllAction"
- icon="AllIcons.Actions.Collapseall" text="Collapse all" description="Collapse all"/>
- </group>
-
-
- <action id="ConvertGroovyToJava"
- class="org.jetbrains.plugins.groovy.actions.ConvertToJavaAction"
- text="Convert to Java"
- description="Convert Groovy files to Java">
- <add-to-group group-id="RefactoringMenu"/>
- </action>
-
- <group id="Internal.Groovy" text="Groovy" popup="true" internal="true">
- <action id="GetPsiTypeAction" class="org.jetbrains.plugins.groovy.actions.GrGetPsiTypeAction"
- text="get PsiType" description=""
- internal="true"/>
-
- <action id="DumpGroovyControlFlowAction"
- class="org.jetbrains.plugins.groovy.actions.DumpGroovyControlFlowAction"
- text="dump groovy control flow"
- description="" internal="true"/>
- <action id="DumpGroovyStubsAction"
- class="org.jetbrains.plugins.groovy.actions.DumpGroovyStubsAction"
- text="dump groovy stubs"
- description="" internal="true"/>
- <add-to-group group-id="Internal"/>
- </group>
-
- <action id="ExcludeFromStubGeneration"
- class="org.jetbrains.plugins.groovy.compiler.ExcludeFromStubGenerationAction"
- text="Exclude from stub generation" description="Don't generate Java stubs for this Groovy file on compilation">
- <add-to-group group-id="EditorTabPopupMenu" anchor="after" relative-to-action="RenameJavaFileToGroovyFileAction"/>
- </action>
-
-
- <group id="GroovyGenerateGroup1">
- <action id="org.jetbrains.plugins.groovy.actions.generate.constructors.GroovyGenerateConstructorAction"
- class="org.jetbrains.plugins.groovy.actions.generate.constructors.GroovyGenerateConstructorAction"
- text="Constructor" description="Generates constructor"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterAction"
- class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterAction"
- text="Getter" description="Generates getter"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateSetterAction"
- class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateSetterAction"
- text="Setter" description="Generates setter"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterSetterAction"
- class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterSetterAction"
- text="Getter and Setter" description="Generates getter"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.equals.GroovyGenerateEqualsAction"
- class="org.jetbrains.plugins.groovy.actions.generate.equals.GroovyGenerateEqualsAction"
- text="equals() and hashCode()" description="Action generates equals and hashCode now"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGenerateMethodMissingAction"
- class="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGenerateMethodMissingAction"
- text="methodMissing()" description="Action generates propertyMissing()"/>
- <action id="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGeneratePropertyMissingAction"
- class="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGeneratePropertyMissingAction"
- text="propertyMissing()" description="Action generates propertyMissing()"/>
-
- <add-to-group group-id="GenerateGroup" anchor="after" relative-to-action="JavaGenerateGroup1"/>
- </group>
-
- <action id="Groovy.Doc.Generating"
- class="org.jetbrains.plugins.groovy.doc.actions.GenerateGroovyDocAction"
- text="Generate GroovyDoc..." description="Generating Groovy Documentation"
- icon="JetgroovyIcons.Groovy.GroovyDoc">
- <add-to-group group-id="ToolsMenu" anchor="last"/>
- </action>
- <action id="Groovy.Shell"
- class="org.jetbrains.plugins.groovy.console.GroovyShellAction"
- text="Groovy Shell..." description="Launch Groovy Shell"
- icon="JetgroovyIcons.Groovy.Groovy_16x16">
- <add-to-group group-id="ToolsMenu" anchor="last"/>
- </action>
-
- <action id="Groovy.Console"
- class="org.jetbrains.plugins.groovy.console.GroovyConsoleAction"
- text="Groovy Console..." description="Launch Groovy Console"
- icon="JetgroovyIcons.Groovy.Groovy_16x16">
- <add-to-group group-id="ToolsMenu" anchor="last"/>
- </action>
-
- <group id="Mvc.Actions" popup="true" class="org.jetbrains.plugins.groovy.mvc.MvcActionGroup">
- <action id="Mvc.Upgrade"
- class="org.jetbrains.plugins.groovy.mvc.MvcUpgradeAction"
- text="Change SDK version" description="Change Grails/Griffon SDK version">
- </action>
-
- <action id="Griffon.UpdateDependencies" class="org.jetbrains.plugins.groovy.griffon.UpdateGriffonSettingsAction"
- text="Synchronize Griffon settings"
- description="Refresh IntelliJ IDEA project structure so that it matches Griffon build settings">
- </action>
-
- <action id="Mvc.RunTarget" class="org.jetbrains.plugins.groovy.mvc.MvcRunTarget"
- text="Run Target" description="Run arbitrary Grails/Griffon target">
- <keyboard-shortcut keymap="$default" first-keystroke="ctrl alt G"/>
- </action>
- <add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="AddFrameworkSupport"/>
- <add-to-group group-id="NavbarPopupMenu" anchor="after" relative-to-action="AddFrameworkSupport"/>
- <add-to-group group-id="ToolsMenu" anchor="last"/>
- </group>
-
- </actions>
-
- <application-components>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.gant.GantLoader</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.mvc.MvcPathMacros</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.dsl.DslActivationStatus</implementation-class>
- </component>
- </application-components>
-
- <project-components>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportsPassFactory</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.annotator.GrKeywordAndDeclarationHighlightFactory</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.annotator.GrReferenceHighlighterFactory</implementation-class>
- </component>
- <component>
- <interface-class>org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManager</interface-class>
- <implementation-class>org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManagerImpl</implementation-class>
- </component>
- <component>
- <implementation-class>org.jetbrains.plugins.groovy.mvc.MvcModuleStructureSynchronizer</implementation-class>
- </component>
- </project-components>
-
-
-</idea-plugin>
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index 53e72c43b68d..a0e51171f9d0 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -96,7 +96,6 @@ import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
@@ -331,7 +330,7 @@ public class GroovyAnnotator extends GroovyElementVisitor {
LOG.assertTrue(nameElement != null);
myHolder.createInfoAnnotation(nameElement, null).setTextAttributes(DefaultHighlighter.MAP_KEY);
}
- else if (GrReferenceResolveUtil.isClassReference(referenceExpression)) {
+ else if (ResolveUtil.isClassReference(referenceExpression)) {
PsiElement nameElement = referenceExpression.getReferenceNameElement();
LOG.assertTrue(nameElement != null);
myHolder.createInfoAnnotation(nameElement, null).setTextAttributes(DefaultHighlighter.KEYWORD);
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/intentions/QuickfixUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/intentions/QuickfixUtil.java
index 988080352933..6d32b15779b8 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/intentions/QuickfixUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/annotator/intentions/QuickfixUtil.java
@@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyNamesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -49,7 +49,7 @@ public class QuickfixUtil {
return PsiUtil.getContextClass(refExpr);
}
- PsiType type = GrReferenceResolveUtil.getQualifierType(refExpr);
+ PsiType type = PsiImplUtil.getQualifierType(refExpr);
if (type == null && compileStatic) {
return GroovyPsiManager.getInstance(refExpr.getProject()).findClassWithCache(CommonClassNames.JAVA_LANG_OBJECT, refExpr.getResolveScope());
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInsight/GroovyClsCustomNavigationPolicy.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInsight/GroovyClsCustomNavigationPolicy.java
index 71378824a577..6505e6e66044 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInsight/GroovyClsCustomNavigationPolicy.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInsight/GroovyClsCustomNavigationPolicy.java
@@ -31,11 +31,17 @@ public class GroovyClsCustomNavigationPolicy extends ClsCustomNavigationPolicyEx
@Override
@Nullable
public PsiElement getNavigationElement(@NotNull ClsMethodImpl clsMethod) {
+ if (isGroovyLanguage(clsMethod)) return null;
+
PsiMethod source = clsMethod.getSourceMirrorMethod();
- if (source instanceof LightElement && source.getLanguage() == GroovyLanguage.INSTANCE) {
+ if (source instanceof LightElement) {
return source.getNavigationElement();
}
return null;
}
+
+ private static boolean isGroovyLanguage(ClsMethodImpl method) {
+ return method.getContainingFile().getNavigationElement().getLanguage() == GroovyLanguage.INSTANCE;
+ }
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovySuppressableInspectionTool.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovySuppressableInspectionTool.java
index 184476b33a7a..b348c9cabefd 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovySuppressableInspectionTool.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/GroovySuppressableInspectionTool.java
@@ -44,14 +44,7 @@ import java.util.regex.Matcher;
/**
* @author peter
*/
-public abstract class GroovySuppressableInspectionTool extends LocalInspectionTool implements BatchSuppressableTool {
- @NotNull
- @Override
- public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
- return getSuppressActions(getShortName());
-
- }
-
+public abstract class GroovySuppressableInspectionTool extends LocalInspectionTool {
public static SuppressQuickFix[] getSuppressActions(String name) {
final HighlightDisplayKey displayKey = HighlightDisplayKey.find(name);
return new SuppressQuickFix[] {
@@ -61,11 +54,6 @@ public abstract class GroovySuppressableInspectionTool extends LocalInspectionTo
};
}
- @Override
- public boolean isSuppressedFor(@NotNull final PsiElement element) {
- return isElementToolSuppressedIn(element, getID());
- }
-
public static boolean isElementToolSuppressedIn(final PsiElement place, final String toolId) {
return getElementToolSuppressedIn(place, toolId) != null;
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrMethodCallInfo.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrMethodCallInfo.java
index 721a6eb38a25..70a42a1092c6 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrMethodCallInfo.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GrMethodCallInfo.java
@@ -23,7 +23,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
/**
@@ -48,7 +48,7 @@ public class GrMethodCallInfo extends CallInfoBase<GrMethodCall> implements Call
@Override
public PsiType getQualifierInstanceType() {
GrExpression invoked = getCall().getInvokedExpression();
- return invoked instanceof GrReferenceExpression ? GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)invoked) : null;
+ return invoked instanceof GrReferenceExpression ? PsiImplUtil.getQualifierType((GrReferenceExpression)invoked) : null;
}
@NotNull
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOverlyComplexArithmeticExpressionInspectionBase.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOverlyComplexArithmeticExpressionInspectionBase.java
index 816f348d96e7..3d09c275ee3f 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOverlyComplexArithmeticExpressionInspectionBase.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOverlyComplexArithmeticExpressionInspectionBase.java
@@ -30,6 +30,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryE
import java.util.HashSet;
import java.util.Set;
+import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
+
public class GroovyOverlyComplexArithmeticExpressionInspectionBase extends BaseInspection {
private static final int TERM_LIMIT = 3;
/**
@@ -193,7 +195,7 @@ public class GroovyOverlyComplexArithmeticExpressionInspectionBase extends BaseI
if (type == null) {
return false;
}
- return "java.lang.String".equals(type.getCanonicalText());
+ return type.equalsToText(JAVA_LANG_STRING);
}
}
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessChecker.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessChecker.java
index 9a615db0f7d8..2978b652f544 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessChecker.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessChecker.java
@@ -65,9 +65,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -146,7 +146,7 @@ public class GrUnresolvedAccessChecker {
if (refElement.getParent() instanceof GrNewExpression) {
- boolean inStaticContext = GrReferenceResolveUtil.isInStaticContext(refElement);
+ boolean inStaticContext = GrStaticChecker.isInStaticContext(refElement);
if (!inStaticContext && GrUnresolvedAccessInspection.isSuppressed(refElement)) return null;
@@ -193,7 +193,7 @@ public class GrUnresolvedAccessChecker {
PsiElement refNameElement = ref.getReferenceNameElement();
if (refNameElement == null) return null;
- boolean inStaticContext = PsiUtil.isCompileStatic(ref) || GrReferenceResolveUtil.isPropertyAccessInStaticMethod(ref);
+ boolean inStaticContext = PsiUtil.isCompileStatic(ref) || GrStaticChecker.isPropertyAccessInStaticMethod(ref);
GroovyResolveResult resolveResult = getBestResolveResult(ref);
if (resolveResult.getElement() != null) {
@@ -207,7 +207,7 @@ public class GrUnresolvedAccessChecker {
return null;
}
- if (ResolveUtil.isKeyOfMap(ref) || GrReferenceResolveUtil.isClassReference(ref)) {
+ if (ResolveUtil.isKeyOfMap(ref) || ResolveUtil.isClassReference(ref)) {
return null;
}
@@ -245,7 +245,7 @@ public class GrUnresolvedAccessChecker {
}
private static boolean areMissingMethodsDeclared(GrReferenceExpression ref) {
- PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(ref);
+ PsiType qualifierType = PsiImplUtil.getQualifierType(ref);
if (!(qualifierType instanceof PsiClassType)) return false;
PsiClass resolved = ((PsiClassType)qualifierType).resolve();
@@ -325,7 +325,7 @@ public class GrUnresolvedAccessChecker {
}
private static boolean checkGroovyObjectMethodsByQualifier(GrReferenceExpression ref, PsiMethod patternMethod) {
- PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(ref);
+ PsiType qualifierType = PsiImplUtil.getQualifierType(ref);
if (!(qualifierType instanceof PsiClassType)) return false;
PsiClass resolved = ((PsiClassType)qualifierType).resolve();
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java
index ef33bef8640f..873345c3eced 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/gpp/GppReferenceContributor.java
@@ -40,7 +40,7 @@ import java.util.List;
public class GppReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(GrArgumentLabel.class), new PsiReferenceProvider() {
@NotNull
@Override
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
index 0cde75af230b..dce723b5f3bc 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
@@ -46,10 +46,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
-import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
-import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
-import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.*;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
@@ -76,6 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
@@ -988,4 +986,38 @@ public class PsiImplUtil {
}
return expr == null;
}
+
+ @Nullable
+ public static PsiType getQualifierType(@NotNull GrReferenceExpression ref) {
+ final GrExpression rtQualifier = getRuntimeQualifier(ref);
+ if (rtQualifier != null) {
+ return rtQualifier.getType();
+ }
+
+ PsiClass containingClass = null;
+ final GrMember member = PsiTreeUtil.getParentOfType(ref, GrMember.class);
+ if (member == null) {
+ final PsiFile file = ref.getContainingFile();
+ if (file instanceof GroovyFileBase && ((GroovyFileBase)file).isScript()) {
+ containingClass = ((GroovyFileBase)file).getScriptClass();
+ }
+ else {
+ return null;
+ }
+ }
+ else if (member instanceof GrMethod) {
+ if (!member.hasModifierProperty(PsiModifier.STATIC)) {
+ containingClass = member.getContainingClass();
+ }
+ }
+
+ if (containingClass != null) {
+ final PsiClassType categoryType = GdkMethodUtil.getCategoryType(containingClass);
+ if (categoryType != null) {
+ return categoryType;
+ }
+ return JavaPsiFacade.getElementFactory(ref.getProject()).createType(containingClass);
+ }
+ return null;
+ }
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
index 40589065654d..4b8a032a5602 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java
@@ -46,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
@@ -59,10 +58,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.*;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer;
-import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
-import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.*;
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.*;
@@ -159,15 +155,15 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
IElementType nameType = nameElement.getNode().getElementType();
if (nameType == GroovyTokenTypes.kTHIS) {
- ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
- if (GrReferenceResolveUtil.resolveThisExpression(this, results)) {
- return results.toArray(new GroovyResolveResult[results.size()]);
+ GroovyResolveResult[] results = GrThisReferenceResolver.resolveThisExpression(this);
+ if (results != null) {
+ return results;
}
}
else if (nameType == GroovyTokenTypes.kSUPER) {
- ArrayList<GroovyResolveResult> results = new ArrayList<GroovyResolveResult>();
- if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) {
- return results.toArray(new GroovyResolveResult[results.size()]);
+ GroovyResolveResult[] results = GrSuperReferenceResolver.resolveSuperExpression(this);
+ if (results != null) {
+ return results;
}
}
@@ -178,8 +174,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
GroovyResolveResult[] classCandidates = null;
+ GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this);
+
ResolverProcessor processor = new PropertyResolverProcessor(name, this);
- GrReferenceResolveUtil.resolveImpl(processor, this);
+ resolveRunner.resolveImpl(processor);
final GroovyResolveResult[] fieldCandidates = processor.getCandidates();
if (hasAt()) {
@@ -191,7 +189,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (canBeClassOrPackage && findClassOrPackageAtFirst()) {
ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
- GrReferenceResolveUtil.resolveImpl(classProcessor, this);
+ resolveRunner.resolveImpl(classProcessor);
classCandidates = classProcessor.getCandidates();
if (classCandidates.length > 0 && containsPackage(classCandidates)) return classCandidates;
}
@@ -215,9 +213,8 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
for (String accessorName : accessorNames) {
AccessorResolverProcessor accessorResolver =
- new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, GrReferenceResolveUtil.getQualifierType(this),
- getTypeArguments());
- GrReferenceResolveUtil.resolveImpl(accessorResolver, this);
+ new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, PsiImplUtil.getQualifierType(this), getTypeArguments());
+ resolveRunner.resolveImpl(accessorResolver);
final GroovyResolveResult[] candidates = accessorResolver.getCandidates();
//can be only one correct candidate or some incorrect
@@ -237,9 +234,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (classCandidates == null && canBeClassOrPackage ) {
ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
- GrReferenceResolveUtil.resolveImpl(classProcessor, this);
+ resolveRunner.resolveImpl(classProcessor);
classCandidates = classProcessor.getCandidates();
}
+
if (classCandidates != null && classCandidates.length > 0) return classCandidates;
if (!accessorResults.isEmpty()) return new GroovyResolveResult[]{accessorResults.get(0)};
return GroovyResolveResult.EMPTY_ARRAY;
@@ -258,23 +256,14 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
private void processMethods(@NotNull MethodResolverProcessor methodResolver) {
- GrReferenceResolveUtil.resolveImpl(methodResolver, this);
+ new GrReferenceResolveRunner(this).resolveImpl(methodResolver);
if (methodResolver.hasApplicableCandidates()) {
return;
}
// Search in ClosureMissingMethodContributor
if (!isQualified() && getContext() instanceof GrMethodCall) {
- for (PsiElement e = this.getContext(); e != null; e = e.getContext()) {
- if (e instanceof GrClosableBlock) {
- ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, e);
- for (ClosureMissingMethodContributor contributor : ClosureMissingMethodContributor.EP_NAME.getExtensions()) {
- if (!contributor.processMembers((GrClosableBlock)e, methodResolver, this, state)) {
- return;
- }
- }
- }
- }
+ ClosureMissingMethodContributor.processMethodsFromClosures(this, methodResolver);
}
}
@@ -287,8 +276,10 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
final String name = getReferenceName();
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
+ GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this);
+
PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this);
- GrReferenceResolveUtil.resolveImpl(propertyResolver, this);
+ resolveRunner.resolveImpl(propertyResolver);
final GroovyResolveResult[] propertyCandidates = propertyResolver.getCandidates();
if (!allVariants) { //search for local variables
@@ -345,8 +336,8 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
//search for getters
for (String getterName : GroovyPropertyUtils.suggestGettersName(name)) {
AccessorResolverProcessor getterResolver =
- new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, GrReferenceResolveUtil.getQualifierType(this), getTypeArguments());
- GrReferenceResolveUtil.resolveImpl(getterResolver, this);
+ new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, PsiImplUtil.getQualifierType(this), getTypeArguments());
+ resolveRunner.resolveImpl(getterResolver);
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
if (!allVariants && candidates.length == 1) {
return candidates;
@@ -424,7 +415,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
argTypes[i] = TypeConversionUtil.erasure(argTypes[i]);
}
}
- PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(this);
+ PsiType qualifierType = PsiImplUtil.getQualifierType(this);
return new MethodResolverProcessor(name, this, false, qualifierType, argTypes, getTypeArguments(), allVariants, byShape);
}
@@ -610,7 +601,19 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return factory.createType((PsiClass)resolved);
}
}
- if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this)) {
+ else if (PsiUtil.isSuperReference(this)) {
+ PsiClass contextClass = PsiUtil.getContextClass(this);
+ if (GrTraitUtil.isTrait(contextClass)) {
+ PsiClassType[] extendsTypes = contextClass.getExtendsListTypes();
+ PsiClassType[] implementsTypes = contextClass.getImplementsListTypes();
+
+ PsiClassType[] superTypes = ArrayUtil.mergeArrays(implementsTypes, extendsTypes, PsiClassType.ARRAY_FACTORY);
+
+ return PsiIntersectionType.createIntersection(ArrayUtil.reverseArray(superTypes));
+ }
+ return factory.createType((PsiClass)resolved);
+ }
+ if (getParent() instanceof GrReferenceExpression) {
return factory.createType((PsiClass)resolved);
}
else {
@@ -637,7 +640,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (containingClass != null &&
CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()) &&
"getClass".equals(method.getName())) {
- return TypesUtil.createJavaLangClassType(GrReferenceResolveUtil.getQualifierType(this), getProject(), getResolveScope());
+ return TypesUtil.createJavaLangClassType(PsiImplUtil.getQualifierType(this), getProject(), getResolveScope());
}
return PsiUtil.getSmartReturnType(method);
@@ -701,7 +704,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Nullable
private static PsiType getTypeFromClassRef(@NotNull GrReferenceExpressionImpl ref) {
if ("class".equals(ref.getReferenceName())) {
- return TypesUtil.createJavaLangClassType(GrReferenceResolveUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope());
+ return TypesUtil.createJavaLangClassType(PsiImplUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope());
}
return null;
}
@@ -710,7 +713,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Override
@Nullable
public PsiType fun(GrReferenceExpressionImpl refExpr) {
- if (GrReferenceResolveUtil.isClassReference(refExpr)) {
+ if (ResolveUtil.isClassReference(refExpr)) {
GrExpression qualifier = refExpr.getQualifier();
LOG.assertTrue(qualifier != null);
return TypesUtil.createJavaLangClassType(qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
@@ -783,7 +786,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
if (incompleteCode) {
ResolverProcessor processor = CompletionProcessor.createRefSameNameProcessor(this, name);
- GrReferenceResolveUtil.resolveImpl(processor, this);
+ new GrReferenceResolveRunner(this).resolveImpl(processor);
GroovyResolveResult[] propertyCandidates = processor.getCandidates();
if (propertyCandidates.length > 0 && !PsiUtil.isSingleBindingVariant(propertyCandidates)) return propertyCandidates;
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java
new file mode 100644
index 000000000000..13159892a3ee
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveRunner.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GrTraitType;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
+import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
+import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
+import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
+
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * @author Medvedev Max
+ */
+public class GrReferenceResolveRunner {
+
+ private final GrReferenceExpression place;
+ private ResolverProcessor processor;
+
+ public GrReferenceResolveRunner(@NotNull GrReferenceExpression _place) {
+ place = _place;
+ }
+
+ public boolean resolveImpl(@NotNull ResolverProcessor _processor) {
+ processor = _processor;
+ try {
+ boolean result = doResolve();
+ ProgressManager.checkCanceled();
+ return result;
+ }
+ finally {
+ processor = null;
+ }
+ }
+
+ private boolean doResolve() {
+ GrExpression qualifier = place.getQualifier();
+ if (qualifier == null) {
+ if (!ResolveUtil.treeWalkUp(place, processor, true)) return false;
+ if (!processor.hasCandidates()) {
+ GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(place);
+ if (runtimeQualifier != null) {
+ if (!processQualifier(runtimeQualifier)) return false;
+ }
+ }
+ }
+ else {
+ if (place.getDotTokenType() == GroovyTokenTypes.mSPREAD_DOT) {
+ final PsiType qtype = qualifier.getType();
+ final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qtype, place);
+ if (componentType != null) {
+ final ResolveState state = ResolveState.initial()
+ .put(ClassHint.RESOLVE_CONTEXT, qualifier)
+ .put(SpreadState.SPREAD_STATE, SpreadState.create(qtype, null));
+ if (!processQualifierType(componentType, state)) return false;
+ }
+ }
+ else {
+ if (ResolveUtil.isClassReference(place)) return true;
+ if (!processQualifier(qualifier)) return false;
+ if (!processJavaLangClass(qualifier)) return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean processJavaLangClass(@NotNull GrExpression qualifier) {
+ if (!(qualifier instanceof GrReferenceExpression)) return true;
+
+ //optimization: only 'class' or 'this' in static context can be an alias of java.lang.Class
+ if (!("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) ||
+ PsiUtil.isThisReference(qualifier))) {
+ return true;
+ }
+
+ PsiType type = qualifier.getType();
+ if (!(type instanceof PsiClassType)) return true;
+
+ final PsiClass psiClass = ((PsiClassType)type).resolve();
+ if (psiClass == null || !CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) return true;
+
+ final PsiType[] params = ((PsiClassType)type).getParameters();
+ if (params.length != 1) return true;
+
+ if (!processQualifierType(params[0], ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier))) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean processQualifier(@NotNull GrExpression qualifier) {
+ PsiType qualifierType = qualifier.getType();
+ ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier);
+ if (qualifierType == null || qualifierType == PsiType.VOID) {
+ if (qualifier instanceof GrReferenceExpression) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved != null && !resolved.processDeclarations(processor, state, null, place)) return false;
+ if (!(resolved instanceof PsiPackage)) {
+ PsiType objectQualifier = TypesUtil.getJavaLangObject(place);
+ if (!processQualifierType(objectQualifier, state)) return false;
+ }
+ }
+ }
+ else if (qualifierType instanceof PsiIntersectionType) {
+ for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
+ if (!processQualifierType(conjunct, state)) return false;
+ }
+ }
+ else {
+ if (!processQualifierType(qualifierType, state)) return false;
+ if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
+ PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
+ if (resolved instanceof PsiClass) {
+ if (!processJavaLangClass(qualifierType, state)) return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean processJavaLangClass(@NotNull PsiType qualifierType,
+ @NotNull ResolveState state) {
+ //omitted .class
+ PsiClass javaLangClass = PsiUtil.getJavaLangClass(place, place.getResolveScope());
+ if (javaLangClass == null) return true;
+
+ PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
+ PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
+ if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
+ if (typeParameters.length == 1) {
+ substitutor = substitutor.put(typeParameters[0], qualifierType);
+ state = state.put(PsiSubstitutor.KEY, substitutor);
+ }
+ if (!javaLangClass.processDeclarations(processor, state, null, place)) return false;
+
+ PsiType javaLangClassType = JavaPsiFacade.getElementFactory(place.getProject()).createType(javaLangClass, substitutor);
+
+ if (!ResolveUtil.processNonCodeMembers(javaLangClassType, processor, place, state)) return false;
+
+ return true;
+ }
+
+ private boolean processQualifierType(@NotNull PsiType originalQualifierType,
+ @NotNull ResolveState state) {
+ PsiType qualifierType = originalQualifierType instanceof PsiDisjunctionType
+ ? ((PsiDisjunctionType)originalQualifierType).getLeastUpperBound()
+ : originalQualifierType;
+
+ if (qualifierType instanceof PsiIntersectionType) {
+ for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
+ if (!processQualifierType(conjunct, state)) return false;
+ }
+ return true;
+ }
+
+ if (qualifierType instanceof GrTraitType) {
+ if (!processTraitType((GrTraitType)qualifierType, state)) {
+ return false;
+ }
+ return true;
+ }
+
+ if (qualifierType instanceof PsiClassType) {
+ PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType)qualifierType).resolveGenerics();
+ PsiClass qualifierClass = qualifierResult.getElement();
+ if (qualifierClass != null) {
+ if (!qualifierClass.processDeclarations(processor, state.put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, place)) {
+ return false;
+ }
+ }
+ }
+ else if (qualifierType instanceof PsiArrayType) {
+ final GroovyPsiManager gmanager = GroovyPsiManager.getInstance(place.getProject());
+ final GrTypeDefinition arrayClass = gmanager.getArrayClass(((PsiArrayType)qualifierType).getComponentType());
+ if (arrayClass != null && !arrayClass.processDeclarations(processor, state, null, place)) return false;
+ }
+
+ if (!(place.getParent() instanceof GrMethodCall) && InheritanceUtil.isInheritor(qualifierType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
+ final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qualifierType, place);
+ if (componentType != null) {
+ final SpreadState spreadState = state.get(SpreadState.SPREAD_STATE);
+ processQualifierType(componentType, state.put(SpreadState.SPREAD_STATE, SpreadState.create(qualifierType, spreadState)));
+ }
+ }
+
+ if (!ResolveUtil.processCategoryMembers(place, processor, state)) return false;
+ if (!ResolveUtil.processNonCodeMembers(qualifierType, processor, place, state)) return false;
+ return true;
+ }
+
+ private boolean processTraitType(@NotNull GrTraitType traitType, @NotNull ResolveState state) {
+ GrTypeDefinition mockDefinition = traitType.getMockTypeDefinition();
+ if (mockDefinition != null) {
+ if (!mockDefinition.processDeclarations(processor, state, null, place)) {
+ return false;
+ }
+ }
+ else {
+ PsiClassType exprType = traitType.getExprType();
+
+ if (!processQualifierType(exprType, state)) return false;
+
+ List<PsiClassType> traitTypes = traitType.getTraitTypes();
+ for (ListIterator<PsiClassType> iterator = traitTypes.listIterator(); iterator.hasPrevious(); ) {
+ PsiClassType type = iterator.previous();
+ if (!processQualifierType(type, state)) return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java
deleted file mode 100644
index 4779fb12f25f..000000000000
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceResolveUtil.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
-
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.psi.*;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
-import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
-import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GrTraitType;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
-import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
-import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
-import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
-
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * @author Medvedev Max
- */
-public class GrReferenceResolveUtil {
-
- private GrReferenceResolveUtil() {
- }
-
- static boolean resolveImpl(@NotNull ResolverProcessor processor,
- @NotNull GrReferenceExpression place) {
- boolean b = doResolve(processor, place);
- ProgressManager.checkCanceled();
- return b;
- }
-
- private static boolean doResolve(ResolverProcessor processor, GrReferenceExpression place) {
- GrExpression qualifier = place.getQualifier();
- if (qualifier == null) {
- if (!ResolveUtil.treeWalkUp(place, processor, true)) return false;
- if (!processor.hasCandidates()) {
- GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(place);
- if (runtimeQualifier != null) {
- if (!processQualifier(processor, runtimeQualifier, place)) return false;
- }
- }
- }
- else {
- if (place.getDotTokenType() == GroovyTokenTypes.mSPREAD_DOT) {
- final PsiType qtype = qualifier.getType();
- final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qtype, place);
- if (componentType != null) {
- final ResolveState state = ResolveState.initial()
- .put(ClassHint.RESOLVE_CONTEXT, qualifier)
- .put(SpreadState.SPREAD_STATE, SpreadState.create(qtype, null));
- if (!processQualifierType(processor, componentType, state, place)) return false;
- }
- }
- else {
- if (isClassReference(place)) return true;
- if (!processQualifier(processor, qualifier, place)) return false;
- }
-
- if (qualifier instanceof GrReferenceExpression &&
- ("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier))) {
- if (!processIfJavaLangClass(processor, qualifier.getType(), qualifier, place)) return false;
- }
- }
- return true;
- }
-
- private static boolean processIfJavaLangClass(@NotNull ResolverProcessor processor,
- @Nullable PsiType type,
- @NotNull GroovyPsiElement resolveContext,
- @NotNull GrReferenceExpression place) {
- if (!(type instanceof PsiClassType)) return true;
-
- final PsiClass psiClass = ((PsiClassType)type).resolve();
- if (psiClass == null || !CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) return true;
-
- final PsiType[] params = ((PsiClassType)type).getParameters();
- if (params.length != 1) return true;
-
- if (!processQualifierType(processor, params[0], ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, resolveContext), place)) {
- return false;
- }
- return true;
- }
-
- public static boolean processQualifier(@NotNull PsiScopeProcessor processor,
- @NotNull GrExpression qualifier,
- @NotNull GrReferenceExpression place) {
- PsiType qualifierType = qualifier.getType();
- ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, qualifier);
- if (qualifierType == null || qualifierType == PsiType.VOID) {
- if (qualifier instanceof GrReferenceExpression) {
- PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
- if (resolved != null && !resolved.processDeclarations(processor, state, null, place)) return false;
- if (!(resolved instanceof PsiPackage)) {
- PsiType objectQualifier = TypesUtil.getJavaLangObject(place);
- if (!processQualifierType(processor, objectQualifier, state, place)) return false;
- }
- }
- }
- else if (qualifierType instanceof PsiIntersectionType) {
- for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
- if (!processQualifierType(processor, conjunct, state, place)) return false;
- }
- }
- else {
- if (!processQualifierType(processor, qualifierType, state, place)) return false;
- if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) {
- PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
- if (resolved instanceof PsiClass) {
- if (!processJavaLangClass(qualifierType, processor, state, place)) return false;
- }
- }
- }
- return true;
- }
-
- private static boolean processJavaLangClass(@NotNull PsiType qualifierType,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- //omitted .class
- PsiClass javaLangClass = PsiUtil.getJavaLangClass(place, place.getResolveScope());
- if (javaLangClass == null) return true;
-
- PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
- PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
- if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
- if (typeParameters.length == 1) {
- substitutor = substitutor.put(typeParameters[0], qualifierType);
- state = state.put(PsiSubstitutor.KEY, substitutor);
- }
- if (!javaLangClass.processDeclarations(processor, state, null, place)) return false;
-
- PsiType javaLangClassType = JavaPsiFacade.getElementFactory(place.getProject()).createType(javaLangClass, substitutor);
-
- if (!ResolveUtil.processNonCodeMembers(javaLangClassType, processor, place, state)) return false;
-
- return true;
- }
-
- private static boolean processQualifierType(@NotNull PsiScopeProcessor processor,
- @NotNull PsiType originalQualifierType,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- PsiType qualifierType = originalQualifierType instanceof PsiDisjunctionType
- ? ((PsiDisjunctionType)originalQualifierType).getLeastUpperBound()
- : originalQualifierType;
-
- if (qualifierType instanceof PsiIntersectionType) {
- for (PsiType conjunct : ((PsiIntersectionType)qualifierType).getConjuncts()) {
- if (!processQualifierType(processor, conjunct, state, place)) return false;
- }
- return true;
- }
-
- if (qualifierType instanceof GrTraitType) {
- if (!processTraitType((GrTraitType)qualifierType, processor, state, place)) {
- return false;
- }
- return true;
- }
-
- if (qualifierType instanceof PsiClassType) {
- PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType)qualifierType).resolveGenerics();
- PsiClass qualifierClass = qualifierResult.getElement();
- if (qualifierClass != null) {
- if (!qualifierClass.processDeclarations(processor, state.put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, place)) {
- return false;
- }
- }
- }
- else if (qualifierType instanceof PsiArrayType) {
- final GroovyPsiManager gmanager = GroovyPsiManager.getInstance(place.getProject());
- final GrTypeDefinition arrayClass = gmanager.getArrayClass(((PsiArrayType)qualifierType).getComponentType());
- if (arrayClass != null && !arrayClass.processDeclarations(processor, state, null, place)) return false;
- }
-
- if (!(place.getParent() instanceof GrMethodCall) && InheritanceUtil.isInheritor(qualifierType, CommonClassNames.JAVA_UTIL_COLLECTION)) {
- final PsiType componentType = ClosureParameterEnhancer.findTypeForIteration(qualifierType, place);
- if (componentType != null) {
- final SpreadState spreadState = state.get(SpreadState.SPREAD_STATE);
- processQualifierType(processor, componentType, state.put(SpreadState.SPREAD_STATE, SpreadState.create(qualifierType, spreadState)), place);
- }
- }
-
- if (!ResolveUtil.processCategoryMembers(place, processor, state)) return false;
- if (!ResolveUtil.processNonCodeMembers(qualifierType, processor, place, state)) return false;
- return true;
- }
-
- private static boolean processTraitType(@NotNull GrTraitType traitType,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull GrReferenceExpression place) {
- GrTypeDefinition mockDefinition = traitType.getMockTypeDefinition();
- if (mockDefinition != null) {
- if (!mockDefinition.processDeclarations(processor, state, null, place)) {
- return false;
- }
- }
- else {
- PsiClassType exprType = traitType.getExprType();
-
- if (!processQualifierType(processor, exprType, state, place)) return false;
-
- List<PsiClassType> traitTypes = traitType.getTraitTypes();
- for (ListIterator<PsiClassType> iterator = traitTypes.listIterator(); iterator.hasPrevious(); ) {
- PsiClassType type = iterator.previous();
- if (!processQualifierType(processor, type, state, place)) return false;
- }
- }
-
- return true;
- }
-
- @Nullable
- public static PsiType getQualifierType(@NotNull GrReferenceExpression ref) {
- final GrExpression rtQualifier = PsiImplUtil.getRuntimeQualifier(ref);
- if (rtQualifier != null) {
- return rtQualifier.getType();
- }
-
- PsiClass containingClass = null;
- final GrMember member = PsiTreeUtil.getParentOfType(ref, GrMember.class);
- if (member == null) {
- final PsiFile file = ref.getContainingFile();
- if (file instanceof GroovyFileBase && ((GroovyFileBase)file).isScript()) {
- containingClass = ((GroovyFileBase)file).getScriptClass();
- }
- else {
- return null;
- }
- }
- else if (member instanceof GrMethod) {
- if (!member.hasModifierProperty(PsiModifier.STATIC)) {
- containingClass = member.getContainingClass();
- }
- }
-
- if (containingClass != null) {
- final PsiClassType categoryType = GdkMethodUtil.getCategoryType(containingClass);
- if (categoryType != null) {
- return categoryType;
- }
- return JavaPsiFacade.getElementFactory(ref.getProject()).createType(containingClass);
- }
- return null;
- }
-
- public static boolean resolveThisExpression(@NotNull GrReferenceExpression ref,
- @NotNull List<GroovyResolveResult> results) {
- GrExpression qualifier = ref.getQualifier();
-
- if (qualifier == null) {
- final PsiElement parent = ref.getParent();
- if (parent instanceof GrConstructorInvocation) {
- GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
- ContainerUtil.addAll(results, res);
- return true;
- }
-
- PsiClass aClass = PsiUtil.getContextClass(ref);
- if (aClass == null) return false;
-
- results.add(new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true));
- return true;
- }
- else {
- if (!(qualifier instanceof GrReferenceExpression)) return false;
-
- GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
- PsiElement resolved = result.getElement();
- if (!(resolved instanceof PsiClass)) return false;
- if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
-
- results.add(result);
- return true;
- }
- }
-
- public static boolean resolveSuperExpression(@NotNull GrReferenceExpression ref,
- @NotNull List<GroovyResolveResult> results) {
- GrExpression qualifier = ref.getQualifier();
-
- PsiClass aClass;
- if (qualifier == null) {
- final PsiElement parent = ref.getParent();
- if (parent instanceof GrConstructorInvocation) {
- GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false);
- ContainerUtil.addAll(results, res);
- return true;
- }
-
- aClass = PsiUtil.getContextClass(ref);
- if (aClass == null) return false;
- }
- else {
- if (!(qualifier instanceof GrReferenceExpression)) return false;
-
- GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
- PsiElement resolved = result.getElement();
- if (!(resolved instanceof PsiClass)) return false;
- aClass = (PsiClass)resolved;
-
- GrTypeDefinition scopeClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true);
- if (GrTraitUtil.isTrait(aClass) && scopeClass != null && PsiUtil.scopeClassImplementsTrait(aClass, ref)) {
- PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(aClass, scopeClass, PsiSubstitutor.EMPTY);
- results.add(new GroovyResolveResultImpl(aClass, null, null, superClassSubstitutor, true, true));
- return true;
- }
-
- if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false;
-
- }
- PsiClass superClass = aClass.getSuperClass();
- if (superClass == null) return true; //no super class, but the reference is definitely super-reference
-
- PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
- results.add(new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true));
- return true;
- }
-
- public static boolean isClassReference(@NotNull GrReferenceExpression ref) {
- GrExpression qualifier = ref.getQualifier();
- return "class".equals(ref.getReferenceName()) &&
- qualifier instanceof GrReferenceExpression &&
- ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass &&
- !PsiUtil.isThisReference(qualifier);
- }
-
- public static boolean isPropertyAccessInStaticMethod(@NotNull GrReferenceExpression referenceExpression) {
- return isInStaticContext(referenceExpression) &&
- !(referenceExpression.getParent() instanceof GrMethodCall) &&
- referenceExpression.getQualifier() == null;
- }
-
- public static boolean isInStaticContext(@NotNull PsiElement place) {
- GrMember context = PsiTreeUtil.getParentOfType(place, GrMember.class, true, GrClosableBlock.class);
- return (context instanceof GrMethod || context instanceof GrClassInitializer) && context.hasModifierProperty(PsiModifier.STATIC);
- }
-}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java
new file mode 100644
index 000000000000..0b45314b34a0
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceResolver.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * Created by Max Medvedev on 15/06/14
+ */
+public class GrSuperReferenceResolver {
+ @Nullable("null if ref is not 'super' reference")
+ public static GroovyResolveResult[] resolveSuperExpression(@NotNull GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+
+ if (qualifier == null) {
+ final PsiElement parent = ref.getParent();
+ if (parent instanceof GrConstructorInvocation) {
+ return ((GrConstructorInvocation)parent).multiResolve(false);
+ }
+ PsiClass aClass = PsiUtil.getContextClass(ref);
+ if (aClass != null) {
+ return getSuperClass(aClass);
+ }
+ }
+ else if (qualifier instanceof GrReferenceExpression) {
+ GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
+ PsiElement resolved = result.getElement();
+ if (resolved instanceof PsiClass) {
+ PsiClass superClass = (PsiClass)resolved;
+
+ GrTypeDefinition scopeClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true);
+ if (scopeClass != null && GrTraitUtil.isTrait(superClass) && scopeClass.isInheritor(superClass, false)) {
+ PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, scopeClass, PsiSubstitutor.EMPTY);
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)};
+ }
+
+ if (PsiUtil.hasEnclosingInstanceInScope(superClass, ref, false)) {
+ return getSuperClass(superClass);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @NotNull
+ private static GroovyResolveResult[] getSuperClass(@NotNull PsiClass aClass) {
+ PsiClass superClass = aClass.getSuperClass();
+ if (superClass != null) {
+ PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)};
+ }
+ else {
+ return GroovyResolveResult.EMPTY_ARRAY; //no super class, but the reference is definitely super-reference
+ }
+ }
+}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java
new file mode 100644
index 000000000000..c891459ae7de
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceResolver.java
@@ -0,0 +1,45 @@
+package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiSubstitutor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+
+/**
+ * Created by Max Medvedev on 15/06/14
+ */
+public class GrThisReferenceResolver {
+ @Nullable("null if ref is not actually 'this' reference")
+ public static GroovyResolveResult[] resolveThisExpression(@NotNull GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+
+ if (qualifier == null) {
+ final PsiElement parent = ref.getParent();
+ if (parent instanceof GrConstructorInvocation) {
+ return ((GrConstructorInvocation)parent).multiResolve(false);
+ }
+ else {
+ PsiClass aClass = PsiUtil.getContextClass(ref);
+ if (aClass != null) {
+ return new GroovyResolveResultImpl[]{new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true)};
+ }
+ }
+ }
+ else if (qualifier instanceof GrReferenceExpression) {
+ GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve();
+ PsiElement resolved = result.getElement();
+ if (resolved instanceof PsiClass && PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) {
+ return new GroovyResolveResult[]{result};
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
index b9f2fcc07ea4..b48fabeb69d8 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java
@@ -42,6 +42,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.Map;
import java.util.Set;
+import static com.intellij.psi.CommonClassNames.*;
+
/**
* @author peter
*/
@@ -50,24 +52,24 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
private static final Set<String> iterations = new HashSet<String>();
static {
- simpleTypes.put("times", "java.lang.Integer");
- simpleTypes.put("upto", "java.lang.Integer");
- simpleTypes.put("downto", "java.lang.Integer");
- simpleTypes.put("step", "java.lang.Integer");
+ simpleTypes.put("times", JAVA_LANG_INTEGER);
+ simpleTypes.put("upto", JAVA_LANG_INTEGER);
+ simpleTypes.put("downto", JAVA_LANG_INTEGER);
+ simpleTypes.put("step", JAVA_LANG_INTEGER);
simpleTypes.put("withObjectOutputStream", "java.io.ObjectOutputStream");//todo
simpleTypes.put("withObjectInputStream", "java.io.ObjectInputStream");
simpleTypes.put("withOutputStream", "java.io.OutputStream");
simpleTypes.put("withInputStream", "java.io.InputStream");
simpleTypes.put("withDataOutputStream", "java.io.DataOutputStream");
simpleTypes.put("withDataInputStream", "java.io.DataInputStream");
- simpleTypes.put("eachLine", "java.lang.String");
- simpleTypes.put("eachFile", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("eachDir", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("eachFileRecurse", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("traverse", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("eachDirRecurse", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("eachFileMatch", CommonClassNames.JAVA_IO_FILE);
- simpleTypes.put("eachDirMatch", CommonClassNames.JAVA_IO_FILE);
+ simpleTypes.put("eachLine", JAVA_LANG_STRING);
+ simpleTypes.put("eachFile", JAVA_IO_FILE);
+ simpleTypes.put("eachDir", JAVA_IO_FILE);
+ simpleTypes.put("eachFileRecurse", JAVA_IO_FILE);
+ simpleTypes.put("traverse", JAVA_IO_FILE);
+ simpleTypes.put("eachDirRecurse", JAVA_IO_FILE);
+ simpleTypes.put("eachFileMatch", JAVA_IO_FILE);
+ simpleTypes.put("eachDirMatch", JAVA_IO_FILE);
simpleTypes.put("withReader", "java.io.Reader");
simpleTypes.put("withWriter", "java.io.Writer");
simpleTypes.put("withWriterAppend", "java.io.Writer");
@@ -78,7 +80,7 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
simpleTypes.put("filterLine", "String");
simpleTypes.put("accept", "java.net.Socket");
simpleTypes.put("dropWhile", "java.lang.Character");
- simpleTypes.put("eachMatch", "java.lang.String");
+ simpleTypes.put("eachMatch", JAVA_LANG_STRING);
simpleTypes.put("replaceAll", "java.util.regex.Matcher");
simpleTypes.put("replaceFirst", "java.util.regex.Matcher");
simpleTypes.put("splitEachLine", "java.util.List<java.lang.String>");
@@ -158,11 +160,11 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
if (params.length == 1) {
return findTypeForIteration(qualifier, closure);
}
- if (params.length == 2 && InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
+ if (params.length == 2 && InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) {
if (index == 0) {
- return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true);
+ return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true);
}
- return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true);
+ return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 1, true);
}
}
else if (GdkMethodUtil.isWithName(methodName) && params.length == 1) {
@@ -174,36 +176,36 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
if (index == 0) {
return res;
}
- return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_INTEGER, closure);
+ return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, closure);
}
- if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
+ if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) {
if (params.length == 2) {
if (index == 0) {
return getEntryForMap(type, closure.getProject(), closure.getResolveScope());
}
- return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_INTEGER, closure);
+ return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, closure);
}
if (params.length == 3) {
if (index == 0) {
- return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true);
+ return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true);
}
if (index == 1) {
- return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 1, true);
+ return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 1, true);
}
- return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_INTEGER, closure);
+ return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, closure);
}
}
}
else if (GdkMethodUtil.INJECT.equals(methodName) && params.length == 2) {
if (index == 0) {
- return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, closure);
+ return TypesUtil.createTypeByFQClassName(JAVA_LANG_OBJECT, closure);
}
PsiType res = findTypeForIteration(qualifier, closure);
if (res != null) {
return res;
}
- if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
+ if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) {
return getEntryForMap(type, closure.getProject(), closure.getResolveScope());
}
}
@@ -211,13 +213,13 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
final PsiType itemType = findTypeForIteration(qualifier, closure);
if (itemType != null) {
return JavaPsiFacade.getElementFactory(closure.getProject()).createTypeFromText(
- CommonClassNames.JAVA_UTIL_ARRAY_LIST + "<" + itemType.getCanonicalText() + ">", closure);
+ JAVA_UTIL_ARRAY_LIST + "<" + itemType.getCanonicalText() + ">", closure);
}
- return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_UTIL_ARRAY_LIST, closure);
+ return TypesUtil.createTypeByFQClassName(JAVA_UTIL_ARRAY_LIST, closure);
}
else if (GdkMethodUtil.WITH_DEFAULT.equals(methodName)) {
- if (params.length == 1 && InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
- return PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_MAP, 0, true);
+ if (params.length == 1 && InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) {
+ return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true);
}
}
else if (GdkMethodUtil.SORT.equals(methodName)) {
@@ -254,18 +256,18 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
@Nullable
private static PsiType getEntryForMap(@Nullable PsiType map, @NotNull final Project project, @NotNull final GlobalSearchScope scope) {
- PsiType key = PsiUtil.substituteTypeParameter(map, CommonClassNames.JAVA_UTIL_MAP, 0, true);
- PsiType value = PsiUtil.substituteTypeParameter(map, CommonClassNames.JAVA_UTIL_MAP, 1, true);
+ PsiType key = PsiUtil.substituteTypeParameter(map, JAVA_UTIL_MAP, 0, true);
+ PsiType value = PsiUtil.substituteTypeParameter(map, JAVA_UTIL_MAP, 1, true);
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- final PsiClass entryClass = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_UTIL_MAP_ENTRY, scope);
+ final PsiClass entryClass = JavaPsiFacade.getInstance(project).findClass(JAVA_UTIL_MAP_ENTRY, scope);
if (entryClass == null) {
if (key != null && key != PsiType.NULL && value != null && value != PsiType.NULL) {
- final String text = String.format("%s<%s,%s>", CommonClassNames.JAVA_UTIL_MAP_ENTRY, key.getCanonicalText(), value.getCanonicalText());
+ final String text = String.format("%s<%s,%s>", JAVA_UTIL_MAP_ENTRY, key.getCanonicalText(), value.getCanonicalText());
return factory.createTypeFromText(text, null);
}
else {
- return factory.createTypeByFQClassName(CommonClassNames.JAVA_UTIL_MAP_ENTRY, scope);
+ return factory.createTypeByFQClassName(JAVA_UTIL_MAP_ENTRY, scope);
}
}
else {
@@ -310,11 +312,11 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
return extracted;
}
- if (TypesUtil.isClassType(type, CommonClassNames.JAVA_LANG_STRING) || TypesUtil.isClassType(type, CommonClassNames.JAVA_IO_FILE)) {
+ if (TypesUtil.isClassType(type, JAVA_LANG_STRING) || TypesUtil.isClassType(type, JAVA_IO_FILE)) {
return PsiType.getJavaLangString(manager, resolveScope);
}
- if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
+ if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) {
return getEntryForMap(type, manager.getProject(), resolveScope);
}
return type;
@@ -332,7 +334,7 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer {
final PsiType returnType = org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.getSmartReturnType((PsiMethod)element);
final PsiType iteratorType = candidate.getSubstitutor().substitute(returnType);
- return PsiUtil.substituteTypeParameter(iteratorType, CommonClassNames.JAVA_UTIL_ITERATOR, 0, false);
+ return PsiUtil.substituteTypeParameter(iteratorType, JAVA_UTIL_ITERATOR, 0, false);
}
@Nullable
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
index 0a9a622d4d10..a24d855919f1 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
@@ -51,7 +51,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
@@ -432,7 +431,7 @@ public class GdkMethodUtil {
}
}
else {
- PsiType qtype = GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)qualifier);
+ PsiType qtype = PsiImplUtil.getQualifierType((GrReferenceExpression)qualifier);
if (qtype instanceof PsiClassType && ((PsiClassType)qtype).resolve() != null) {
return Pair.create((PsiClassType)qtype, (GrReferenceExpression)qualifier);
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/StaticChecker.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStaticChecker.java
index 74d3cb396bcc..c9d17cb3afb3 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/StaticChecker.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/GrStaticChecker.java
@@ -26,6 +26,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
@@ -34,7 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe
/**
* @author Max Medvedev
*/
-public class StaticChecker {
+public class GrStaticChecker {
public static boolean isStaticsOK(@NotNull PsiModifierListOwner member,
@NotNull PsiElement place,
@Nullable PsiElement resolveContext,
@@ -114,7 +115,7 @@ public class StaticChecker {
}
else if (PsiUtil.isThisOrSuperRef(qualifier)) {
//static members may be invoked from this.<...>
- final boolean isInStatic = isInStaticContext((GrReferenceExpression)qualifier);
+ final boolean isInStatic = isInStaticContext(qualifier);
if (PsiUtil.isThisReference(qualifier) && isInStatic) {
return checkJavaLangClassMember(place, containingClass, member) || member.hasModifierProperty(PsiModifier.STATIC);
}
@@ -187,37 +188,49 @@ public class StaticChecker {
return null;
}
- public static boolean isInStaticContext(GrQualifiedReference refExpression) {
+ public static boolean isInStaticContext(@NotNull PsiElement place) {
PsiClass targetClass = null;
- if (PsiUtil.isThisReference(refExpression) && refExpression.getQualifier() != null) {
- targetClass = (PsiClass)((GrReferenceExpression)refExpression.getQualifier()).resolve();
+ if (place instanceof GrReferenceExpression) {
+ PsiElement qualifier = ((GrQualifiedReference)place).getQualifier();
+ if (PsiUtil.isThisReference(place) && qualifier instanceof GrQualifiedReference) {
+ targetClass = (PsiClass)((GrQualifiedReference)qualifier).resolve();
+ }
}
- return isInStaticContext(refExpression, targetClass);
+ return isInStaticContext(place, targetClass);
}
- public static boolean isInStaticContext(GrQualifiedReference refExpression, @Nullable PsiClass targetClass) {
- PsiElement qualifier = refExpression.getQualifier();
- if (qualifier != null && !PsiUtil.isThisOrSuperRef(refExpression)) {
- if (PsiUtil.isInstanceThisRef(qualifier) || PsiUtil.isSuperReference(qualifier)) {
- return false;
- }
- else if (PsiUtil.isThisReference(qualifier)) { //instance 'this' already is processed. So it static 'this'
- return true;
+ public static boolean isInStaticContext(@NotNull PsiElement place, @Nullable PsiClass targetClass) {
+ if (place instanceof GrReferenceExpression) {
+ GrQualifiedReference reference = (GrQualifiedReference)place;
+ PsiElement qualifier = reference.getQualifier();
+ if (qualifier != null && !PsiUtil.isThisOrSuperRef(reference)) {
+ if (PsiUtil.isInstanceThisRef(qualifier) || PsiUtil.isSuperReference(qualifier)) {
+ return false;
+ }
+ else if (PsiUtil.isThisReference(qualifier)) { //instance 'this' already is processed. So it static 'this'
+ return true;
+ }
+ return qualifier instanceof GrQualifiedReference && ((GrQualifiedReference)qualifier).resolve() instanceof PsiClass;
}
- return qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass;
- }
-
- if (PsiUtil.isSuperReference(refExpression)) return false;
- //this reference should be checked as all other refs
+ if (PsiUtil.isSuperReference(reference)) return false;
+ //this reference should be checked as all other refs
+ }
- PsiElement run = refExpression;
+ PsiElement run = place;
while (run != null && run != targetClass) {
if (targetClass == null && run instanceof PsiClass) return false;
+ if (run instanceof GrClosableBlock) return false;
if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true;
run = run.getParent();
}
return false;
}
+
+ public static boolean isPropertyAccessInStaticMethod(@NotNull GrReferenceExpression referenceExpression) {
+ return isInStaticContext(referenceExpression) &&
+ !(referenceExpression.getParent() instanceof GrMethodCall) &&
+ referenceExpression.getQualifier() == null;
+ }
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
index 3e5a91b80125..bf75b982cb4e 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java
@@ -740,11 +740,11 @@ public class PsiUtil {
return findEnclosingInstanceClassInScope(clazz, scope, isSuperClassAccepted) != null;
}
- public static PsiClass findEnclosingInstanceClassInScope(@NotNull PsiClass clazz, @Nullable PsiElement scope, boolean isSuperClassAccepted) {
+ public static PsiClass findEnclosingInstanceClassInScope(@NotNull PsiClass clazz, @Nullable PsiElement scope, boolean isInheritorOfClazzAccepted) {
PsiElement place = scope;
while (place != null && place != clazz && !(place instanceof PsiFile && place.isPhysical())) {
if (place instanceof PsiClass) {
- if (isSuperClassAccepted) {
+ if (isInheritorOfClazzAccepted) {
if (InheritanceUtil.isInheritorOrSelf((PsiClass)place, clazz, true)) return (PsiClass)place;
}
else {
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ClosureMissingMethodContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ClosureMissingMethodContributor.java
index 4bedf1db1185..535729946558 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ClosureMissingMethodContributor.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ClosureMissingMethodContributor.java
@@ -16,10 +16,13 @@
package org.jetbrains.plugins.groovy.lang.resolve;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
+import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
/**
* @author Sergey Evdokimov
@@ -28,6 +31,20 @@ public abstract class ClosureMissingMethodContributor {
public static final ExtensionPointName<ClosureMissingMethodContributor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.closureMissingMethodContributor");
+ public static boolean processMethodsFromClosures(GrReferenceExpressionImpl ref, PsiScopeProcessor processor) {
+ for (PsiElement e = ref.getContext(); e != null; e = e.getContext()) {
+ if (e instanceof GrClosableBlock) {
+ ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, e);
+ for (ClosureMissingMethodContributor contributor : EP_NAME.getExtensions()) {
+ if (!contributor.processMembers((GrClosableBlock)e, processor, ref, state)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
public abstract boolean processMembers(GrClosableBlock closure, PsiScopeProcessor processor, GrReferenceExpression refExpr, ResolveState state);
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java
index 51c50c05ce72..7f1b23f2f4bb 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
import java.util.ArrayList;
import java.util.List;
@@ -155,20 +156,23 @@ public class CollectClassMembersUtil {
if (!visitedClasses.add(aClass)) return;
- for (PsiField field : getFields(aClass, includeSynthetic)) {
- String name = field.getName();
+ if (visitedClasses.size() == 1 || !GrTraitUtil.isTrait(aClass)) {
+ for (PsiField field : getFields(aClass, includeSynthetic)) {
+ String name = field.getName();
- if (!allFields.containsKey(name)) {
- allFields.put(name, new CandidateInfo(field, substitutor));
- }
- else if (hasExplicitVisibilityModifiers(field)) {
- final CandidateInfo candidateInfo = allFields.get(name);
- final PsiElement element = candidateInfo.getElement();
- if (element instanceof GrField) {
- final GrModifierList modifierList = ((GrField)element).getModifierList();
- if ((modifierList == null || !modifierList.hasExplicitVisibilityModifiers()) && aClass == ((GrField)element).getContainingClass()) {
- //replace property-field with field with explicit visibilityModifier
- allFields.put(name, new CandidateInfo(field, substitutor));
+ if (!allFields.containsKey(name)) {
+ allFields.put(name, new CandidateInfo(field, substitutor));
+ }
+ else if (hasExplicitVisibilityModifiers(field)) {
+ final CandidateInfo candidateInfo = allFields.get(name);
+ final PsiElement element = candidateInfo.getElement();
+ if (element instanceof GrField) {
+ final GrModifierList modifierList = ((GrField)element).getModifierList();
+ if ((modifierList == null || !modifierList.hasExplicitVisibilityModifiers()) &&
+ aClass == ((GrField)element).getContainingClass()) {
+ //replace property-field with field with explicit visibilityModifier
+ allFields.put(name, new CandidateInfo(field, substitutor));
+ }
}
}
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyMethodArgumentReferenceContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyMethodArgumentReferenceContributor.java
index 46e25a719c8d..30bc357240b4 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyMethodArgumentReferenceContributor.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GroovyMethodArgumentReferenceContributor.java
@@ -37,7 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public final class GroovyMethodArgumentReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(GroovyPatterns.stringLiteral(), new MyProvider());
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
index 7dec4e4c3cae..49f9d40387d8 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java
@@ -976,6 +976,14 @@ public class ResolveUtil {
}, state, null, place);
}
+ public static boolean isClassReference(@NotNull GrReferenceExpression ref) {
+ GrExpression qualifier = ref.getQualifier();
+ return "class".equals(ref.getReferenceName()) &&
+ qualifier instanceof GrReferenceExpression &&
+ ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass &&
+ !org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isThisReference(qualifier);
+ }
+
private static class DuplicateVariablesProcessor extends PropertyResolverProcessor {
private boolean myBorderPassed;
private final boolean myHasVisibilityModifier;
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java
index f4483d7e1d23..7192c53afbec 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java
@@ -27,8 +27,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
import java.util.*;
@@ -146,7 +146,7 @@ public class ResolverProcessor extends GrScopeProcessorWithHints {
if (resolveContext instanceof GrImportStatement) return true;
if (element instanceof PsiModifierListOwner) {
- return StaticChecker.isStaticsOK((PsiModifierListOwner)element, myPlace, resolveContext, filterStaticAfterInstanceQualifier);
+ return GrStaticChecker.isStaticsOK((PsiModifierListOwner)element, myPlace, resolveContext, filterStaticAfterInstanceQualifier);
}
return true;
}
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/providers/GroovyReferenceContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/providers/GroovyReferenceContributor.java
index 8f8367cdda6d..e25c490f87cd 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/providers/GroovyReferenceContributor.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/providers/GroovyReferenceContributor.java
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.resolve.providers;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns;
@@ -28,7 +29,7 @@ import org.jetbrains.plugins.groovy.spock.SpockUnrollReferenceProvider;
*/
public class GroovyReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(GrLiteral.class), new PropertiesReferenceProvider());
registrar.registerReferenceProvider(GroovyPatterns.stringLiteral().withParent(GrAnnotationNameValuePair.class),
diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java
index 6fd4937095e8..9996634f7d58 100644
--- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/util/dynamicMembers/DynamicMemberUtils.java
@@ -35,7 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAc
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
@@ -77,7 +77,7 @@ public class DynamicMemberUtils {
}
public static boolean process(PsiScopeProcessor processor, PsiClass psiClass, GrReferenceExpression ref, String classSource) {
- return process(processor, StaticChecker.isInStaticContext(ref, psiClass), ref, classSource);
+ return process(processor, GrStaticChecker.isInStaticContext(ref, psiClass), ref, classSource);
}
public static boolean process(PsiScopeProcessor processor, boolean isInStaticContext, PsiElement place, String classSource) {
diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml
index aa40a30a8f49..4ae317b2555c 100644
--- a/plugins/groovy/jetgroovy.iml
+++ b/plugins/groovy/jetgroovy.iml
@@ -36,6 +36,7 @@
<orderEntry type="module" module-name="ByteCodeViewer" />
<orderEntry type="module" module-name="properties-psi-api" />
<orderEntry type="module" module-name="groovy-psi" exported="" />
+ <orderEntry type="module" module-name="external-system-api" />
</component>
</module>
diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
index 2f089433d40f..855deba56575 100644
--- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
+++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
@@ -30,7 +30,6 @@ import com.intellij.util.lang.UrlClassLoader;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
import org.jetbrains.groovy.compiler.rt.GroovyRtConstants;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
@@ -58,6 +57,7 @@ import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.service.JpsServiceManager;
import org.jetbrains.jps.service.SharedThreadPool;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.File;
import java.io.IOException;
@@ -315,6 +315,9 @@ public class GroovyBuilder extends ModuleLevelBuilder {
}
}
}
+ if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
+ LOG.info("Chunk " + chunk + " compilation finished");
+ }
return compiled;
}
diff --git a/plugins/groovy/src/META-INF/groovy-byte-code-viewer.xml b/plugins/groovy/src/META-INF/groovy-byte-code-viewer.xml
new file mode 100644
index 000000000000..ee9aeea6ff67
--- /dev/null
+++ b/plugins/groovy/src/META-INF/groovy-byte-code-viewer.xml
@@ -0,0 +1,5 @@
+<idea-plugin>
+ <extensions defaultExtensionNs="ByteCodeViewer">
+ <classSearcher implementation="org.jetbrains.plugins.groovy.byteCodeViewer.GroovyScriptClassSearcher"/>
+ </extensions>
+</idea-plugin>
diff --git a/plugins/groovy/groovy-psi/src/META-INF/groovy-copyright.xml b/plugins/groovy/src/META-INF/groovy-copyright.xml
index ecaa29b00e40..ecaa29b00e40 100644
--- a/plugins/groovy/groovy-psi/src/META-INF/groovy-copyright.xml
+++ b/plugins/groovy/src/META-INF/groovy-copyright.xml
diff --git a/plugins/groovy/groovy-psi/src/META-INF/intellilang-groovy-support.xml b/plugins/groovy/src/META-INF/intellilang-groovy-support.xml
index e46a0b193a9c..e46a0b193a9c 100644
--- a/plugins/groovy/groovy-psi/src/META-INF/intellilang-groovy-support.xml
+++ b/plugins/groovy/src/META-INF/intellilang-groovy-support.xml
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 0fd442787d12..f16d2c195482 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -1,3 +1,1686 @@
-<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="/META-INF/GroovyPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
+<!--
+ ~ Copyright 2000-2009 JetBrains s.r.o.
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+<idea-plugin>
+ <id>org.intellij.groovy</id>
+ <name>Groovy</name>
+ <description>Plugin for Groovy language support, including Groovy++, Grape, Gant and Griffon</description>
+ <version>9.0</version>
+ <vendor>JetBrains</vendor>
+ <depends>com.intellij.properties</depends>
+
+ <depends optional="true" config-file="groovy-copyright.xml">com.intellij.copyright</depends>
+ <depends optional="true" config-file="intellilang-groovy-support.xml">org.intellij.intelliLang</depends>
+ <depends optional="true">AntSupport</depends>
+ <depends optional="true" config-file="groovy-byte-code-viewer.xml">ByteCodeViewer</depends>
+ <depends optional="true" config-file="structuralsearch.xml">Structural Search</depends>
+
+ <extensionPoints>
+ <extensionPoint name="methodComparator" interface="org.jetbrains.plugins.groovy.lang.resolve.GrMethodComparator"/>
+ <extensionPoint name="membersContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor"/>
+ <extensionPoint name="defaultImportContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.DefaultImportContributor"/>
+ <extensionPoint name="astTransformContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor"/>
+ <extensionPoint name="closureMissingMethodContributor"
+ interface="org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor"/>
+ <extensionPoint name="variableEnhancer" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrVariableEnhancer"/>
+ <extensionPoint name="referenceTypeEnhancer" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrReferenceTypeEnhancer"/>
+ <extensionPoint name="typeConverter" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter"/>
+ <extensionPoint name="expectedTypesContributor"
+ interface="org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesContributor"/>
+
+ <extensionPoint name="positionManagerDelegate"
+ interface="org.jetbrains.plugins.groovy.extensions.debugger.ScriptPositionManagerHelper"/>
+ <extensionPoint name="compilerExtension" interface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerExtension"/>
+ <extensionPoint name="scriptTypeDetector" interface="org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector"/>
+
+ <extensionPoint name="namedArgumentProvider" interface="org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider"/>
+ <extensionPoint name="mapContentProvider" interface="org.jetbrains.plugins.groovy.extensions.GroovyMapContentProvider"/>
+
+ <extensionPoint name="unresolvedHighlightFilter" interface="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFilter"/>
+ <extensionPoint name="unresolvedHighlightFileFilter"
+ interface="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedHighlightFileFilter"/>
+ <extensionPoint name="configSlurperSupport" interface="org.jetbrains.plugins.groovy.configSlurper.ConfigSlurperSupport"/>
+
+ <extensionPoint name="callExpressionTypeCalculator"
+ interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrCallExpressionTypeCalculator"/>
+ <extensionPoint name="classDescriptor" beanClass="org.jetbrains.plugins.groovy.extensions.GroovyClassDescriptor"/>
+ <extensionPoint name="methodDescriptor" beanClass="org.jetbrains.plugins.groovy.extensions.GroovyMethodDescriptorExtension"/>
+
+ <extensionPoint name="groovyShellRunner" interface="org.jetbrains.plugins.groovy.console.GroovyShellRunner"/>
+
+ <!-- Groovy DSL extension points -->
+ <extensionPoint name="psiEnhancerCategory" interface="org.jetbrains.plugins.groovy.dsl.psi.PsiEnhancerCategory"/>
+ <extensionPoint name="gdslTopLevelProvider" interface="org.jetbrains.plugins.groovy.dsl.dsltop.GdslMembersProvider"/>
+
+ <extensionPoint name="groovyFrameworkConfigNotification"
+ interface="org.jetbrains.plugins.groovy.annotator.GroovyFrameworkConfigNotification"/>
+ <extensionPoint name="groovySourceFolderDetector" interface="org.jetbrains.plugins.groovy.actions.GroovySourceFolderDetector"/>
+
+ <extensionPoint name="mvc.framework" interface="org.jetbrains.plugins.groovy.mvc.MvcFramework"/>
+ <extensionPoint name="mvc.command.executor" interface="org.jetbrains.plugins.groovy.mvc.MvcCommandExecutor"/>
+
+ <extensionPoint name="closureCompleter" interface="org.jetbrains.plugins.groovy.lang.completion.ClosureCompleter"/>
+
+ <extensionPoint name="methodMayBeStaticInspectionFilter"
+ interface="org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStaticInspectionFilter"/>
+
+ <extensionPoint name="customAnnotationChecker" interface="org.jetbrains.plugins.groovy.annotator.checkers.CustomAnnotationChecker"/>
+
+ <extensionPoint name="convertToJava.customMethodInvocator"
+ interface="org.jetbrains.plugins.groovy.refactoring.convertToJava.invocators.CustomMethodInvocator"/>
+
+ <extensionPoint name="signatureHintProcessor" interface="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SignatureHintProcessor"/>
+ </extensionPoints>
+
+ <extensions defaultExtensionNs="org.intellij.groovy">
+
+ <groovyFrameworkConfigNotification order="last"
+ implementation="org.jetbrains.plugins.groovy.config.DefaultGroovyFrameworkConfigNotification"/>
+
+ <membersContributor implementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicMembersContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.GrCollectionTypeMembersProvider"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.spock.SpockMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.swingBuilder.SwingBuilderNonCodeMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.dgm.DGMMemberContributor"/>
+
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebSpockTestMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebPageMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebModuleMemberContributor"/>
+
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebJUnitTestMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebTestNGTestMemberContributor"/>
+ <membersContributor implementation="org.jetbrains.plugins.groovy.geb.GebBrowserMemberContributor"/>
+
+ <membersContributor implementation="org.jetbrains.plugins.groovy.gant.GantMemberContributor"/>
+
+ <membersContributor implementation="org.jetbrains.plugins.groovy.markup.XmlMarkupBuilderNonCodeMemberContributor"/>
+
+ <closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
+
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.DelegatedMethodsContributor"/>
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoExternalizeContributor"/>
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoCloneContributor"/>
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.ConstructorAnnotationsProcessor"/>
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.GrInheritConstructorContributor"/>
+ <astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.LoggingContributor"/>
+
+ <positionManagerDelegate implementation="org.jetbrains.plugins.groovy.gant.GantPositionManagerHelper"/>
+
+ <methodDescriptor lightMethodKey="SwingBuilder_builder_method"
+ namedArgsProvider="org.jetbrains.plugins.groovy.swingBuilder.SwingBuilderNamedArgumentProvider"/>
+
+ <mapContentProvider implementation="org.jetbrains.plugins.groovy.configSlurper.ConfigSlurperMapContentProvider"/>
+ <referenceTypeEnhancer implementation="org.jetbrains.plugins.groovy.configSlurper.GroovyMapValueTypeEnhancer"/>
+
+ <unresolvedHighlightFilter implementation="org.jetbrains.plugins.groovy.extensions.GroovyUnresolvedReferenceFilterByFile"/>
+
+ <callExpressionTypeCalculator
+ implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.DefaultCallExpressionTypeCalculator"
+ order="last"/>
+ <callExpressionTypeCalculator
+ implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDescriptorReturnTypeCalculator"/>
+ <callExpressionTypeCalculator
+ implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDGMTypeCalculator"/>
+
+ <scriptTypeDetector implementation="org.jetbrains.plugins.groovy.gant.GantScriptTypeDetector"/>
+
+ <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovySourceCodeNamedArgumentProvider" order="last"/>
+ <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovyConstructorNamedArgumentProvider"/>
+ <namedArgumentProvider implementation="org.jetbrains.plugins.groovy.lang.GroovyMethodReturnNamedArgumentProvider" order="last"/>
+
+
+ <!-- GroovyDSL extensions -->
+ <gdslTopLevelProvider implementation="org.jetbrains.plugins.groovy.dsl.dsltop.GroovyDslDefaultMembers"/>
+ <gdslTopLevelProvider implementation="org.jetbrains.plugins.groovy.lang.resolve.GdkMethodDslProvider"/>
+ <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiClassCategory"/>
+ <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiElementCategory"/>
+ <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiMethodCategory"/>
+ <psiEnhancerCategory implementation="org.jetbrains.plugins.groovy.dsl.psi.PsiExpressionCategory"/>
+
+ <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer"/>
+ <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureAsAnonymousParameterEnhancer"/>
+ <variableEnhancer implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParamsEnhancer"/>
+
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FromStringHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SimpleTypeHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.MapEntryOrKeyValueHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FromAbstractTypeMethodsHintProcessor"/>
+
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$FirstGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$SecondGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$ThirdGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.FirstParamHintProcessor$Component"/>
+
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$FirstGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$SecondGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$ThirdGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.SecondParamHintProcessor$Component"/>
+
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$FirstGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$SecondGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$ThirdGeneric"/>
+ <signatureHintProcessor implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ThirdParamHintProcessor$Component"/>
+
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerTypeConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrStringTypeConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrBooleanTypeConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrGenericTypeConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureToSamConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrStringConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrContainerConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.gpp.GppTypeConverter"/>
+ <typeConverter implementation="org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrNumberConverter"/>
+
+ <expectedTypesContributor implementation="org.jetbrains.plugins.groovy.gpp.GppExpectedTypesContributor"/>
+ <variableEnhancer implementation="org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider"/>
+
+ <mvc.framework implementation="org.jetbrains.plugins.groovy.griffon.GriffonFramework"/>
+ <groovyFrameworkConfigNotification implementation="org.jetbrains.plugins.groovy.griffon.GriffonConfigureNotification"/>
+ <defaultImportContributor implementation="org.jetbrains.plugins.groovy.griffon.GriffonDefaultImportContributor"/>
+
+ <groovyShellRunner implementation="org.jetbrains.plugins.groovy.console.GroovyConsoleRunner" order="last"/>
+
+ <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.GdslClosureCompleter"/>
+ <closureCompleter implementation="org.jetbrains.plugins.groovy.lang.completion.EachWithIndexClosureCompleter"/>
+
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.FieldAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.NewifyAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.GrabAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.GrAliasAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.AnnotationCollectorChecker" order="first"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.DelegatesToAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.griffon.GriffonPropertyListenerAnnotationChecker"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.BaseScriptAnnotationChecker"/>
+
+ <convertToJava.customMethodInvocator
+ implementation="org.jetbrains.plugins.groovy.refactoring.convertToJava.invocators.MapGetterSetterInvocator"/>
+ <customAnnotationChecker implementation="org.jetbrains.plugins.groovy.annotator.checkers.TypeCheckedAnnotationChecker"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.intellij.properties">
+ <implicitPropertyUsageProvider implementation="org.jetbrains.plugins.groovy.dgm.DGMImplicitPropertyUsageProvider"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <navbar implementation="org.jetbrains.plugins.groovy.navbar.GrNavBarModelExtension" order="after defaultNavbar"/>
+
+ <fileTypeDetector implementation="org.jetbrains.plugins.groovy.GroovyHashBangFileTypeDetector"/>
+
+
+ <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod"
+ implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrMethodDeclarationRangeHandler"/>
+ <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition"
+ implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrTypeDefinitionRangeHandler"/>
+ <declarationRangeHandler key="org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer"
+ implementationClass="org.jetbrains.plugins.groovy.codeInsight.hint.GrClassInitializerDeclarationRangeHandler"/>
+
+
+ <psi.clsCustomNavigationPolicy implementation="org.jetbrains.plugins.groovy.codeInsight.GroovyClsCustomNavigationPolicy"/>
+
+ <moduleBuilder builderClass="org.jetbrains.plugins.groovy.config.GroovyAwareModuleBuilder"/>
+
+ <pom.declarationSearcher implementation="org.jetbrains.plugins.groovy.geb.GebContentDeclarationSearcher"/>
+
+ <itemPresentationProvider forClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl"
+ implementationClass="org.jetbrains.plugins.groovy.findUsages.GrFileItemPresentationProvider"/>
+
+ <testFramework implementation="org.jetbrains.plugins.groovy.testIntegration.GroovyTestFramework" order="first"/>
+ <testFramework implementation="org.jetbrains.plugins.groovy.spock.SpockTestFramework" order="first"/>
+
+ <testCreator language="Groovy" implementationClass="com.intellij.testIntegration.JavaTestCreator"/>
+ <testGenerator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.testIntegration.GroovyTestGenerator"/>
+ <constructorBodyGenerator language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.GrConstructorBodyGenerator"/>
+ <editorNotificationProvider implementation="org.jetbrains.plugins.groovy.config.ConfigureGroovyLibraryNotificationProvider"/>
+ <refactoring.introduceParameterMethodUsagesProcessor
+ implementation="org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor"/>
+ <refactoring.changeSignatureUsageProcessor
+ implementation="org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeSignatureUsageProcessor" id="groovyProcessor"
+ order="before javaProcessor"/>
+ <safeDelete.importSearcher implementation="org.jetbrains.plugins.groovy.refactoring.safeDelete.GroovyImportSearcher"/>
+ <refactoring.safeDelete.JavaSafeDeleteDelegate
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.safeDelete.JavaSafeDeleteDelegateForGroovy" language="Groovy"/>
+
+ <encapsulateFields.Helper language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.encapsulateFields.GroovyEncapsulateFieldHelper"/>
+
+ <constantExpressionEvaluator language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator"/>
+ <annotationSupport language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GroovyAnnotationSupport"/>
+
+ <expressionConverter language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyExpressionConverter"/>
+
+ <codeInsight.createFieldFromUsageHelper language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.annotator.intentions.GroovyCreateFieldFromUsageHelper"/>
+
+ <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+ <fileTypeFactory implementation="org.jetbrains.plugins.groovy.GroovyFileTypeLoader"/>
+ <fileTypeFactory implementation="org.jetbrains.plugins.groovy.dgm.DGMFileTypeFactory"/>
+
+ <projectConfigurable instance="org.jetbrains.plugins.groovy.gant.GantConfigurable" id="reference.settingsdialog.project.gant"
+ displayName="Gant"/>
+
+ <library.presentationProvider implementation="org.jetbrains.plugins.groovy.config.GroovyLibraryPresentationProvider"/>
+ <library.presentationProvider implementation="org.jetbrains.plugins.groovy.gpp.GppLibraryPresentationProvider" order="first"/>
+ <library.presentationProvider implementation="org.jetbrains.plugins.groovy.gant.GantLibraryPresentationProvider" order="last"/>
+
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.gant.GantSettings"
+ serviceImplementation="org.jetbrains.plugins.groovy.gant.GantSettings"/>
+
+ <spellchecker.support language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.spellchecker.GroovySpellcheckingStrategy"/>
+ <lang.inspectionSuppressor language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionSuppressor"/>
+
+ <colorSettingsPage implementation="org.jetbrains.plugins.groovy.highlighter.GroovyColorsAndFontsPage"/>
+ <framework.type implementation="org.jetbrains.plugins.groovy.config.GroovyFrameworkType"/>
+ <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.PropertyRenameHandler"/>
+ <renamePsiElementProcessor id="groovyFieldRenameProcessor"
+ implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGrFieldProcessor"
+ order="first"/>
+ <renamePsiElementProcessor id="groovyPropertyRenameProcessor"
+ implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGroovyPropertyProcessor"
+ order="first"/>
+ <renamePsiElementProcessor id="groovyLightElementRenamer"
+ implementation="org.jetbrains.plugins.groovy.refactoring.rename.GrLightElementRenamer"
+ order="first, after groovyPropertyRenameProcessor"/>
+ <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedClassProcessor"
+ order="first"/>
+ <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedMethodProcessor"
+ order="first"/>
+ <renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGroovyScriptProcessor"/>
+
+ <rename.inplace.resolveSnapshotProvider language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GroovyResolveSnapshotProvider"/>
+
+ <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GrVariableInplaceRenameHandler"/>
+ <renameHandler implementation="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GrMethodInplaceRenameHandler"/>
+
+ <nameSuggestionProvider implementation="org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionProvider"/>
+
+ <statementUpDownMover implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyStatementMover"/>
+
+ <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrVariableJoinLinesHandler"/>
+ <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinBlockStatementHandler"/>
+ <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinControlStatementHandler"/>
+ <joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinStatementsHandler"/>
+
+ <applicationService serviceInterface="org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings"
+ serviceImplementation="org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings"/>
+ <applicationService serviceInterface="org.jetbrains.plugins.groovy.dsl.DslErrorReporter"
+ serviceImplementation="org.jetbrains.plugins.groovy.dsl.DslErrorReporterImpl"/>
+
+ <!-- Groovy language -->
+ <syntaxHighlighter key="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovySyntaxHighlighter"/>
+
+ <annotator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.annotator.GrAnnotatorImpl"/>
+ <annotator language="Groovy" implementationClass="org.jetbrains.plugins.groovy.dsl.GroovyDslAnnotator"/>
+
+ <lang.psiStructureViewFactory language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.structure.GroovyStructureViewFactory"/>
+ <lang.parserDefinition language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.parser.GroovyParserDefinition"/>
+ <lang.commenter language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyCommenter"/>
+ <lang.foldingBuilder language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.folding.GroovyFoldingBuilder"/>
+ <lang.formatter language="Groovy" implementationClass="org.jetbrains.plugins.groovy.formatter.GroovyFormattingModelBuilder"/>
+ <lang.whiteSpaceFormattingStrategy language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.formatter.GroovyWhiteSpaceFormattingStrategy"/>
+ <postFormatProcessor implementation="org.jetbrains.plugins.groovy.formatter.GroovyBracePostFormatProcessor"/>
+
+ <enterHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyEnterHandler"
+ order="before EnterBetweenBracesHandler"/>
+ <typedHandler implementation="org.jetbrains.plugins.groovy.editor.actions.GStringTypedActionHandler"/>
+ <backspaceHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GStringBackspaceHandlerDelegate"/>
+
+ <typedHandler implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyTypedHandler"/>
+ <backspaceHandlerDelegate implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyBackspaceHandler"/>
+
+ <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Generic"/>
+ <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Expression"/>
+ <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Statement"/>
+ <liveTemplateContext implementation="org.jetbrains.plugins.groovy.template.GroovyTemplateContextType$Declaration"/>
+
+ <defaultLiveTemplatesProvider implementation="org.jetbrains.plugins.groovy.template.GroovyTemplatesProvider"/>
+
+ <liveTemplateOptionalProcessor implementation="org.jetbrains.plugins.groovy.template.GroovyShortenFQNamesProcessor"/>
+ <variableTypeCalculator implementation="org.jetbrains.plugins.groovy.template.GroovyVariableTypeCalculator"/>
+
+ <gotoSymbolContributor implementation="org.jetbrains.plugins.groovy.gotoclass.GroovyGoToSymbolContributor"/>
+ <lang.refactoringSupport language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringSupportProvider"/>
+ <lang.surroundDescriptor language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.surroundWith.GroovySurroundDescriptor"/>
+ <lang.findUsagesProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.findUsages.GroovyFindUsagesProvider"/>
+ <importFilteringRule implementation="org.jetbrains.plugins.groovy.findUsages.GrImportFilteringRule"/>
+
+ <readWriteAccessDetector implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReadWriteAccessDetector" order="before java"/>
+ <findUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GroovyFieldFindUsagesHandlerFactory"/>
+ <highlightUsagesHandlerFactory implementation="org.jetbrains.plugins.groovy.findUsages.GrHighlightHandlerFactory"/>
+ <lang.braceMatcher language="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyBraceMatcher"/>
+ <lang.importOptimizer language="Groovy" implementationClass="org.jetbrains.plugins.groovy.editor.GroovyImportOptimizer"/>
+ <lang.documentationProvider language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.documentation.GroovyDocumentationProvider"/>
+ <lang.smartEnterProcessor language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.completion.smartEnter.GroovySmartEnterProcessor"/>
+ <codeInsight.overrideMethod language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.overrideImplement.GroovyOverrideMethodsHandler"/>
+ <codeInsight.implementMethod language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.overrideImplement.GroovyImplementMethodsHandler"/>
+
+ <methodImplementor implementation="org.jetbrains.plugins.groovy.overrideImplement.GroovyMethodImplementor"/>
+ <methodImplementor implementation="org.jetbrains.plugins.groovy.overrideImplement.TraitMethodImplementor"/>
+ <codeInsight.parameterInfo language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyParameterInfoHandler"/>
+ <codeInsight.parameterInfo language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyAnnotationAttributeInfoHandler"/>
+ <codeInsight.parameterInfo language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.parameterInfo.GroovyTypeParameterInfoHandler"/>
+ <refactoring.inlineHandler language="Groovy" implementationClass="org.jetbrains.plugins.groovy.refactoring.inline.GroovyInlineHandler"/>
+ <inlineActionHandler implementation="org.jetbrains.plugins.groovy.refactoring.inline.GroovyInlineLocalHandler"/>
+
+ <refactoring.moveClassHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyClassHandler"/>
+ <refactoring.moveClassToInnerHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.GroovyMoveClassToInnerHandler"/>
+ <moveFileHandler implementation="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyFileHandler"/>
+ <refactoring.moveMemberHandler language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.move.MoveGroovyMemberHandler"/>
+
+ <refactoring.helper implementation="org.jetbrains.plugins.groovy.refactoring.GroovyImportOptimizerRefactoringHelper"/>
+ <codeInsight.lineMarkerProvider language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.codeInsight.GroovyLineMarkerProvider"/>
+ <codeInsight.gotoSuper language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.codeInsight.navigation.actions.GroovyGotoSuperHandler"/>
+ <lookup.charFilter implementation="org.jetbrains.plugins.groovy.lang.completion.GroovyReferenceCharFilter"/>
+ <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyNoVariantsDelegator"
+ id="groovyBasic2ClassName" order="first, after liveTemplates"/>
+ <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor"
+ id="groovyBasic" order="before javaClassName"/>
+ <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.console.GroovyShellCompletionContributor"/>
+
+ <completion.contributor language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovySmartCompletionContributor"/>
+ <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GrMethodMergingContributor"
+ id="grMethodMerger" order="before methodMerger"/>
+
+ <completion.contributor language="Properties" implementationClass="org.jetbrains.plugins.groovy.dgm.DGMCompletionContributor"/>
+
+ <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.UnfocusedNameIdentifier"
+ id="groovyNameIdentifier"/>
+ <completion.confidence language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionConfidence"
+ id="groovyAdvanced" order="after groovyNameIdentifier"/>
+ <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.UnfocusedComments"
+ id="groovyComments"/>
+ <completion.confidence language="Groovy" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" id="groovyTrue"
+ order="last"/>
+ <completion.contributor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.geb.GebPageFieldNameCompletionContributor"/>
+
+ <cantBeStatic implementation="org.jetbrains.plugins.groovy.codeInspection.declaration.GrCategoryMethodsCantBeStaticExtension"/>
+
+ <psi.referenceContributor language="Properties" implementation="org.jetbrains.plugins.groovy.dgm.DGMReferenceContributor"/>
+
+ <psi.referenceContributor language="Groovy"
+ implementation="org.jetbrains.plugins.groovy.lang.resolve.GroovyMethodArgumentReferenceContributor"/>
+
+ <weigher key="completion" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrWithWeigher"
+ id="groovyWithWeigher" order="after prefix"/>
+ <weigher key="completion" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrKindWeigher"
+ id="groovyKindWeigher" order="after groovyWithWeigher, before explicitProximity"/>
+
+ <weigher key="proximity" implementationClass="org.jetbrains.plugins.groovy.lang.completion.weighers.GrReferenceListWeigher"
+ id="groovyReferenceListWeigher" order="before openedInEditor"/>
+
+ <debuggerClassFilterProvider implementation="org.jetbrains.plugins.groovy.debugger.filters.GroovyDebuggerClassFilterProvider"/>
+
+ <useScopeEnlarger implementation="org.jetbrains.plugins.groovy.lang.psi.impl.search.GrPrivateFieldScopeEnlarger"/>
+
+ <debuggerEditorTextProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.debugger.GroovyEditorTextProvider"/>
+
+ <xdebugger.settings implementation="org.jetbrains.plugins.groovy.debugger.filters.GroovyDebuggerSettings"/>
+ <langCodeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyLanguageCodeStyleSettingsProvider"/>
+ <codeStyleSettingsProvider implementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettingsProvider"/>
+
+ <typeHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.type.GroovyTypeHierarchyProvider"/>
+ <callHierarchyProvider language="Groovy" implementationClass="org.jetbrains.plugins.groovy.hierarchy.call.GrCallHierarchyProvider"/>
+
+ <lang.unwrapDescriptor language="Groovy" implementationClass="org.jetbrains.plugins.groovy.unwrap.GroovyUnwrapDescriptor"/>
+
+ <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral"
+ implementationClass="org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator"/>
+ <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel"
+ implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.statements.arguments.GrArgumentLabelManipulator"/>
+ <lang.elementManipulator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringContent"
+ implementationClass="org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator"/>
+
+
+ <directClassInheritorsSearch implementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyDirectInheritorsSearcher"/>
+
+ <pom.declarationSearcher implementation="org.jetbrains.plugins.groovy.spock.SpockPomDeclarationSearcher"/>
+
+ <typeDeclarationProvider implementation="org.jetbrains.plugins.groovy.editor.GroovyTypeDeclarationProvider" order="first"/>
+
+ <!--Run/debug-->
+ <configurationType implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType"/>
+ <configurationProducer implementation="org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationProducer"/>
+
+ <quoteHandler fileType="Groovy" className="org.jetbrains.plugins.groovy.editor.GroovyQuoteHandler"/>
+
+ <compileServer.plugin classpath="groovy-jps-plugin.jar"/>
+
+ <indexPatternBuilder implementation="org.jetbrains.plugins.groovy.util.GroovyIndexPatternBuilder"/>
+ <todoIndexer filetype="Groovy" implementationClass="org.jetbrains.plugins.groovy.highlighter.GroovyTodoIndexer"/>
+
+ <basicWordSelectionFilter implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyWordSelectionFilter"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyLiteralSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyMembersWithDocSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyBlockStatementsSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeDefinitionBodySelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyTypeCastSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyDocParamsSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyArgListSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyGStringSelectioner"
+ order="before wordSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyParameterListSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyElseSelectioner"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyWordSelectionHandler"/>
+ <extendWordSelectionHandler implementation="org.jetbrains.plugins.groovy.editor.selection.GroovyStatementSelectioner"/>
+
+
+ <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.AccessorMethodReferencesSearcher"/>
+ <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.MethodLateBoundReferencesSearcher"/>
+ <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyConstructorUsagesSearcher"/>
+ <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyReflectedMethodReferenceSearcher"/>
+ <methodReferencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GrLiteralMethodSearcher"/>
+ <annotatedElementsSearch implementation="org.jetbrains.plugins.groovy.findUsages.AnnotatedMembersSearcher"/>
+ <superMethodsSearch implementation="org.jetbrains.plugins.groovy.findUsages.GDKSuperMethodSearcher"/>
+ <definitionsScopedSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyImplementationSearch"/>
+
+ <targetElementEvaluator language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyTargetElementEvaluator"/>
+
+ <fileTemplateGroup implementation="org.jetbrains.plugins.groovy.actions.GroovyTemplatesFactory"/>
+
+ <attachSourcesProvider implementation="org.jetbrains.plugins.groovy.ivy.IvyAttachSourceProvider"/>
+
+ <projectConfigurable instance="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfigurable" id="Groovy compiler"
+ displayName="Groovy Compiler" parentId="project.propCompiler"/>
+
+ <vetoSPICondition implementation="org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider$GroovyExtensionVetoSPI"/>
+
+ <stubElementTypeHolder class="org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes"/>
+ <!--Stubs index-->
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFullClassNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFullScriptNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrFieldNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrMethodNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnnotationMethodNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnnotatedMemberIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrScriptClassNameIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrDirectInheritorsIndex"/>
+ <stubIndex implementation="org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnonymousClassIndex"/>
+
+ <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.ConstructorReferencesSearcher"/>
+ <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GrAliasedImportedElementSearcher"/>
+ <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.AccessorReferencesSearcher"/>
+ <referencesSearch implementation="org.jetbrains.plugins.groovy.findUsages.GroovyTraitFieldSearcher"/>
+
+ <antCustomCompiler implementation="org.jetbrains.plugins.groovy.ant.GroovyAntCustomCompilerProvider"/>
+
+ <project.converterProvider implementation="org.jetbrains.plugins.groovy.config.GroovyModuleConverterProvider"/>
+ <project.converterProvider implementation="org.jetbrains.plugins.groovy.config.GroovyRunConfigurationConverterProvider"/>
+
+ <iconProvider implementation="org.jetbrains.plugins.groovy.GroovyIconProvider"/>
+
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory"
+ serviceImplementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementFactoryImpl"/>
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerWorkspaceConfiguration"
+ serviceImplementation="org.jetbrains.plugins.groovy.compiler.GroovyCompilerWorkspaceConfiguration"/>
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"
+ serviceImplementation="org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration"/>
+
+ <psi.referenceContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.providers.GroovyReferenceContributor"/>
+
+ <resolveScopeProvider implementation="org.jetbrains.plugins.groovy.lang.resolve.GroovyResolveScopeProvider"/>
+
+ <java.elementFinder implementation="org.jetbrains.plugins.groovy.lang.psi.impl.javaView.GroovyClassFinder"/>
+ <java.elementFinder implementation="org.jetbrains.plugins.groovy.gant.GantClassFinder"/>
+ <java.shortNamesCache implementation="org.jetbrains.plugins.groovy.lang.stubs.GroovyShortNamesCache"/>
+
+ <projectService
+ serviceImplementation="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager"/>
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyCodeStyleManager"
+ serviceImplementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleManagerImpl"/>
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyCodeStyleSettingsFacade"
+ serviceImplementation="org.jetbrains.plugins.groovy.codeStyle.GroovyCodeStyleSettingsFacadeImpl"/>
+
+ <projectService
+ serviceImplementation="org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider"/>
+
+ <problemFileHighlightFilter implementation="org.jetbrains.plugins.groovy.GroovyProblemFileHighlightFilter"/>
+
+ <renameInputValidator implementation="org.jetbrains.plugins.groovy.GroovyRenameInputValidator"/>
+ <lang.namesValidator implementationClass="org.jetbrains.plugins.groovy.lang.GroovyNamesValidator" language="Groovy"/>
+
+ <fileBasedIndex implementation="org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex"/>
+
+ <patterns.patternClass className="org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns" alias="groovy"/>
+
+ <stacktrace.fold substring="at org.codehaus.groovy."/>
+ <stacktrace.fold substring="at groovy."/>
+ <stacktrace.fold substring="at org.codehaus.groovy.runtime.DefaultGroovyMethods." negate="true"/>
+ <stacktrace.fold substring="at org.codehaus.groovy.vmplugin.v5.PluginDefaultGroovyMethods." negate="true"/>
+ <stacktrace.fold substring="at org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport." negate="true"/>
+
+ <projectStructureDetector implementation="org.jetbrains.plugins.groovy.GroovySourceRootDetector" id="groovyDetector"/>
+
+ <generation.topLevelFactory language="Groovy" implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFactoryProvider"/>
+
+ <postStartupActivity implementation="org.jetbrains.plugins.groovy.mvc.MvcProjectWithoutLibraryNotificator"/>
+
+ <treeCopyHandler implementation="org.jetbrains.plugins.groovy.lang.GroovyChangeUtilSupport"/>
+ <treeGenerator implementation="org.jetbrains.plugins.groovy.lang.psi.impl.source.impl.GroovyTreeGenerator" order="first"/>
+
+ <copyPastePreProcessor implementation="org.jetbrains.plugins.groovy.editor.GroovyLiteralCopyPasteProcessor"/>
+ <copyPastePostProcessor implementation="org.jetbrains.plugins.groovy.editor.GroovyReferenceCopyPasteProcessor"/>
+
+ <localInspection shortName="GroovyUnusedDeclaration" displayName="Unused declaration"
+ groupPath="Groovy"
+ groupName="Declaration redundancy" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.GroovyUnusedDeclarationInspection" unfair="true"/>
+
+ <localInspection language="Groovy" groupPath="Groovy" shortName="SecondUnsafeCall"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="second.unsafe.call" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.secondUnsafeCall.SecondUnsafeCallInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedAssignment"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="unused.assignment" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedIncOrDec"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="unused.inc.dec" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyVariableNotAssigned"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="unassigned.access" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.unassignedVariable.UnassignedVariableAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMissingReturnStatement"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="no.return.display.name" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="TypeCustomizer"
+ displayName="Type customizer inspection"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ groupKey="other" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.resources.TypeCustomizerInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignabilityCheck" displayName="Incompatible type assignments"
+ groupName="Assignment issues"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfAssignmentUsed" displayName="Result of assignment used"
+ groupName="Assignment issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentCanBeOperatorAssignment"
+ displayName="Assignment replaceable with operator assignment"
+ groupName="Assignment issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentCanBeOperatorAssignmentInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentToForLoopParameter"
+ displayName="Assignment to for-loop parameter"
+ groupName="Assignment issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentToForLoopParameterInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAssignmentToMethodParameter"
+ displayName="Assignment to method parameter"
+ groupName="Assignment issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentToMethodParameterInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedAssignment" displayName="Nested assignment"
+ groupName="Assignment issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyNestedAssignmentInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySillyAssignment" displayName="Silly assignment"
+ groupName="Assignment issues" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovySillyAssignmentInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUncheckedAssignmentOfMemberOfRawType"
+ displayName="Unchecked assignment from members of raw type"
+ groupName="Assignment issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyUncheckedAssignmentOfMemberOfRawTypeInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyContinueOrBreakFromFinallyBlock"
+ displayName="'continue' or 'break' inside 'finally' block"
+ groupName="Error handling" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyContinueOrBreakFromFinallyBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrMethodMayBeStatic"
+ displayName="Method may be static"
+ groupName="Declaration" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.declaration.GrMethodMayBeStaticInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyReturnFromFinallyBlock"
+ displayName="'return' inside 'finally' block" groupName="Error handling"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyReturnFromFinallyBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyThrowFromFinallyBlock"
+ displayName="'throw' inside 'finally' block" groupName="Error handling"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyThrowFromFinallyBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyCatchBlock" displayName="Empty 'catch' block"
+ groupName="Error handling" enabledByDefault="false"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyCatchBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyFinallyBlock" displayName="Empty 'finally' block"
+ groupName="Error handling"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyFinallyBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyTryBlock" displayName="Empty 'try' block"
+ groupName="Error handling" enabledByDefault="false"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyEmptyTryBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedCatchParameter" displayName="Unused catch parameter"
+ groupName="Error handling"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.exception.GroovyUnusedCatchParameterInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyBreak" displayName="Break statement" groupName="Control Flow"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyBreakInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyContinue" displayName="Continue statement"
+ groupName="Control Flow" enabledByDefault="false"
+ level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyContinueInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnreachableStatement" displayName="Unreachable Statement"
+ groupName="Validity issues"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.validity.GroovyUnreachableStatementInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLoopStatementThatDoesntLoop"
+ displayName="Loop statement that doesn't loop" groupName="Control Flow"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyLoopStatementThatDoesntLoopInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalWithIdenticalBranches"
+ displayName="Conditional expression with identical branches"
+ groupName="Control Flow" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalWithIdenticalBranchesInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalCanBeElvis"
+ displayName="Conditional expression can be elvis" groupName="Control Flow"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalCanBeElvisInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditionalCanBeConditionalCall"
+ displayName="Conditional expression can be conditional call"
+ groupName="Control Flow" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConditionalCanBeConditionalCallInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyIfStatementWithIdenticalBranches"
+ displayName="If statement with identical branches"
+ groupName="Control Flow" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyIfStatementWithIdenticalBranchesInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyIfStatementWithTooManyBranches"
+ displayName="If statement with too many branches"
+ groupName="Control Flow" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyIfStatementWithTooManyBranchesInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyFallthrough" displayName="Fallthrough in switch statement"
+ groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyFallthroughInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnnecessaryContinue"
+ displayName="Unnecessary 'continue' statement" groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryContinueInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnnecessaryReturn" displayName="Unnecessary 'return' statement"
+ groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrFinalVariableAccess" displayName="Final variable access"
+ groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.finalVar.GrFinalVariableAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySwitchStatementWithNoDefault"
+ displayName="Switch statement with no default case"
+ groupName="Control Flow" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovySwitchStatementWithNoDefaultInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyReturnFromClosureCanBeImplicit"
+ displayName="'return' statement can be implicit"
+ groupName="Control Flow" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyReturnFromClosureCanBeImplicitInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyTrivialConditional"
+ displayName="Redundant conditional expression" groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantConditional"
+ displayName="Constant conditional expression" groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConstantConditionalInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantIfStatement" displayName="Constant if statement"
+ groupName="Control Flow"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyConstantIfStatementInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyTrivialIf" displayName="Redundant 'if' statement"
+ groupName="Control Flow" enabledByDefault="true"
+ level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="JavaStylePropertiesInvocation"
+ displayName="Java-style property access"
+ groupName="Style" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.style.JavaStylePropertiesInvocationInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAccessToStaticFieldLockedOnInstance"
+ displayName="Access to static field locked on instance data"
+ groupName="Threading issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyAccessToStaticFieldLockedOnInstanceInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDoubleCheckedLocking" displayName="Double-checked locking"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyDoubleCheckedLockingInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnconditionalWait" displayName="Unconditional 'wait' call"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyUnconditionalWaitInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPublicFieldAccessedInSynchronizedContext"
+ displayName="Non-private field accessed in synchronized context" groupName="Threading issues" enabledByDefault="false"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyPublicFieldAccessedInSynchronizedContextInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyBusyWait" displayName="Busy wait" groupName="Threading issues"
+ enabledByDefault="false"
+ level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyBusyWaitInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptySyncBlock" displayName="Empty 'synchronized' block"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyEmptySyncBlockInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnThis" displayName="Synchronization on 'this'"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnThisInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizedMethod" displayName="Synchronized method"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizedMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedSynchronizedStatement"
+ displayName="Nested 'synchronized' statement"
+ groupName="Threading issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyNestedSynchronizedStatementInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyThreadStopSuspendResume"
+ displayName="Call to Thread.stop(), Thread.suspend(), or Thread.resume()"
+ groupName="Threading issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyThreadStopSuspendResumeInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySystemRunFinalizersOnExit"
+ displayName="Call to System.runFinalizersOnExit()"
+ groupName="Threading issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySystemRunFinalizersOnExitInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNotifyWhileNotSynchronized"
+ displayName="'notify()' or 'notifyAll()' while not synced"
+ groupName="Threading issues" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyNotifyWhileNotSynchronizedInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWaitCallNotInLoop" displayName="'wait()' not in loop"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWaitCallNotInLoopInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWaitWhileNotSynchronized" displayName="'wait()' while not synced"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWaitWhileNotSynchronizedInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnNonFinalField"
+ displayName="Synchronization on non-final field"
+ groupName="Threading issues" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnNonFinalFieldInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySynchronizationOnVariableInitializedWithLiteral"
+ displayName="Synchronization on variable initialized with literal" groupName="Threading issues"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovySynchronizationOnVariableInitializedWithLiteralInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnsynchronizedMethodOverridesSynchronizedMethod"
+ displayName="Unsynchronized method overrides synchronized method" groupName="Threading issues" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyUnsynchronizedMethodOverridesSynchronizedMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyWhileLoopSpinsOnField" displayName="While loop spins on field"
+ groupName="Threading issues"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.threading.GroovyWhileLoopSpinsOnFieldInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMethodParameterCount"
+ displayName="Method with too many parameters" groupName="Method Metrics"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMethodParameterCountInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexMethod" displayName="Overly complex method"
+ groupName="Method Metrics"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyComplexMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyLongMethod" displayName="Overly long method"
+ groupName="Method Metrics" enabledByDefault="false"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyNestedMethod" displayName="Overly nested method"
+ groupName="Method Metrics"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyNestedMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMethodWithMoreThanThreeNegations"
+ displayName="Method with more than three negations"
+ groupName="Method Metrics" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMethodWithMoreThanThreeNegationsInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMultipleReturnPointsPerMethod"
+ displayName="Method with multiple return points"
+ groupName="Method Metrics" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMultipleReturnPointsPerMethodInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedSwitch" displayName="Nested switch statement"
+ groupName="Potentially confusing code constructs"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNestedSwitchInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConditional" displayName="Conditional expression"
+ groupName="Potentially confusing code constructs"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyConditionalInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrFieldAlreadyDefined"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="field.already.defined" groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrFieldAlreadyDefinedInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="ClashingGetters"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="clashing.getters" groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingGettersInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrPackage"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="gr.package" groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrPackageInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrDeprecatedAPIUsage"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="gr.deprecated.api.usage" groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrDeprecatedAPIUsageInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedConditional" displayName="Nested conditional expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNestedConditionalInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNegatedConditional" displayName="Negated conditional expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNegatedConditionalInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInArgumentCheck" displayName="Incompatible 'in' argument types"
+ enabledByDefault="true" groupName="Probable bugs" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInArgumentCheckInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNegatedIf" displayName="Negated if condition expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNegatedIfInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfIncrementOrDecrementUsed"
+ displayName="Result of increment or decrement used"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyResultOfIncrementOrDecrementUsedInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" enabledByDefault="true" level="WARNING"
+ shortName="GrReassignedInClosureLocalVar"
+ displayName="Local variable is reassigned in closure or anonymous class"
+ groupName="Potentially confusing code constructs"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrReassignedInClosureLocalVarInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="UnnecessaryQualifiedReference"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="unnecessary.qualified.reference" groupName="Potentially confusing code constructs" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.UnnecessaryQualifiedReferenceInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEmptyStatementBody" displayName="Statement with empty body"
+ groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyEmptyStatementBodyInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPointlessBoolean"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="pointless.boolean.display.name" groupName="Potentially confusing code constructs" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyPointlessBooleanInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyPointlessArithmetic"
+ displayName="Pointless arithmetic expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyPointlessArithmeticInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDoubleNegation" displayName="Double negation"
+ groupName="Potentially confusing code constructs"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyDoubleNegationInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexArithmeticExpression"
+ displayName="Overly complex arithmetic expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOverlyComplexArithmeticExpressionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="ClashingTraitMethods"
+ displayName="Clashing trait methods"
+ groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingTraitMethodsInspection"/>
+
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOverlyComplexBooleanExpression"
+ displayName="Overly complex boolean expression"
+ groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOverlyComplexBooleanExpressionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyOctalInteger" displayName="Octal integer"
+ groupName="Potentially confusing code constructs"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOctalIntegerInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDuplicateSwitchBranch" displayName="Duplicate switch case"
+ groupName="Validity issues"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.validity.GroovyDuplicateSwitchBranchInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNonShortCircuitBoolean" displayName="Non short-circuit boolean"
+ groupName="Probable bugs"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyNonShortCircuitBooleanInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInfiniteLoopStatement" displayName="Infinite loop statement"
+ groupName="Probable bugs"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInfiniteLoopStatementInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInfiniteRecursion" displayName="Infinite recursion"
+ groupName="Probable bugs" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInfiniteRecursionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDivideByZero" displayName="Divide by zero"
+ groupName="Probable bugs" enabledByDefault="true"
+ level="WARNING" implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyDivideByZeroInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyResultOfObjectAllocationIgnored"
+ displayName="Result of object allocation ignored"
+ groupName="Probable bugs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyResultOfObjectAllocationIgnoredInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAccessibility"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="access.to.inaccessible.element" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyAccessibilityInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstructorNamedArguments"
+ displayName="Named arguments of constructor call" groupName="Probable bugs"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyConstructorNamedArgumentsInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyDocCheck" displayName="GroovyDoc issues"
+ groupName="Probable bugs"
+ enabledByDefault="true" level="ERROR"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyDocCheckInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyRangeTypeCheck"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="incorrect.range.argument" groupName="Probable bugs" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyRangeTypeCheckInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="NewInstanceOfSingleton"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="new.instance.of.singleton" groupName="Potentially confusing code constructs" enabledByDefault="true"
+ level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.NewInstanceOfSingletonInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLabeledStatement"
+ bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
+ key="check.labeled.statement" groupName="Probable bugs" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyLabeledStatementInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyClassNamingConvention" displayName="Class naming convention"
+ groupName="Naming Conventions"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyClassNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInterfaceNamingConvention"
+ displayName="Interface naming convention" groupName="Naming Conventions"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInterfaceNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAnnotationNamingConvention"
+ displayName="Annotation naming convention" groupName="Naming Conventions"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyAnnotationNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyEnumerationNamingConvention"
+ displayName="Enumeration naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyEnumerationNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyLocalVariableNamingConvention"
+ displayName="Local variable naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyLocalVariableNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyStaticMethodNamingConvention"
+ displayName="Static method naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyStaticMethodNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyStaticVariableNamingConvention"
+ displayName="Static variable naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyStaticVariableNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInstanceMethodNamingConvention"
+ displayName="Instance method naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInstanceMethodNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInstanceVariableNamingConvention"
+ displayName="Instance variable naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyInstanceVariableNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyConstantNamingConvention"
+ displayName="Constant naming convention" groupName="Naming Conventions"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyConstantNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyParameterNamingConvention"
+ displayName="Method parameter naming convention"
+ groupName="Naming Conventions" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.naming.GroovyParameterNamingConventionInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMapGetCanBeKeyedAccess"
+ displayName="Call to Map.get can be keyed access"
+ groupName="GPath inspections" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyMapGetCanBeKeyedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyMapPutCanBeKeyedAccess"
+ displayName="Call to Map.put can be keyed access"
+ groupName="GPath inspections" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyMapPutCanBeKeyedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyListGetCanBeKeyedAccess"
+ displayName="Call to List.get can be keyed access"
+ groupName="GPath inspections" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyListGetCanBeKeyedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyListSetCanBeKeyedAccess"
+ displayName="Call to List.set can be keyed access"
+ groupName="GPath inspections" enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.gpath.GroovyListSetCanBeKeyedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUntypedAccess" displayName="Access to untyped expression"
+ groupName="Probable bugs"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GrUnresolvedAccess" displayName="Access to unresolved expression"
+ groupName="Probable bugs"
+ enabledByDefault="true" level="WEAK WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection"/>
+ <localInspection language="Groovy" groupPath="Groovy" shortName="GroovySingletonAnnotation"
+ displayName="Check '@Singleton' annotation conventions"
+ groupName="Annotations verifying" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.annotator.inspections.GroovySingletonAnnotationInspection"/>
+
+ <localInspection language="Groovy" groupPath="Groovy" shortName="DelegatesTo" displayName="@DelegatesTo inspection"
+ groupName="Annotations verifying" enabledByDefault="true" level="WARNING"
+ implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.DelegatesToInspection"/>
+
+ <implicitUsageProvider implementation="org.jetbrains.plugins.groovy.gpp.GppImplicitUsageProvider"/>
+ <implicitUsageProvider implementation="org.jetbrains.plugins.groovy.findUsages.GrImplicitUsageProvider"/>
+
+ <!-- control flow -->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.DemorgansLawIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.SplitIfIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.InvertIfIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.GrRedundantElseIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.FlipIfIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.ReplaceTernaryWithIfElseIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.ReplaceIfWithTernaryIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.SimplifyTernaryOperatorIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.CreateParameterForFieldIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.MergeIfAndIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.ExpandBooleanIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.FlipConjunctionIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.FlipComparisonIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.NegateComparisonIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.MergeElseIfIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.SplitElseIfIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.control.flow</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.control.FlipConditionalIntention</className>
+ </intentionAction>
+
+ <!-- closures -->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.closures</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.closure.MakeClosureCallExplicitIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.closures</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.closure.MakeClosureCallImplicitIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.closures</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.closure.ForToEachIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.closures</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.closure.EachToForIntention</className>
+ </intentionAction>
+ <!--
+ todo make this work
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.closures</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.closure.ConvertClosureArgToItIntention</className>
+ </intentionAction>
+ -->
+
+
+ <!-- comments -->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.comments</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.comments.ChangeToCStyleCommentIntention</className>
+ </intentionAction>
+ <!--
+ todo make this work
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.comments</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.comments.ChangeToEndOfLineCommentIntention</className>
+ </intentionAction>
+ -->
+
+ <!-- conversions -->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertJavaStyleArrayIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToDecimalIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToHexIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToOctalIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToBinaryIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.IndexingMethodConversionIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.IndexedExpressionConversionIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertGStringToStringIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertMultilineStringToSingleLineIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertToRegexIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertToDollarSlashRegexIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.GrConvertStringToCharIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.RemoveUnnecessaryEscapeCharactersIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.GrBreakStringOnLineBreaksIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.GrSplitDeclarationIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.RemoveParenthesesFromMethodCallIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.RemoveUnnecessaryBracesInGStringIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertMapToClassIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertConcatenationToGstringIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.RenameFileWithClassIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.MoveClassToNewFileIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertMethodToClosureIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertStringToMultilineIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertClosureToMethodIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertSimpleGetterToPropertyIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.GrConvertTypeCastToSafeCastIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.conversions</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.conversions.ConvertJunitAssertionToAssertStatementIntention</className>
+ </intentionAction>
+
+ <!-- groovy style -->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.JavaStylePropertiesInvocationIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.RemoveUnnecessarySemicolonsIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.ImportStaticIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.ImportOnDemandIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.ConvertToGeeseBracesIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.RemoveRedundantClassPropertyIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.ConvertFromGeeseBracesIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.RemoveUnnecessaryReturnIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.AddReturnTypeFix</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.parameterToEntry.ConvertParameterToMapEntryIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.style</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.style.ReplaceAbstractClassInstanceByMapIntention</className>
+ </intentionAction>
+
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy</categoryKey>
+ <className>org.jetbrains.plugins.groovy.grape.GrabDependencies</className>
+ </intentionAction>
+
+ <!--declaration-->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrCreateSubclassAction</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrCreateFieldForParameterIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrSetStrongTypeIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberPublicIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberProtectedIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrMakeMemberPrivateIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrIntroduceLocalVariableIntention</className>
+ </intentionAction>
+
+ <!--other-->
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.other</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.other.GrCreateMissingSwitchBranchesIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.other</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.other.GrAliasImportIntention</className>
+ </intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.other</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.other.GrCopyStringConcatenationContentIntention</className>
+ </intentionAction>
+
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.other</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.other.GrSortMapKeysIntention</className>
+ </intentionAction>
+
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrRemoveExplicitTypeDeclarationIntention</className>
+ </intentionAction>
+
+ <projectService
+ serviceImplementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"/>
+
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.griffon.GriffonProjectViewState"
+ serviceImplementation="org.jetbrains.plugins.groovy.griffon.GriffonProjectViewState"/>
+
+ <java.programPatcher implementation="org.jetbrains.plugins.groovy.debugger.GroovyHotSwapper"/>
+ <psi.referenceContributor implementation="org.jetbrains.plugins.groovy.gpp.GppReferenceContributor"/>
+
+ <library.presentationProvider implementation="org.jetbrains.plugins.groovy.griffon.GriffonLibraryPresentationProvider"/>
+ <moduleBuilder builderClass="org.jetbrains.plugins.groovy.griffon.GriffonModuleBuilder" id="griffonModuleBuilder"/>
+ <projectStructureDetector implementation="org.jetbrains.plugins.groovy.griffon.GriffonProjectStructureDetector"
+ order="before groovyDetector"/>
+ <programRunner implementation="org.jetbrains.plugins.groovy.griffon.GriffonDebuggerRunner"/>
+ <configurationType implementation="org.jetbrains.plugins.groovy.griffon.GriffonRunConfigurationType"/>
+ <toolWindow id="Griffon View" anchor="left" secondary="false" icon="JetgroovyIcons.Griffon.GriffonToolWindow"
+ factoryClass="org.jetbrains.plugins.groovy.griffon.GriffonToolWindowFactory"
+ conditionClass="org.jetbrains.plugins.groovy.griffon.GriffonToolWindowFactory"/>
+
+ <roots.watchedRootsProvider implementation="org.jetbrains.plugins.groovy.mvc.MvcWatchedRootProvider"/>
+ <projectService serviceInterface="org.jetbrains.plugins.groovy.mvc.MvcConsole"
+ serviceImplementation="org.jetbrains.plugins.groovy.mvc.MvcConsole"/>
+ <selectInTarget implementation="org.jetbrains.plugins.groovy.mvc.projectView.MvcProjectViewSelectInTarget"/>
+ <applicationService serviceImplementation="org.jetbrains.plugins.groovy.mvc.MvcRunTargetHistoryService"
+ serviceInterface="org.jetbrains.plugins.groovy.mvc.MvcRunTargetHistoryService"/>
+ <applicationService serviceInterface="org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactory"
+ serviceImplementation="org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactoryImpl"/>
+
+ <debugger.positionManagerFactory id="groovyPositionManager"
+ implementation="org.jetbrains.plugins.groovy.debugger.GroovyPositionManagerFactory"/>
+ <debugger.positionManagerFactory order="after groovyPositionManager"
+ implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
+ <debugger.nodeRenderer implementation="org.jetbrains.plugins.groovy.debugger.GroovyRefRenderer"/>
+ <codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
+ <codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
+ <lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
+ <refactoring.pullUpHelperFactory language="Groovy"
+ implementationClass="org.jetbrains.plugins.groovy.refactoring.memberPullUp.GrPullUpHelperFactory"/>
+ <classTypePointerFactory implementation="org.jetbrains.plugins.groovy.lang.psi.impl.smartPointers.GrClassReferenceTypePointerFactory"/>
+ <hierarchy.referenceProcessor implementation="org.jetbrains.plugins.groovy.hierarchy.call.GrCallReferenceProcessor"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.intellij.debugger">
+ <codeFragmentFactory implementation="org.jetbrains.plugins.groovy.debugger.GroovyCodeFragmentFactory"/>
+ </extensions>
+
+ <actions>
+ <action id="Groovy.Shell.Execute" class="com.intellij.openapi.actionSystem.EmptyAction" text="Execute Groovy Code"
+ description="Execute Groovy code in console">
+ <keyboard-shortcut first-keystroke="control ENTER" keymap="$default"/>
+ </action>
+
+ <action id="Groovy.NewClass" class="org.jetbrains.plugins.groovy.actions.NewGroovyClassAction"
+ text="Groovy Class" description="Create new Groovy class">
+ <add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewGroup1"/>
+ </action>
+ <action id="Groovy.NewScript" class="org.jetbrains.plugins.groovy.actions.NewScriptAction"
+ text="Groovy Script" description="Create new Groovy script">
+ <add-to-group group-id="NewGroup" anchor="last"/>
+ </action>
+
+ <action id="Gant.NewScript" class="org.jetbrains.plugins.groovy.gant.NewGantScriptAction"
+ text="Gant Script" description="Create new Gant script">
+ <add-to-group group-id="NewGroup" anchor="last"/>
+ </action>
+
+ <group id="Groovy.Dynamic.Toolbar">
+ <action id="Groovy.Dynamic.Remove" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.RemoveDynamicAction"
+ icon="AllIcons.General.Remove" text="Remove" description="Remove dynamic element"/>
+ <separator/>
+ <action id="Groovy.Dynamic.ExpandAll" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ExpandAllAction"
+ icon="AllIcons.Actions.Expandall" text="Expand all" description="Collapse all"/>
+ <action id="Groovy.Dynamic.CollapseAll" class="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.CollapseAllAction"
+ icon="AllIcons.Actions.Collapseall" text="Collapse all" description="Collapse all"/>
+ </group>
+
+
+ <action id="ConvertGroovyToJava"
+ class="org.jetbrains.plugins.groovy.actions.ConvertToJavaAction"
+ text="Convert to Java"
+ description="Convert Groovy files to Java">
+ <add-to-group group-id="RefactoringMenu"/>
+ </action>
+
+ <group id="Internal.Groovy" text="Groovy" popup="true" internal="true">
+ <action id="GetPsiTypeAction" class="org.jetbrains.plugins.groovy.actions.GrGetPsiTypeAction"
+ text="get PsiType" description=""
+ internal="true"/>
+
+ <action id="DumpGroovyControlFlowAction"
+ class="org.jetbrains.plugins.groovy.actions.DumpGroovyControlFlowAction"
+ text="dump groovy control flow"
+ description="" internal="true"/>
+ <action id="DumpGroovyStubsAction"
+ class="org.jetbrains.plugins.groovy.actions.DumpGroovyStubsAction"
+ text="dump groovy stubs"
+ description="" internal="true"/>
+ <add-to-group group-id="Internal"/>
+ </group>
+
+ <action id="ExcludeFromStubGeneration"
+ class="org.jetbrains.plugins.groovy.compiler.ExcludeFromStubGenerationAction"
+ text="Exclude from stub generation" description="Don't generate Java stubs for this Groovy file on compilation">
+ <add-to-group group-id="EditorTabPopupMenu" anchor="after" relative-to-action="RenameJavaFileToGroovyFileAction"/>
+ </action>
+
+
+ <group id="GroovyGenerateGroup1">
+ <action id="org.jetbrains.plugins.groovy.actions.generate.constructors.GroovyGenerateConstructorAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.constructors.GroovyGenerateConstructorAction"
+ text="Constructor" description="Generates constructor"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterAction"
+ text="Getter" description="Generates getter"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateSetterAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateSetterAction"
+ text="Setter" description="Generates setter"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterSetterAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.accessors.GroovyGenerateGetterSetterAction"
+ text="Getter and Setter" description="Generates getter"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.equals.GroovyGenerateEqualsAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.equals.GroovyGenerateEqualsAction"
+ text="equals() and hashCode()" description="Action generates equals and hashCode now"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGenerateMethodMissingAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGenerateMethodMissingAction"
+ text="methodMissing()" description="Action generates propertyMissing()"/>
+ <action id="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGeneratePropertyMissingAction"
+ class="org.jetbrains.plugins.groovy.actions.generate.missing.GroovyGeneratePropertyMissingAction"
+ text="propertyMissing()" description="Action generates propertyMissing()"/>
+
+ <add-to-group group-id="GenerateGroup" anchor="after" relative-to-action="JavaGenerateGroup1"/>
+ </group>
+
+ <action id="Groovy.Doc.Generating"
+ class="org.jetbrains.plugins.groovy.doc.actions.GenerateGroovyDocAction"
+ text="Generate GroovyDoc..." description="Generating Groovy Documentation"
+ icon="JetgroovyIcons.Groovy.GroovyDoc">
+ <add-to-group group-id="ToolsMenu" anchor="last"/>
+ </action>
+ <action id="Groovy.Shell"
+ class="org.jetbrains.plugins.groovy.console.GroovyShellAction"
+ text="Groovy Shell..." description="Launch Groovy Shell"
+ icon="JetgroovyIcons.Groovy.Groovy_16x16">
+ <add-to-group group-id="ToolsMenu" anchor="last"/>
+ </action>
+
+ <action id="Groovy.Console"
+ class="org.jetbrains.plugins.groovy.console.GroovyConsoleAction"
+ text="Groovy Console..." description="Launch Groovy Console"
+ icon="JetgroovyIcons.Groovy.Groovy_16x16">
+ <add-to-group group-id="ToolsMenu" anchor="last"/>
+ </action>
+
+ <group id="Mvc.Actions" popup="true" class="org.jetbrains.plugins.groovy.mvc.MvcActionGroup">
+ <action id="Mvc.Upgrade"
+ class="org.jetbrains.plugins.groovy.mvc.MvcUpgradeAction"
+ text="Change SDK version" description="Change Grails/Griffon SDK version">
+ </action>
+
+ <action id="Griffon.UpdateDependencies" class="org.jetbrains.plugins.groovy.griffon.UpdateGriffonSettingsAction"
+ text="Synchronize Griffon settings"
+ description="Refresh IntelliJ IDEA project structure so that it matches Griffon build settings">
+ </action>
+
+ <action id="Mvc.RunTarget" class="org.jetbrains.plugins.groovy.mvc.MvcRunTarget"
+ text="Run Target" description="Run arbitrary Grails/Griffon target">
+ <keyboard-shortcut keymap="$default" first-keystroke="ctrl alt G"/>
+ </action>
+ <add-to-group group-id="ProjectViewPopupMenu" anchor="after" relative-to-action="AddFrameworkSupport"/>
+ <add-to-group group-id="NavbarPopupMenu" anchor="after" relative-to-action="AddFrameworkSupport"/>
+ <add-to-group group-id="ToolsMenu" anchor="last"/>
+ </group>
+
+ </actions>
+
+ <application-components>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.gant.GantLoader</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.mvc.MvcPathMacros</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.dsl.DslActivationStatus</implementation-class>
+ </component>
+ </application-components>
+
+ <project-components>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportsPassFactory</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.annotator.GrKeywordAndDeclarationHighlightFactory</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.annotator.GrReferenceHighlighterFactory</implementation-class>
+ </component>
+ <component>
+ <interface-class>org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManager</interface-class>
+ <implementation-class>org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManagerImpl</implementation-class>
+ </component>
+ <component>
+ <implementation-class>org.jetbrains.plugins.groovy.mvc.MvcModuleStructureSynchronizer</implementation-class>
+ </component>
+ </project-components>
</idea-plugin>
diff --git a/plugins/groovy/src/META-INF/structuralsearch.xml b/plugins/groovy/src/META-INF/structuralsearch.xml
new file mode 100644
index 000000000000..b3b6193771de
--- /dev/null
+++ b/plugins/groovy/src/META-INF/structuralsearch.xml
@@ -0,0 +1,6 @@
+<idea-plugin url="http://www.jetbrains.com/idea">
+ <extensions defaultExtensionNs="com.intellij">
+ <structuralsearch.profile implementation="com.intellij.structuralsearch.GroovyStructuralSearchProfile"/>
+ </extensions>
+</idea-plugin>
+ \ No newline at end of file
diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrLanguageReferenceProvider.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrLanguageReferenceProvider.java
index 401f20edc06e..f4094b2d665f 100644
--- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrLanguageReferenceProvider.java
+++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/GrLanguageReferenceProvider.java
@@ -32,7 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns;
*/
public class GrLanguageReferenceProvider extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
final Configuration configuration = Configuration.getInstance();
registrar.registerReferenceProvider(
GroovyPatterns.groovyLiteralExpression().annotationParam(StandardPatterns.string().with(isLanguageAnnotation(configuration)), "value").and(
diff --git a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java
index 0e9a216c441b..e23254da8d1a 100644
--- a/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java
+++ b/plugins/groovy/src/org/intellij/plugins/intelliLang/inject/groovy/PatternEditorContextMembersProvider.java
@@ -146,7 +146,7 @@ public class PatternEditorContextMembersProvider extends NonCodeMembersContribut
GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.XML);
final TextOccurenceProcessor occurenceProcessor = new TextOccurenceProcessor() {
@Override
- public boolean execute(PsiElement element, int offsetInElement) {
+ public boolean execute(@NotNull PsiElement element, int offsetInElement) {
final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
final String className = tag == null ? null : tag.getAttributeValue("className");
if (className != null && tag.getLocalName().endsWith("patternClass")) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java
index 068e96dd4cd0..00068d82237d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -71,7 +71,7 @@ public class GroovyGenerationInfo<T extends PsiMember> extends PsiGenerationInfo
final T member = getPsiMember();
if (member == null) return;
- LOG.assertTrue(member instanceof GroovyPsiElement);
+ LOG.assertTrue(member instanceof GroovyPsiElement, member);
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(member.getProject());
final PsiElement prev = member.getPrevSibling();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java
index 7f4f40fe94aa..ef19899ba5df 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java
@@ -25,7 +25,7 @@ import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
/**
* @author ven
@@ -49,7 +49,7 @@ public class CreateFieldFromUsageFix extends GrCreateFromUsageBaseFix {
private String[] generateModifiers(@NotNull PsiClass targetClass) {
final GrReferenceExpression myRefExpression = getRefExpr();
- if (myRefExpression != null && StaticChecker.isInStaticContext(myRefExpression, targetClass)) {
+ if (myRefExpression != null && GrStaticChecker.isInStaticContext(myRefExpression, targetClass)) {
return new String[]{PsiModifier.STATIC};
}
return ArrayUtil.EMPTY_STRING_ARRAY;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java
index a1f356cdf4bb..881e823285c9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateMethodFromUsageFix.java
@@ -33,9 +33,9 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
-import org.jetbrains.plugins.groovy.lang.psi.util.StaticChecker;
import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression;
/**
@@ -60,7 +60,7 @@ public class CreateMethodFromUsageFix extends GrCreateFromUsageBaseFix implement
PsiMethod method = factory.createMethod(getMethodName(), PsiType.VOID);
final GrReferenceExpression ref = getRefExpr();
- if (StaticChecker.isInStaticContext(ref, targetClass)) {
+ if (GrStaticChecker.isInStaticContext(ref, targetClass)) {
method.getModifierList().setModifierProperty(PsiModifier.STATIC, true);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java
index 2fd5dc753988..16100550885d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java
@@ -31,7 +31,7 @@ import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStaticChecker;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import javax.swing.*;
@@ -139,7 +139,7 @@ public abstract class GrCreateFromUsageBaseFix extends Intention {
private List<PsiClass> getTargetClasses() {
final GrReferenceExpression ref = getRefExpr();
- final boolean compileStatic = PsiUtil.isCompileStatic(ref) || GrReferenceResolveUtil.isPropertyAccessInStaticMethod(ref);
+ final boolean compileStatic = PsiUtil.isCompileStatic(ref) || GrStaticChecker.isPropertyAccessInStaticMethod(ref);
final PsiClass targetClass = QuickfixUtil.findTargetClass(ref, compileStatic);
if (targetClass == null || !canBeTargetClass(targetClass)) return Collections.emptyList();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/navigation/actions/GroovyGotoSuperHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/navigation/actions/GroovyGotoSuperHandler.java
index 0aa67f28969b..d2d4a1bc6161 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/navigation/actions/GroovyGotoSuperHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/navigation/actions/GroovyGotoSuperHandler.java
@@ -56,18 +56,21 @@ public class GroovyGotoSuperHandler extends GotoTargetHandler implements Languag
return new GotoData(e, findTargets(e), Collections.<AdditionalAction>emptyList());
}
+ @NotNull
@Override
protected String getChooserTitle(PsiElement sourceElement, String name, int length) {
return CodeInsightBundle.message("goto.super.method.chooser.title");
}
+ @NotNull
@Override
protected String getFindUsagesTitle(PsiElement sourceElement, String name, int length) {
return CodeInsightBundle.message("goto.super.method.findUsages.title", name);
}
+ @NotNull
@Override
- protected String getNotFoundMessage(Project project, Editor editor, PsiFile file) {
+ protected String getNotFoundMessage(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
final PsiMember source = findSource(editor, file);
if (source instanceof PsiClass) {
return GroovyBundle.message("no.super.classes.found");
@@ -87,7 +90,8 @@ public class GroovyGotoSuperHandler extends GotoTargetHandler implements Languag
return PsiTreeUtil.getParentOfType(element, PsiMethod.class, GrField.class, PsiClass.class);
}
- private static PsiElement[] findTargets(PsiMember e) {
+ @NotNull
+ private static PsiElement[] findTargets(@NotNull PsiMember e) {
if (e instanceof PsiClass) {
PsiClass aClass = (PsiClass)e;
List<PsiClass> allSupers = new ArrayList<PsiClass>(Arrays.asList(aClass.getSupers()));
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionSuppressor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionSuppressor.java
new file mode 100644
index 000000000000..df2288a5159b
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionSuppressor.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.codeInspection;
+
+import com.intellij.codeInspection.InspectionSuppressor;
+import com.intellij.codeInspection.SuppressQuickFix;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public class GroovyInspectionSuppressor implements InspectionSuppressor {
+ @Override
+ public boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String name) {
+ return GroovySuppressableInspectionTool.getElementToolSuppressedIn(element, name) != null;
+ }
+
+ @Override
+ public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, String toolShortName) {
+ return GroovySuppressableInspectionTool.getSuppressActions(toolShortName);
+ }
+}
+
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingTraitMethodsInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingTraitMethodsInspection.java
index a446f3821b5c..b5579e186613 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingTraitMethodsInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingTraitMethodsInspection.java
@@ -30,7 +30,7 @@ import java.util.List;
* Created by Max Medvedev on 03/06/14
*/
public class ClashingTraitMethodsInspection extends BaseInspection {
- private static final Logger LOG = Logger.getInstance(MyQuickFix.class);
+ private static final Logger LOG = Logger.getInstance(ClashingTraitMethodsInspection.class);
@NotNull
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/spellchecker/GroovySpellcheckingStrategy.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/spellchecker/GroovySpellcheckingStrategy.java
index f252ee8869ef..9bc67a4355d0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/spellchecker/GroovySpellcheckingStrategy.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/spellchecker/GroovySpellcheckingStrategy.java
@@ -15,16 +15,14 @@
*/
package org.jetbrains.plugins.groovy.codeInspection.spellchecker;
-import com.intellij.codeInspection.SuppressQuickFix;
import com.intellij.psi.PsiElement;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.spellchecker.inspections.PlainTextSplitter;
import com.intellij.spellchecker.tokenizer.EscapeSequenceTokenizer;
-import com.intellij.spellchecker.tokenizer.SuppressibleSpellcheckingStrategy;
+import com.intellij.spellchecker.tokenizer.SpellcheckingStrategy;
import com.intellij.spellchecker.tokenizer.TokenConsumer;
import com.intellij.spellchecker.tokenizer.Tokenizer;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.codeInspection.GroovySuppressableInspectionTool;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
@@ -32,7 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
/**
* @author peter
*/
-public class GroovySpellcheckingStrategy extends SuppressibleSpellcheckingStrategy {
+public class GroovySpellcheckingStrategy extends SpellcheckingStrategy {
private final GrDocCommentTokenizer myDocCommentTokenizer = new GrDocCommentTokenizer();
private final Tokenizer<PsiElement> myStringTokenizer = new Tokenizer<PsiElement>() {
@Override
@@ -66,14 +64,4 @@ public class GroovySpellcheckingStrategy extends SuppressibleSpellcheckingStrate
//if (element instanceof GrLiteralImpl && ((GrLiteralImpl)element).isStringLiteral()) return myStringTokenizer;
return super.getTokenizer(element);
}
-
- @Override
- public boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String name) {
- return GroovySuppressableInspectionTool.getElementToolSuppressedIn(element, name) != null;
- }
-
- @Override
- public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, @NotNull String name) {
- return GroovySuppressableInspectionTool.getSuppressActions(name);
- }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
index 911451e55e2d..1b2f82fe186b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/config/ConfigureGroovyLibraryNotificationProvider.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -67,13 +68,14 @@ public class ConfigureGroovyLibraryNotificationProvider extends EditorNotificati
}
}
+ @NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
- public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
+ public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
try {
if (!supportedFileTypes.contains(file.getFileType())) return null;
// do not show the panel for Gradle build scripts
@@ -81,7 +83,7 @@ public class ConfigureGroovyLibraryNotificationProvider extends EditorNotificati
if (StringUtil.endsWith(file.getName(), ".gradle")) return null;
if (CompilerManager.getInstance(myProject).isExcludedFromCompilation(file)) return null;
- final Module module = ModuleUtil.findModuleForFile(file, myProject);
+ final Module module = ModuleUtilCore.findModuleForFile(file, myProject);
if (module == null) return null;
if (isMavenModule(module)) return null;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellCompletionContributor.java
index 709c5e396483..b1a3a00418fd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellCompletionContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/console/GroovyShellCompletionContributor.java
@@ -34,7 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
*/
public class GroovyShellCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
if (!(file instanceof GroovyShellCodeFragment)) return;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java
index 48e98a45206b..73e3b27afcf9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java
@@ -27,6 +27,7 @@ import com.intellij.debugger.requests.ClassPrepareRequestor;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
@@ -109,9 +110,16 @@ public class GroovyPositionManager implements PositionManager {
}
}
+ private static void checkGroovyFile(@NotNull SourcePosition position) throws NoDataException {
+ if (!(position.getFile() instanceof GroovyFileBase)) {
+ throw new NoDataException();
+ }
+ }
+
@Override
public ClassPrepareRequest createPrepareRequest(@NotNull final ClassPrepareRequestor requestor, @NotNull final SourcePosition position)
throws NoDataException {
+ checkGroovyFile(position);
String qName = getOuterClassName(position);
if (qName != null) {
return myDebugProcess.getRequestsManager().createClassPrepareRequest(requestor, qName);
@@ -260,7 +268,10 @@ public class GroovyPositionManager implements PositionManager {
private static GlobalSearchScope addModuleContent(GlobalSearchScope scope) {
if (scope instanceof ModuleWithDependenciesScope) {
- return scope.uniteWith(((ModuleWithDependenciesScope)scope).getModule().getModuleContentWithDependenciesScope());
+ Module module = ((ModuleWithDependenciesScope)scope).getModule();
+ if (!module.isDisposed()) {
+ return scope.uniteWith(module.getModuleContentWithDependenciesScope());
+ }
}
return scope;
}
@@ -277,6 +288,7 @@ public class GroovyPositionManager implements PositionManager {
@Override
@NotNull
public List<ReferenceType> getAllClasses(@NotNull final SourcePosition position) throws NoDataException {
+ checkGroovyFile(position);
List<ReferenceType> result = ApplicationManager.getApplication().runReadAction(new Computable<List<ReferenceType>>() {
@Override
public List<ReferenceType> compute() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java
index 2dd7f99dd95c..d5f6e0f3c5c2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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 DGMReferenceContributor extends PsiReferenceContributor {
private final JavaClassReferenceProvider myProvider = new JavaClassReferenceProvider();
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PropertiesTokenTypes.VALUE_CHARACTERS), new PsiReferenceProvider() {
@NotNull
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java
index adda0faf476f..56d51c6d7e7d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantScriptType.java
@@ -20,12 +20,12 @@ import com.intellij.compiler.options.CompileStepBeforeRunNoErrorCheck;
import com.intellij.execution.Location;
import com.intellij.execution.RunManagerEx;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.NonClasspathDirectoryScope;
+import com.intellij.psi.search.NonClasspathDirectoriesScope;
import icons.JetgroovyIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -84,7 +84,7 @@ public class GantScriptType extends GroovyRunnableScriptType {
final GrNamedArgument[] args = ((GrMethodCallExpression)parent).getNamedArguments();
if (args.length == 1) {
final GrArgumentLabel label = args[0].getLabel();
- if (label != null && GantUtils.isPlainIdentifier(label)) {
+ if (label != null) {
return label.getName();
}
}
@@ -104,7 +104,7 @@ public class GantScriptType extends GroovyRunnableScriptType {
}
public static List<VirtualFile> additionalScopeFiles(@NotNull GroovyFile file) {
- final Module module = ModuleUtil.findModuleForPsiElement(file);
+ final Module module = ModuleUtilCore.findModuleForPsiElement(file);
if (module != null) {
final String sdkHome = GantUtils.getSdkHomeFromClasspath(module);
if (sdkHome != null) {
@@ -123,10 +123,6 @@ public class GantScriptType extends GroovyRunnableScriptType {
@Override
public GlobalSearchScope patchResolveScope(@NotNull GroovyFile file, @NotNull GlobalSearchScope baseScope) {
- GlobalSearchScope result = baseScope;
- for (final VirtualFile root : additionalScopeFiles(file)) {
- result = result.uniteWith(new NonClasspathDirectoryScope(root));
- }
- return result;
+ return baseScope.uniteWith(new NonClasspathDirectoriesScope(additionalScopeFiles(file)));
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java
index 5c1c824fb580..11a0c2b9ccd6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/grape/GrabDependencies.java
@@ -82,6 +82,7 @@ public class GrabDependencies implements IntentionAction {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.grape.GrabDependencies");
private static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup("Grape", NotificationDisplayType.BALLOON, true);
+ public static final String GRAPE_RUNNER = "org.jetbrains.plugins.groovy.grape.GrapeRunner";
@Override
@NotNull
@@ -195,7 +196,7 @@ public class GrabDependencies implements IntentionAction {
//javaParameters.getVMParametersList().add("-Xdebug"); javaParameters.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239");
try {
- DefaultGroovyScriptRunner.configureGenericGroovyRunner(javaParameters, module, "org.jetbrains.plugins.groovy.grape.GrapeRunner", false, true);
+ DefaultGroovyScriptRunner.configureGenericGroovyRunner(javaParameters, module, GRAPE_RUNNER, false, true);
}
catch (CantRunException e) {
NOTIFICATION_GROUP.createNotification("Can't run @Grab: " + ExceptionUtil.getMessage(e), ExceptionUtil.getThrowableText(e), NotificationType.ERROR, null).notify(project);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/CompleteReferenceExpression.java
index e23b5976d3fa..91a8c6f1fac3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/CompleteReferenceExpression.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/CompleteReferenceExpression.java
@@ -43,7 +43,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
@@ -55,7 +54,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
@@ -63,7 +61,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
-import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.SubstitutorComputer;
@@ -157,14 +154,7 @@ public class CompleteReferenceExpression {
if (qualifier == null) {
ResolveUtil.treeWalkUp(myRefExpr, myProcessor, true);
- for (PsiElement e = myRefExpr.getParent(); e != null; e = e.getParent()) {
- if (e instanceof GrClosableBlock) {
- ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, e);
- for (ClosureMissingMethodContributor contributor : ClosureMissingMethodContributor.EP_NAME.getExtensions()) {
- contributor.processMembers((GrClosableBlock)e, myProcessor, myRefExpr, state);
- }
- }
- }
+ ClosureMissingMethodContributor.processMethodsFromClosures(myRefExpr, myProcessor);
GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(myRefExpr);
if (runtimeQualifier != null) {
@@ -394,7 +384,7 @@ public class CompleteReferenceExpression {
}
private boolean isMap() {
- final PsiType qType = GrReferenceResolveUtil.getQualifierType(myRefExpr);
+ final PsiType qType = PsiImplUtil.getQualifierType(myRefExpr);
return InheritanceUtil.isInheritor(qType, CommonClassNames.JAVA_UTIL_MAP);
}
@@ -436,7 +426,7 @@ public class CompleteReferenceExpression {
myFieldPointerOperator = myRefExpr.hasAt();
myMethodPointerOperator = myRefExpr.getDotTokenType() == GroovyTokenTypes.mMEMBER_POINTER;
myIsMap = isMap();
- final PsiType thisType = GrReferenceResolveUtil.getQualifierType(myRefExpr);
+ final PsiType thisType = PsiImplUtil.getQualifierType(myRefExpr);
mySubstitutorComputer = new SubstitutorComputer(thisType, PsiType.EMPTY_ARRAY, PsiType.EMPTY_ARRAY, myRefExpr, myRefExpr.getParent());
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java
index 47ebb661c960..3227ff76e01e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GdslClosureCompleter.java
@@ -26,7 +26,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
+import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -44,7 +44,7 @@ public class GdslClosureCompleter extends ClosureCompleter {
PsiElement place) {
final ArrayList<ClosureDescriptor> descriptors = new ArrayList<ClosureDescriptor>();
GrReferenceExpression ref = (GrReferenceExpression)place;
- PsiType qtype = GrReferenceResolveUtil.getQualifierType(ref);
+ PsiType qtype = PsiImplUtil.getQualifierType(ref);
if (qtype == null) return null;
GrExpression qualifier = ref.getQualifier();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java
index 9fced9dac8bd..e84361b0f57d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GrMethodMergingContributor.java
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.ResolveResult;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -32,7 +33,7 @@ import java.util.ArrayList;
*/
public class GrMethodMergingContributor extends CompletionContributor {
@Override
- public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
+ public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final CompletionParameters parameters = context.getParameters();
if (parameters.getCompletionType() != CompletionType.SMART && parameters.getCompletionType() != CompletionType.BASIC) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java
index e02f73314eb5..4c0c342030fb 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java
@@ -73,7 +73,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (!AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) {
super.fillCompletionVariants(parameters, result);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java
index 6985f16cbc31..745f353ccf5b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyNoVariantsDelegator.java
@@ -48,7 +48,7 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java
index 68d418c1f381..4b5459ff432e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovySmartCompletionContributor.java
@@ -377,7 +377,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
super.fillCompletionVariants(parameters, result);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCliCommandExecutor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCliCommandExecutor.java
new file mode 100644
index 000000000000..120c5abf189b
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCliCommandExecutor.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.mvc;
+
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/19/2014
+ */
+public class MvcCliCommandExecutor extends MvcCommandExecutor {
+ @Override
+ protected boolean isApplicable(Module module) {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ protected ConsoleProcessDescriptor doRun(@NotNull Module module,
+ @NotNull MvcFramework framework,
+ @NotNull MvcCommand mvcCommand,
+ @Nullable Runnable onDone,
+ boolean showConsole,
+ boolean closeOnDone,
+ String... input) {
+ final GeneralCommandLine commandLine = framework.createCommandAndShowErrors(null, module, mvcCommand);
+ if (commandLine == null) return null;
+ return MvcConsole.executeProcess(module, commandLine, onDone, closeOnDone, input);
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCommandExecutor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCommandExecutor.java
new file mode 100644
index 000000000000..c4c791ba0042
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcCommandExecutor.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.mvc;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 6/19/2014
+ */
+public abstract class MvcCommandExecutor {
+ private static final ExtensionPointName<MvcCommandExecutor> EP_NAME =
+ ExtensionPointName.create("org.intellij.groovy.mvc.command.executor");
+
+ @Nullable
+ public static ConsoleProcessDescriptor run(@NotNull Module module,
+ @NotNull MvcFramework framework,
+ @NotNull MvcCommand mvcCommand,
+ @Nullable Runnable onDone,
+ boolean closeOnDone,
+ String... input) {
+ return run(module, framework, mvcCommand, onDone, true, closeOnDone, input);
+ }
+
+ @Nullable
+ public static ConsoleProcessDescriptor run(@NotNull Module module,
+ @NotNull MvcFramework framework,
+ @NotNull MvcCommand mvcCommand,
+ @Nullable Runnable onDone,
+ boolean showConsole,
+ boolean closeOnDone,
+ String... input) {
+ for (MvcCommandExecutor executor : EP_NAME.getExtensions()) {
+ if (executor.isApplicable(module)) {
+ return executor.doRun(module, framework, mvcCommand, onDone, showConsole, closeOnDone, input);
+ }
+ }
+
+ // fallback to default CLI implementation
+ return new MvcCliCommandExecutor().doRun(module, framework, mvcCommand, onDone, showConsole, closeOnDone, input);
+ }
+
+ protected abstract boolean isApplicable(Module module);
+
+ @Nullable
+ protected abstract ConsoleProcessDescriptor doRun(@NotNull Module module,
+ @NotNull MvcFramework framework,
+ @NotNull MvcCommand mvcCommand,
+ @Nullable Runnable onDone,
+ boolean showConsole,
+ boolean closeOnDone,
+ String... input);
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.form
index 688fe451db4c..a86aade6a66f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.form
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.form
@@ -39,7 +39,7 @@
</constraints>
<properties/>
</component>
- <component id="d1e7d" class="javax.swing.JComboBox" binding="myModulesBox">
+ <component id="d1e7d" class="com.intellij.application.options.ModulesComboBox" binding="myModulesBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.java
index 68f6d50ae80d..d81ce98ffec6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunConfigurationEditor.java
@@ -20,13 +20,13 @@ import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBLabel;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.mvc.util.ModuleCellRenderer;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -35,8 +35,7 @@ import java.io.File;
import java.util.HashMap;
public class MvcRunConfigurationEditor<T extends MvcRunConfiguration> extends SettingsEditor<T> implements PanelWithAnchor {
- private DefaultComboBoxModel myModulesModel;
- protected JComboBox myModulesBox;
+ protected ModulesComboBox myModulesBox;
private JPanel myMainPanel;
private RawCommandLineEditor myVMParameters;
private JTextField myCommandLine;
@@ -67,11 +66,8 @@ public class MvcRunConfigurationEditor<T extends MvcRunConfiguration> extends Se
myCommandLine.setText(configuration.cmdLine);
- myModulesModel.removeAllElements();
- for (Module module : configuration.getValidModules()) {
- myModulesModel.addElement(module);
- }
- myModulesModel.setSelectedItem(configuration.getModule());
+ myModulesBox.setModules(configuration.getValidModules());
+ myModulesBox.setSelectedModule(configuration.getModule());
commandLineChanged(getCommandLine());
@@ -142,7 +138,7 @@ public class MvcRunConfigurationEditor<T extends MvcRunConfiguration> extends Se
}
protected Module getSelectedModule() {
- return (Module)myModulesBox.getSelectedItem();
+ return myModulesBox.getSelectedModule();
}
public void addExtension(JComponent component) {
@@ -152,10 +148,6 @@ public class MvcRunConfigurationEditor<T extends MvcRunConfiguration> extends Se
@Override
@NotNull
protected JComponent createEditor() {
- myModulesModel = new DefaultComboBoxModel();
- myModulesBox.setModel(myModulesModel);
- myModulesBox.setRenderer(new ModuleCellRenderer(myModulesBox.getRenderer()));
-
return myMainPanel;
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTarget.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTarget.java
index 6efc6665504e..ad856e862223 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTarget.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTarget.java
@@ -15,7 +15,6 @@
*/
package org.jetbrains.plugins.groovy.mvc;
-import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.NotNull;
@@ -34,13 +33,8 @@ public class MvcRunTarget extends MvcActionBase {
}
Module selectedModule = dialog.getSelectedModule();
-
MvcCommand cmd = MvcCommand.parse(dialog.getTargetArguments());
-
- final GeneralCommandLine commandLine = framework.createCommandAndShowErrors(dialog.getVmOptions(), selectedModule, cmd);
- if (commandLine == null) return;
-
- MvcConsole.executeProcess(selectedModule, commandLine, null, false);
+ MvcCommandExecutor.run(selectedModule, framework, cmd, null, false);
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.form
index 3d086ca296b6..cafff50f6c2a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.form
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.form
@@ -69,7 +69,7 @@
<text value="&amp;Module:"/>
</properties>
</component>
- <component id="cf36f" class="javax.swing.JComboBox" binding="myModuleBox">
+ <component id="cf36f" class="com.intellij.application.options.ModulesComboBox" binding="myModuleBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.java
index 2b629bb668a1..65c6b4be97b4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcRunTargetDialog.java
@@ -22,14 +22,17 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.*;
+import com.intellij.ui.EditorComboBoxEditor;
+import com.intellij.ui.EditorComboBoxRenderer;
+import com.intellij.ui.EditorTextField;
+import com.intellij.ui.StringComboboxEditor;
import com.intellij.util.TextFieldCompletionProvider;
import com.intellij.util.TextFieldCompletionProviderDumbAware;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.mvc.util.ModuleCellRenderer;
import org.jetbrains.plugins.groovy.mvc.util.MvcTargetDialogCompletionUtils;
import javax.swing.*;
@@ -47,7 +50,7 @@ public class MvcRunTargetDialog extends DialogWrapper {
private JLabel myTargetLabel;
private JPanel myFakePanel;
private EditorTextField myVmOptionsField;
- private JComboBox myModuleBox;
+ private ModulesComboBox myModuleBox;
private JLabel myModuleLabel;
private JLabel myVmOptionLabel;
private ComboBox myTargetField;
@@ -114,18 +117,17 @@ public class MvcRunTargetDialog extends DialogWrapper {
assert mvcModules.contains(myModule);
myModuleLabel.setLabelFor(myModuleBox);
- myModuleBox.setModel(new CollectionComboBoxModel(mvcModules, myModule));
+ myModuleBox.setModules(mvcModules);
+ myModuleBox.setSelectedModule(myModule);
myModuleBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- myModule = (Module)myModuleBox.getSelectedItem();
+ myModule = myModuleBox.getSelectedModule();
if (myInteractiveRunAction != null) {
myInteractiveRunAction.setEnabled(myFramework.isInteractiveConsoleSupported(myModule));
}
}
});
-
- myModuleBox.setRenderer(new ModuleCellRenderer(myModuleBox.getRenderer()));
}
@NotNull
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/util/ModuleCellRenderer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/util/ModuleCellRenderer.java
deleted file mode 100644
index 208de7bbcfbc..000000000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/util/ModuleCellRenderer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.mvc.util;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleType;
-import com.intellij.ui.ListCellRendererWrapper;
-
-import javax.swing.*;
-
-/**
- * @author Sergey Evdokimov
- */
-public class ModuleCellRenderer extends ListCellRendererWrapper<Module> {
- public ModuleCellRenderer(ListCellRenderer renderer) {
- super();
- }
-
- @Override
- public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) {
- if (module != null) {
- setIcon(ModuleType.get(module).getIcon());
- setText(module.getName());
- }
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
index 615a2dac667a..aceef3c34b84 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
@@ -69,7 +69,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
@@ -447,7 +446,7 @@ public class ExpressionGenerator extends Generator {
else if (resolved == null || resolved instanceof GrBindingVariable) {
//write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value)
final GrExpression qualifier = ((GrReferenceExpression)realLValue).getQualifier();
- final PsiType type = GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)realLValue);
+ final PsiType type = PsiImplUtil.getQualifierType((GrReferenceExpression)realLValue);
final GrExpression[] args = {
factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""),
@@ -952,7 +951,7 @@ public class ExpressionGenerator extends Generator {
return;
}
- if (GrReferenceResolveUtil.isClassReference(referenceExpression)) {
+ if (ResolveUtil.isClassReference(referenceExpression)) {
LOG.assertTrue(qualifier != null);
qualifier.accept(this);
builder.append(".class");
@@ -1052,7 +1051,7 @@ public class ExpressionGenerator extends Generator {
}
else {
PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
- PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(referenceExpression);
+ PsiType qualifierType = PsiImplUtil.getQualifierType(referenceExpression);
GroovyResolveResult[] candidates = qualifierType != null
? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression,
stringType)
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameAliasImportedFieldProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameAliasImportedFieldProcessor.java
deleted file mode 100644
index 3cd416459bd3..000000000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameAliasImportedFieldProcessor.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.plugins.groovy.refactoring.rename;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiReference;
-import com.intellij.refactoring.rename.RenameJavaVariableProcessor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
-
-import java.util.Collection;
-
-/**
- * @author Maxim.Medvedev
- */
-public class RenameAliasImportedFieldProcessor extends RenameJavaVariableProcessor{
- @Override
- public boolean canProcessElement(@NotNull PsiElement element) {
- return element instanceof GrField && !((GrField)element).isProperty();
- }
-
- @NotNull
- @Override
- public Collection<PsiReference> findReferences(PsiElement element) {
- return RenameAliasedUsagesUtil.filterAliasedRefs(super.findReferences(element), element);
- }
-}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameGrFieldProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameGrFieldProcessor.java
index 8bccb8073874..9e90ac2326a0 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameGrFieldProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/rename/RenameGrFieldProcessor.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.refactoring.rename;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
@@ -30,8 +31,8 @@ import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
-import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
@@ -40,6 +41,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrTraitField;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -56,6 +59,8 @@ import java.util.Map;
*/
public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
+ private static final Logger LOG = Logger.getInstance(RenameGrFieldProcessor.class);
+
@NotNull
@Override
public Collection<PsiReference> findReferences(PsiElement element) {
@@ -84,16 +89,8 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
@Nullable RefactoringElementListener listener) throws IncorrectOperationException {
final GrField field = (GrField)psiElement;
String fieldName = field.getName();
- Map<PsiElement, String> renames = new HashMap<PsiElement, String>();
- renames.put(field, newName);
- for (GrAccessorMethod getter : field.getGetters()) {
- renames.put(getter, RenamePropertyUtil.getGetterNameByOldName(newName, getter.getName()));
- }
- final GrAccessorMethod setter = field.getSetter();
- if (setter != null) {
- renames.put(setter, GroovyPropertyUtils.getSetterName(newName));
- }
+ NameProvider nameProvider = new NameProvider(field, newName);
MultiMap<PsiNamedElement, UsageInfo> propertyUsages = MultiMap.createLinked();
MultiMap<PsiNamedElement, UsageInfo> simpleUsages = MultiMap.createLinked();
@@ -106,12 +103,7 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
final GroovyResolveResult resolveResult = ((GrReferenceExpression)ref).advancedResolve();
final PsiElement element = resolveResult.getElement();
if (resolveResult.isInvokedOnProperty()) {
- if (element == null) {
- unknownUsages.add(ref);
- }
- else {
- propertyUsages.putValue((PsiNamedElement)element, usage);
- }
+ propertyUsages.putValue((PsiNamedElement)element, usage);
}
else {
simpleUsages.putValue((PsiNamedElement)element, usage);
@@ -128,22 +120,13 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
field.setName(newName);
- final GrAccessorMethod[] newGetters = field.getGetters();
- final GrAccessorMethod newSetter = field.getSetter();
- Map<String, PsiNamedElement> newElements = new HashMap<String, PsiNamedElement>();
- newElements.put(newName, field);
- for (GrAccessorMethod newGetter : newGetters) {
- newElements.put(newGetter.getName(), newGetter);
- }
- if (newSetter != null) {
- newElements.put(newSetter.getName(), newSetter);
- }
+ nameProvider.putNewElements(field);
PsiManager manager = field.getManager();
for (PsiNamedElement element : simpleUsages.keySet()) {
for (UsageInfo info : simpleUsages.get(element)) {
- final String name = renames.get(element);
- rename(newElements.get(name), info, name == null ? newName : name, name != null, manager);
+ final String name = nameProvider.getNewName(element);
+ rename(nameProvider.getNewElement(element), info, name == null ? newName : name, name != null, manager);
}
}
for (PsiNamedElement element : propertyUsages.keySet()) {
@@ -156,6 +139,72 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
}
}
+ private static class NameProvider {
+
+ private final Map<PsiElement, String> myNameMap = ContainerUtil.newHashMap();
+ private final Map<String, PsiNamedElement> myNewElements = ContainerUtil.newHashMap();
+
+
+ public NameProvider(GrField field, String newName) {
+ myNameMap.put(field, newName);
+
+ if (field.isProperty()) {
+ for (GrAccessorMethod getter : field.getGetters()) {
+ myNameMap.put(getter, RenamePropertyUtil.getGetterNameByOldName(newName, getter.getName()));
+ }
+ final GrAccessorMethod setter = field.getSetter();
+ if (setter != null) {
+ myNameMap.put(setter, GroovyPropertyUtils.getSetterName(newName));
+ }
+ }
+ }
+
+ String getNewName(@NotNull PsiElement element) {
+ String name = myNameMap.get(element);
+ if (name != null) {
+ return name;
+ }
+
+ if (element instanceof GrTraitField) {
+ PsiField prototype = ((GrTraitField)element).getPrototype();
+ String newPrototypeName = getNewName(prototype);
+ return GrTraitUtil.getTraitFieldPrefix(prototype.getContainingClass()) + newPrototypeName;
+ }
+
+ return null;
+ }
+
+ public void putNewElements(@NotNull GrField field) {
+ myNewElements.put(field.getName(), field);
+
+ if (field.isProperty()) {
+ for (GrAccessorMethod newGetter : field.getGetters()) {
+ myNewElements.put(newGetter.getName(), newGetter);
+ }
+
+ final GrAccessorMethod newSetter = field.getSetter();
+ if (newSetter != null) {
+ myNewElements.put(newSetter.getName(), newSetter);
+ }
+ }
+ }
+
+ public PsiNamedElement getNewElement(PsiNamedElement element) {
+ String newName = getNewName(element);
+ PsiNamedElement newElement = myNewElements.get(newName);
+ if (newElement != null) {
+ return newElement;
+ }
+
+ if (element instanceof GrTraitField) {
+ PsiField prototype = ((GrTraitField)element).getPrototype();
+ return getNewElement(prototype);
+ }
+
+ return null;
+ }
+ }
+
private static void rename(PsiNamedElement element,
UsageInfo info,
String nameToUse,
@@ -241,7 +290,7 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
@Override
public boolean canProcessElement(@NotNull final PsiElement element) {
- return element instanceof GrField && ((GrField)element).isProperty() || element instanceof GrAccessorMethod;
+ return element instanceof GrField /*&& ((GrField)element).isProperty()*/ || element instanceof GrAccessorMethod;
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
index 7676de9fdc3d..90e4131f1ef9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java
@@ -37,6 +37,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.groovy.GroovycOSProcessHandler;
import org.jetbrains.plugins.groovy.config.GroovyFacetUtil;
+import org.jetbrains.plugins.groovy.grape.GrabDependencies;
import org.jetbrains.plugins.groovy.util.LibrariesUtil;
import java.nio.charset.Charset;
@@ -118,7 +119,9 @@ public class DefaultGroovyScriptRunner extends GroovyScriptRunner {
params.getProgramParametersList().add("--main");
params.getProgramParametersList().add(mainClass);
- addClasspathFromRootModel(module, tests, params, true);
+ if (!GrabDependencies.GRAPE_RUNNER.equals(mainClass)) {
+ addClasspathFromRootModel(module, tests, params, true);
+ }
if (params.getVMParametersList().getPropertyValue(GroovycOSProcessHandler.GRAPE_ROOT) == null) {
String sysRoot = System.getProperty(GroovycOSProcessHandler.GRAPE_ROOT);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.form
index 31e26e527258..a5ffd20bd1d2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.form
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.form
@@ -74,7 +74,7 @@
<text value="Module:"/>
</properties>
</component>
- <component id="d1e7d" class="javax.swing.JComboBox" binding="myModulesBox">
+ <component id="d1e7d" class="com.intellij.application.options.ModulesComboBox" binding="myModulesBox">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.java
index 46a0d0389f49..e41164f7442d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyRunConfigurationEditor.java
@@ -19,26 +19,22 @@ package org.jetbrains.plugins.groovy.runner;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.ide.util.BrowseFilesListener;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
-import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.*;
+import com.intellij.ui.FieldPanel;
+import com.intellij.ui.PanelWithAnchor;
+import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBLabel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyFileType;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRunConfiguration> implements PanelWithAnchor {
- private DefaultComboBoxModel myModulesModel;
- private JComboBox myModulesBox;
+ private ModulesComboBox myModulesBox;
private JPanel myMainPanel;
private RawCommandLineEditor myVMParameters;
private RawCommandLineEditor myParameters;
@@ -93,20 +89,15 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
myDebugCB.setEnabled(true);
myDebugCB.setSelected(configuration.isDebugEnabled());
- myModulesModel.removeAllElements();
- List<Module> modules = new ArrayList<Module>(configuration.getValidModules());
- Collections.sort(modules, ModulesAlphaComparator.INSTANCE);
- for (Module module : modules) {
- myModulesModel.addElement(module);
- }
- myModulesModel.setSelectedItem(configuration.getModule());
+ myModulesBox.setModules(configuration.getValidModules());
+ myModulesBox.setSelectedModule(configuration.getModule());
myEnvVariables.setEnvs(configuration.getEnvs());
}
@Override
public void applyEditorTo(GroovyScriptRunConfiguration configuration) throws ConfigurationException {
- configuration.setModule((Module) myModulesBox.getSelectedItem());
+ configuration.setModule(myModulesBox.getSelectedModule());
configuration.setVMParameters(myVMParameters.getText());
configuration.setDebugEnabled(myDebugCB.isSelected());
configuration.setScriptParameters(myParameters.getText());
@@ -118,27 +109,8 @@ public class GroovyRunConfigurationEditor extends SettingsEditor<GroovyScriptRun
@Override
@NotNull
public JComponent createEditor() {
- myModulesModel = new DefaultComboBoxModel();
- myModulesBox.setModel(myModulesModel);
myDebugCB.setEnabled(true);
myDebugCB.setSelected(false);
-
- myModulesBox.setRenderer(new ListCellRendererWrapper<Module>() {
- @Override
- public void customize(JList list, Module module, int index, boolean selected, boolean hasFocus) {
- if (module != null) {
- setIcon(ModuleType.get(module).getIcon());
- setText(module.getName());
- }
- }
- });
- new ComboboxSpeedSearch(myModulesBox) {
- @Override
- protected String getElementText(Object element) {
- return element instanceof Module ? ((Module)element).getName() : "";
- }
- };
-
return myMainPanel;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunner.java
index f4457d9bc8c2..743895151093 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunner.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunner.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -32,6 +32,7 @@ import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyLanguage;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import java.io.File;
@@ -66,7 +67,7 @@ public abstract class GroovyScriptRunner {
public static String getPathInConf(String fileName) {
try {
- final String jarPath = PathUtil.getJarPathForClass(GroovyScriptRunner.class);
+ final String jarPath = PathUtil.getJarPathForClass(GroovyLanguage.class);
if (new File(jarPath).isFile()) { //jar; distribution mode
return new File(jarPath, "../" + fileName).getCanonicalPath();
}
diff --git a/plugins/groovy/structuralsearch-groovy/src/com/intellij/structuralsearch/GroovyStructuralSearchProfile.java b/plugins/groovy/structuralsearch-groovy/src/com/intellij/structuralsearch/GroovyStructuralSearchProfile.java
new file mode 100644
index 000000000000..5638715b3d38
--- /dev/null
+++ b/plugins/groovy/structuralsearch-groovy/src/com/intellij/structuralsearch/GroovyStructuralSearchProfile.java
@@ -0,0 +1,85 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.template.GroovyTemplateContextType;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class GroovyStructuralSearchProfile extends StructuralSearchProfileBase {
+ public static final String FILE_CONTEXT = "File";
+ public static final String CLASS_CONTEXT = "Class";
+
+ private static final TokenSet VARIABLE_DELIMETERS = TokenSet.create(GroovyTokenTypes.mCOMMA, GroovyTokenTypes.mSEMI);
+
+ @NotNull
+ @Override
+ protected String[] getVarPrefixes() {
+ return new String[]{"_$_____"};
+ }
+
+ @NotNull
+ @Override
+ public String[] getContextNames() {
+ return new String[]{FILE_CONTEXT, CLASS_CONTEXT};
+ }
+
+ @NotNull
+ @Override
+ protected LanguageFileType getFileType() {
+ return GroovyFileType.GROOVY_FILE_TYPE;
+ }
+
+ @NotNull
+ @Override
+ protected TokenSet getVariableDelimiters() {
+ return VARIABLE_DELIMETERS;
+ }
+
+ @Override
+ public PsiCodeFragment createCodeFragment(Project project, String text, @Nullable PsiElement context) {
+ GroovyCodeFragment result = new GroovyCodeFragment(project, text);
+ result.setContext(context);
+ return result;
+ }
+
+ @Override
+ public Class<? extends TemplateContextType> getTemplateContextTypeClass() {
+ return GroovyTemplateContextType.class;
+ }
+
+ @Override
+ public String getContext(@NotNull String pattern, @Nullable Language language, String contextName) {
+ return CLASS_CONTEXT.equals(contextName)
+ ? "class AAAAA { " + PATTERN_PLACEHOLDER + " }"
+ : PATTERN_PLACEHOLDER;
+ }
+
+ @Override
+ public Class getElementContextByPsi(PsiElement element) {
+ if (element instanceof PsiIdentifier) {
+ element = element.getParent();
+ }
+
+ if (element instanceof PsiMember) {
+ return PsiMember.class;
+ } else {
+ return PsiExpression.class;
+ }
+ }
+
+ @Override
+ public boolean isIdentifier(PsiElement element) {
+ return element instanceof PsiIdentifier;
+ }
+}
diff --git a/plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml b/plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml
new file mode 100644
index 000000000000..dbde3887908d
--- /dev/null
+++ b/plugins/groovy/structuralsearch-groovy/structuralsearch-groovy.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="structuralsearch" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="jetgroovy" />
+ <orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="structuralsearch-tests" scope="TEST" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ <orderEntry type="module" module-name="duplicates-analysis" scope="TEST" />
+ </component>
+</module>
+
diff --git a/plugins/groovy/structuralsearch-groovy/testSrc/com/intellij/structuralsearch/GroovyStructuralSearchTest.java b/plugins/groovy/structuralsearch-groovy/testSrc/com/intellij/structuralsearch/GroovyStructuralSearchTest.java
new file mode 100644
index 000000000000..8990fba2716e
--- /dev/null
+++ b/plugins/groovy/structuralsearch-groovy/testSrc/com/intellij/structuralsearch/GroovyStructuralSearchTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.structuralsearch;
+
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
+import com.intellij.idea.Bombed;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+@Bombed(day = 14, month = Calendar.JULY)
+public class GroovyStructuralSearchTest extends StructuralSearchTestCase {
+
+ public void test1() throws Exception {
+ String s = "def int x = 0;\n" +
+ "def y = 0;\n" +
+ "int z = 10;\n" +
+ "def int x1";
+
+ doTest(s, "def $x$ = $value$;", 3, 1);
+ doTest(s, "def $x$", 4, 3);
+ doTest(s, "int $x$", 3, 3);
+ doTest(s, "def $x$ = $value$", 3, 1);
+ doTest(s, "def $x$ = 0", 2, 1);
+ doTest(s, "int $x$ = 0", 1, 1);
+ doTest(s, "int $x$ = $value$", 2, 2);
+ }
+
+ public void test2() throws Exception {
+ String s = "def void f(int x) {}\n" +
+ "def f(int x) {\n" +
+ " System.out.println(\"hello\");\n" +
+ "}\n" +
+ "def f(def x) {}\n" +
+ "void g(x) {}\n" +
+ "public def void f(def int y) {\n" +
+ " System.out.println(\"hello\");\n" +
+ "}\n" +
+ "def int f() {}";
+
+ doTest(s, "def $f$($param$)", 5, 2);
+ doTest(s, "def $f$($param$) {}", 3, 1);
+ doTest(s, "void $f$($param$) {}", 2, 2);
+ doTest(s, "void $f$(def x)", 2, 0);
+ doTest(s, "def $f$(def x)", 4, 1);
+ doTest(s, "void $f$(def $x$)", 3, 0);
+ doTest(s, "void $f$(int $x$)", 2, 2);
+ doTest(s, "def $f$(int $x$)", 3, 1);
+ doTest(s, "def g($param$)", 1, 0);
+ doTest(s, "def '_T1('_T2*)", 6, 2);
+
+ // a problem with default eq is that ; is not part of statement
+ doTest(s, "def '_T1('_T2*) {'_T3+}", 2, 0);
+ doTest(s, "def '_T1('_T2*) {'_T3*}", 6, 1);
+ }
+
+ public void test3() throws Exception {
+ String s = "public class C implements I1, I2 {\n" +
+ " void f() {\n" +
+ " def a = 1;\n" +
+ " def int b = 2;\n" +
+ " }\n" +
+ "}";
+
+ doTest(s, "class $name$", 1, 1);
+ doTest(s, "class $name$ implements I1, I2", 1, 1);
+ doTest(s, "class $name$ implements $interface$", 1, 0);
+ doTest(s, "class '_T1 implements '_T2*", 1, 1);
+ doTest(s, "class '_T1 implements '_T2+", 1, 1);
+ doTest(s, "class $name$ implements I2, I1", 1, 0);
+ doTest(s, "class C implements I1, I2 {}", 1, 0);
+ doTest(s, "def a = 1;\n def b = 2;", 1, 0);
+ doTest(s, "def a = 1\n def b = 2", 1, 0);
+ }
+
+ public void test4() throws Exception {
+ String s = "for (a in list) {\n" +
+ " println(\"hello1\");\n" +
+ " println(\"hello2\");\n" +
+ "}";
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " $st1$;\n" +
+ " $st2$\n" +
+ "}", 1, 0);
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " $st1$;\n" +
+ " $st2$;\n" +
+ "}", 1, 1);
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " $st1$\n" +
+ " $st2$\n" +
+ "}", 1, 0);
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " $st$\n" +
+ "}", 0, 0);
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " '_T*\n" +
+ "}", 1, 0);
+ doTest(s, "for ($a$ in $b$) {\n" +
+ " '_T+\n" +
+ "}", 1, 0);
+ }
+
+ public void test5() {
+ String s = "class A {\n" +
+ " def f = {\n" +
+ " println('Hello1')\n" +
+ " println('Hello2')\n" +
+ " }\n" +
+ " def f1 = {\n" +
+ " println('Hello')\n" +
+ " }\n" +
+ "}";
+ doTest(s, "def $name$ = {\n" +
+ " '_T+\n" +
+ "}", 0, 0);
+ final String old = options.getPatternContext();
+ try {
+ options.setPatternContext(GroovyStructuralSearchProfile.CLASS_CONTEXT);
+ doTest(s, "def $name$ = {\n" +
+ " '_T+\n" +
+ "}", 2, 2);
+ }
+ finally {
+ options.setPatternContext(old);
+ }
+ }
+
+ private void doTest(String source,
+ String pattern,
+ int expectedOccurences,
+ int expectedWithDefaultEquivalence) {
+ findAndCheck(source, pattern, expectedOccurences);
+ try {
+ EquivalenceDescriptorProvider.ourUseDefaultEquivalence = true;
+ findAndCheck(source, pattern, expectedWithDefaultEquivalence);
+ }
+ finally {
+ EquivalenceDescriptorProvider.ourUseDefaultEquivalence = false;
+ }
+ }
+
+ private void findAndCheck(String source, String pattern, int expectedOccurences) {
+ testMatcher.clearContext();
+ final List<MatchResult> matches =
+ findMatches(source, pattern, true, GroovyFileType.GROOVY_FILE_TYPE, null, GroovyFileType.GROOVY_FILE_TYPE, null, false);
+ assertEquals(expectedOccurences, matches.size());
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy
index 84e09567aee4..022f775dcf7f 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +25,7 @@ import com.intellij.debugger.engine.evaluation.CodeFragmentKind
import com.intellij.debugger.engine.evaluation.EvaluateException
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
+import com.intellij.debugger.engine.events.DebuggerCommandImpl
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl
import com.intellij.debugger.impl.DebuggerContextUtil
import com.intellij.debugger.impl.DebuggerManagerImpl
@@ -37,6 +38,7 @@ import com.intellij.execution.executors.DefaultDebugExecutor
import com.intellij.execution.process.OSProcessHandler
import com.intellij.execution.process.OSProcessManager
import com.intellij.execution.process.ProcessAdapter
+import com.intellij.execution.process.ProcessEvent
import com.intellij.execution.runners.ProgramRunner
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
@@ -52,11 +54,14 @@ import com.intellij.testFramework.builders.JavaModuleFixtureBuilder
import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl
import com.intellij.util.SystemProperties
import com.intellij.util.concurrency.Semaphore
+import org.jetbrains.annotations.NotNull
/**
* @author peter
*/
class GroovyDebuggerTest extends GroovyCompilerTestCase {
+ private static final int ourTimeout = 60000
+
@Override
protected void setUp() {
edt {
@@ -72,7 +77,7 @@ class GroovyDebuggerTest extends GroovyCompilerTestCase {
}
@Override
- protected void invokeTestRunnable(Runnable runnable) {
+ protected void invokeTestRunnable(@NotNull Runnable runnable) {
runnable.run()
}
@@ -95,7 +100,7 @@ class GroovyDebuggerTest extends GroovyCompilerTestCase {
make()
edt {
ProgramRunner runner = ProgramRunner.PROGRAM_RUNNER_EP.extensions.find { it.class == GenericDebuggerRunner }
- def listener = [onTextAvailable: { evt, type -> }] as ProcessAdapter
+ def listener = [onTextAvailable: { ProcessEvent evt, type -> /*println evt.text*/}] as ProcessAdapter
runConfiguration(DefaultDebugExecutor, listener, runner, configuration);
}
try {
@@ -104,7 +109,7 @@ class GroovyDebuggerTest extends GroovyCompilerTestCase {
finally {
def handler = debugProcess.executionResult.processHandler
resume()
- if (!handler.waitFor(20000)) {
+ if (!handler.waitFor(ourTimeout)) {
if (handler instanceof OSProcessHandler) {
OSProcessManager.instance.killProcessTree(handler.process)
} else {
@@ -338,7 +343,7 @@ foo()
}
}
- public void "test navigation to script outside source root"() {
+ public void "test_navigation_outside_source"() {
def module1 = addModule("module1", false)
def module2 = addModule("module2", true)
addGroovyLibrary(module1)
@@ -405,10 +410,22 @@ public static void main(String[] args) {
}
private def resume() {
- debugProcess.managerThread.invokeAndWait(debugProcess.createResumeCommand(debugProcess.suspendManager.pausedContext))
+ debugProcess.managerThread.invoke(debugProcess.createResumeCommand(debugProcess.suspendManager.pausedContext))
}
private SuspendContextImpl waitForBreakpoint() {
+ Semaphore semaphore = new Semaphore()
+ semaphore.down()
+ // wait for all events processed
+ debugProcess.managerThread.schedule(new DebuggerCommandImpl() {
+ @Override
+ protected void action() throws Exception {
+ semaphore.up();
+ }
+ });
+ def finished = semaphore.waitFor(ourTimeout);
+ assert finished : 'Too long debugger actions'
+
int i = 0
def suspendManager = debugProcess.suspendManager
while (i++ < 1000 && !suspendManager.pausedContext && !debugProcess.executionResult.processHandler.processTerminated) {
@@ -433,11 +450,15 @@ public static void main(String[] args) {
def ctx = DebuggerContextUtil.createDebuggerContext(debugSession, debugProcess.suspendManager.pausedContext)
Semaphore semaphore = new Semaphore()
semaphore.down()
- debugProcess.managerThread.invokeAndWait(new DebuggerContextCommandImpl(ctx) {
+ debugProcess.managerThread.invoke(new DebuggerContextCommandImpl(ctx) {
@Override
void threadAction() {
- result = cl()
- semaphore.up()
+ try {
+ result = cl()
+ }
+ finally {
+ semaphore.up()
+ }
}
@Override
@@ -445,7 +466,7 @@ public static void main(String[] args) {
println DebugUtil.currentStackTrace()
}
})
- def finished = semaphore.waitFor(20000)
+ def finished = semaphore.waitFor(ourTimeout)
assert finished : 'Too long debugger action'
return result
}
@@ -462,7 +483,7 @@ public static void main(String[] args) {
item.updateRepresentation(ctx, { } as DescriptorLabelListener)
semaphore.up()
}
- assert semaphore.waitFor(10000): "too long evaluation: $item.label $item.evaluateException"
+ assert semaphore.waitFor(ourTimeout): "too long evaluation: $item.label $item.evaluateException"
String result = managed { DebuggerUtils.getValueAsString(ctx, item.value) }
assert result == expected
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/ClashingTraitMethodsQuickFixTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/ClashingTraitMethodsQuickFixTest.groovy
index 63839085f468..0871016ff7ac 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/ClashingTraitMethodsQuickFixTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/ClashingTraitMethodsQuickFixTest.groovy
@@ -14,15 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.highlighting
-
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle
import org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingTraitMethodsInspection
-import org.jetbrains.plugins.groovy.intentions.GrIntentionTestCase
-
/**
* Created by Max Medvedev on 09/06/14
*/
-class ClashingTraitMethodsQuickFixTest extends GrIntentionTestCase {
+class ClashingTraitMethodsQuickFixTest /*extends GrIntentionTestCase*/ {
ClashingTraitMethodsQuickFixTest() {
super(GroovyInspectionBundle.message("declare.explicit.implementations.of.trait"), ClashingTraitMethodsInspection)
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy
index 485f91eaeeac..24cde2e72fe8 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy
@@ -393,6 +393,89 @@ class foo {
assertInstanceOf(resolved, PsiMethod)
}
+ void testSuperInTrait1() {
+ def clazz = resolveByText('''
+trait T1 {
+ void on() {
+ println "T1"
+ }
+}
+
+trait T2 {
+ void on() {
+ println "T2"
+ }
+}
+
+trait LoggingHandler extends T1 implements T2 {
+ void on() {
+ super.o<caret>n()
+ }
+}
+''', PsiMethod).containingClass
+
+ assertEquals("T1", clazz.qualifiedName)
+ }
+
+ void testSuperInTrait2() {
+ def clazz = resolveByText('''
+trait T1 {
+ void on() {
+ println "T1"
+ }
+}
+
+trait T2 {
+ void on() {
+ println "T2"
+ }
+}
+
+trait LoggingHandler implements T1, T2 {
+ void on() {
+ super.o<caret>n()
+ }
+}
+''', PsiMethod).containingClass
+
+ assertEquals("T2", clazz.qualifiedName)
+ }
+
+ void testSuperInTrait3() {
+ def clazz = resolveByText('''
+trait T1 {
+ void on() {
+ println "T1"
+ }
+}
+
+trait LoggingHandler extends T1 {
+ void on() {
+ super.o<caret>n()
+ }
+}
+''', PsiMethod).containingClass
+
+ assertEquals("T1", clazz.qualifiedName)
+ }
+
+ void testSuperInTrait4() {
+ def clazz = resolveByText('''
+trait T1 {
+ void on() {
+ println "T1"
+ }
+}
+
+trait LoggingHandler implements T1 {
+ void on() {
+ super.o<caret>n()
+ }
+}
+''', PsiMethod).containingClass
+
+ assertEquals("T1", clazz.qualifiedName)
+ }
private void doTest(String fileName = getTestName(false) + ".groovy") { resolve(fileName, PsiClass) }
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy
index bfc029ec64d8..f975807bffb1 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolvePropertyTest.groovy
@@ -1335,7 +1335,7 @@ trait T {
public int field = 4
}
-class C extends T {
+class C implements T {
void foo() {
print T__fie<caret>ld
@@ -1374,7 +1374,7 @@ trait T {
public int field = 4
}
-class C extends T {}
+class C implements T {}
new C().T__fiel<caret>d
''', GrField)
@@ -1445,4 +1445,31 @@ def v = new B() as A
print v.A<caret>__foo
''', GrField)
}
+
+ void testTraitField1() {
+ resolveByText('''
+ trait T {
+ public foo = 4
+ }
+
+ class X implements T{
+ def bar() {
+ print fo<caret>o
+ }
+ }
+''', null)
+ }
+
+ void testTraitField2() {
+ resolveByText('''
+ trait T {
+ public foo
+
+ def bar() {
+ print fo<caret>o
+ }
+ }
+''', PsiField)
+ }
+
} \ No newline at end of file
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy
index 40173b3ee230..92cb22802c6c 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy
@@ -352,7 +352,7 @@ def foo(Integer a) {
<caret>a.substring(2)
}
}
-''', '[java.lang.String,java.lang.Integer]')
+''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod2() {
@@ -363,7 +363,7 @@ def foo(Integer a) {
bar(a)
<caret>a.substring(2)
}
-''', '[java.lang.String,java.lang.Integer]')
+''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod3() {
@@ -375,7 +375,7 @@ def foo(Integer a) {
print a
<caret>a.substring(2)
}
-''', '[java.lang.String,java.lang.Integer]')
+''', '[java.lang.Integer,java.lang.String]')
}
void testInferArgumentTypeFromMethod4() {
@@ -389,7 +389,7 @@ def foo(Integer a) {
<caret>a.substring(2)
}
}
-''', '[java.lang.String,java.lang.Integer]')
+''', '[java.lang.Integer,java.lang.String]')
}
void testEmptyListOrListWithGenerics() {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy
index e1a39a1b68b1..c6146d6214a0 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy
@@ -707,4 +707,52 @@ print new Abcd()
''')
}
}
+
+ void testTraitField() {
+ myFixture.with {
+ configureByText('a.groovy', '''\
+trait T {
+ public int f<caret>oo = 5
+
+ def bar() {
+ print foo
+ }
+}
+
+class X implements T {
+ def bar() {
+ print T__foo
+ }
+}
+
+trait T2 extends T {
+ def bar() {
+ print T__foo //actually this ref is unresolved since super fields are not visible in extending traits
+ }
+}
+''')
+ renameElementAtCaret("baz")
+ checkResult('''\
+trait T {
+ public int baz = 5
+
+ def bar() {
+ print baz
+ }
+}
+
+class X implements T {
+ def bar() {
+ print T__baz
+ }
+}
+
+trait T2 extends T {
+ def bar() {
+ print T__foo //actually this ref is unresolved since super fields are not visible in extending traits
+ }
+}
+''')
+ }
+ }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
index 9a94824e2dcf..14f6c981777b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
@@ -14,6 +14,7 @@ package org.zmlx.hg4idea.execution;
import com.intellij.ide.passwordSafe.PasswordSafe;
import com.intellij.ide.passwordSafe.PasswordSafeException;
+import com.intellij.ide.passwordSafe.config.PasswordSafeSettings;
import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -35,7 +36,7 @@ class HgCommandAuthenticator {
private static final Logger LOG = Logger.getInstance(HgCommandAuthenticator.class.getName());
- private GetPasswordRunnable myRunnable;
+ private GetPasswordRunnable myGetPassword;
private final Project myProject;
private boolean myForceAuthorization;
@@ -45,24 +46,23 @@ class HgCommandAuthenticator {
}
public void saveCredentials() {
- if (myRunnable == null) return;
+ if (myGetPassword == null) return;
// if checkbox is selected, save on disk. Otherwise in memory. Don't read password safe settings.
final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
- final String url = VirtualFileManager.extractPath(myRunnable.getURL());
- final String key = keyForUrlAndLogin(url, myRunnable.getUserName());
-
+ final String url = VirtualFileManager.extractPath(myGetPassword.getURL());
+ final String key = keyForUrlAndLogin(url, myGetPassword.getUserName());
try {
- if (myRunnable.isRememberPassword()) {
- //save password to memory, despite of settings-> passwords
- //todo should be reworked
- passwordSafe.getMemoryProvider().storePassword(myProject, HgCommandAuthenticator.class, key, myRunnable.getPassword());
+ if (myGetPassword.isRememberPassword()) {
+ PasswordSafe.getInstance().storePassword(myProject, HgCommandAuthenticator.class, key, myGetPassword.getPassword());
+ }
+ else if (passwordSafe.getSettings().getProviderType() != PasswordSafeSettings.ProviderType.DO_NOT_STORE) {
+ passwordSafe.getMemoryProvider().storePassword(myProject, HgCommandAuthenticator.class, key, myGetPassword.getPassword());
}
- passwordSafe.storePassword(myProject, HgCommandAuthenticator.class, key, myRunnable.getPassword());
final HgVcs vcs = HgVcs.getInstance(myProject);
if (vcs != null) {
- vcs.getGlobalSettings().addRememberedUrl(url, myRunnable.getUserName());
+ vcs.getGlobalSettings().addRememberedUrl(url, myGetPassword.getUserName());
}
}
catch (PasswordSafeException e) {
@@ -73,16 +73,16 @@ class HgCommandAuthenticator {
public boolean promptForAuthentication(Project project, String proposedLogin, String uri, String path, @Nullable ModalityState state) {
GetPasswordRunnable runnable = new GetPasswordRunnable(project, proposedLogin, uri, path, myForceAuthorization);
ApplicationManager.getApplication().invokeAndWait(runnable, state == null ? ModalityState.defaultModalityState() : state);
- myRunnable = runnable;
+ myGetPassword = runnable;
return runnable.isOk();
}
public String getUserName() {
- return myRunnable.getUserName();
+ return myGetPassword.getUserName();
}
public String getPassword() {
- return myRunnable.getPassword();
+ return myGetPassword.getPassword();
}
private static class GetPasswordRunnable implements Runnable {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index e215d3d8c644..03c98621a8c2 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -38,6 +38,7 @@ import org.zmlx.hg4idea.util.HgUtil;
import java.text.SimpleDateFormat;
import java.util.*;
+import static org.zmlx.hg4idea.util.HgUtil.HEAD_REFERENCE;
import static org.zmlx.hg4idea.util.HgUtil.TIP_REFERENCE;
public class HgLogProvider implements VcsLogProvider {
@@ -118,7 +119,11 @@ public class HgLogProvider implements VcsLogProvider {
}
String currentRevision = repository.getCurrentRevision();
if (currentRevision != null) { // null => fresh repository
- refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), TIP_REFERENCE, HgRefManager.HEAD, root));
+ refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), HEAD_REFERENCE, HgRefManager.HEAD, root));
+ }
+ String tipRevision = repository.getTipRevision();
+ if (tipRevision != null) { // null => fresh repository
+ refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(tipRevision), TIP_REFERENCE, HgRefManager.TIP, root));
}
for (HgNameWithHashInfo tagInfo : tags) {
refs.add(myVcsObjectsFactory.createRef(tagInfo.getHash(), tagInfo.getName(), HgRefManager.TAG, root));
@@ -175,6 +180,12 @@ public class HgLogProvider implements VcsLogProvider {
filterParameters.add(prepareParameter("branch", branchName));
atLeastOneBranchExists = true;
}
+ else if (branchName.equals(HEAD_REFERENCE)) {
+ filterParameters.add(prepareParameter("branch", "."));
+ filterParameters.add("-r");
+ filterParameters.add("::."); //all ancestors for current revision;
+ atLeastOneBranchExists = true;
+ }
}
if (!atLeastOneBranchExists) { // no such branches => filter matches nothing
return Collections.emptyList();
@@ -190,18 +201,19 @@ public class HgLogProvider implements VcsLogProvider {
if (filterCollection.getDateFilter() != null) {
StringBuilder args = new StringBuilder();
final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
- filterParameters.add("-r");
+ filterParameters.add("-d");
VcsLogDateFilter filter = filterCollection.getDateFilter();
if (filter.getAfter() != null) {
- args.append("date('>").append(dateFormatter.format(filter.getAfter())).append("')");
- }
-
- if (filter.getBefore() != null) {
- if (args.length() > 0) {
- args.append(" and ");
+ if (filter.getBefore() != null) {
+ args.append(dateFormatter.format(filter.getAfter())).append(" to ").append(dateFormatter.format(filter.getBefore()));
+ }
+ else {
+ args.append('>').append(dateFormatter.format(filter.getAfter()));
}
+ }
- args.append("date('<").append(dateFormatter.format(filter.getBefore())).append("')");
+ else if (filter.getBefore() != null) {
+ args.append('<').append(dateFormatter.format(filter.getBefore()));
}
filterParameters.add(args.toString());
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgRefManager.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgRefManager.java
index f1df227dce61..9fa266e560a1 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgRefManager.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgRefManager.java
@@ -29,18 +29,17 @@ import java.awt.*;
import java.util.*;
import java.util.List;
-/**
- * @author Nadya Zabrodina
- */
public class HgRefManager implements VcsLogRefManager {
- private static final Color HEAD_COLOR = new JBColor(new Color(0xf1ef9e), new Color(113, 111, 64));
+ private static final Color TIP_COLOR = new JBColor(new Color(0xf1ef9e), new Color(113, 111, 64));
+ private static final Color HEAD_COLOR = new JBColor(new Color(0xF10FA9), new Color(0xF10FA9).darker());
private static final Color BRANCH_COLOR = new JBColor(new Color(0x75eec7), new Color(0x0D6D4F));
private static final Color CLOSED_BRANCH_COLOR = new JBColor(new Color(0xee7f8a), new Color(0xee7f8a).darker());
private static final Color BOOKMARK_COLOR = new JBColor(new Color(0xbcbcfc), new Color(0xbcbcfc).darker().darker());
private static final Color TAG_COLOR = JBColor.WHITE;
private static final Color LOCAL_TAG_COLOR = JBColor.CYAN;
+ public static final VcsRefType TIP = new SimpleRefType(true, TIP_COLOR);
public static final VcsRefType HEAD = new SimpleRefType(true, HEAD_COLOR);
public static final VcsRefType BRANCH = new SimpleRefType(true, BRANCH_COLOR);
public static final VcsRefType CLOSED_BRANCH = new SimpleRefType(false, CLOSED_BRANCH_COLOR);
@@ -49,7 +48,7 @@ public class HgRefManager implements VcsLogRefManager {
public static final VcsRefType LOCAL_TAG = new SimpleRefType(false, LOCAL_TAG_COLOR);
// first has the highest priority
- private static final List<VcsRefType> REF_TYPE_PRIORITIES = Arrays.asList(HEAD, BRANCH, BOOKMARK, TAG);
+ private static final List<VcsRefType> REF_TYPE_PRIORITIES = Arrays.asList(TIP, HEAD, BRANCH, BOOKMARK, TAG);
// -1 => higher priority
public static final Comparator<VcsRefType> REF_TYPE_COMPARATOR = new Comparator<VcsRefType>() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
index 15fbbe5a07c0..c60e46c63ced 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ContentRevision;
+import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
@@ -109,6 +110,11 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
//abort
return exceptions;
}
+ //firstly selected changes marked dirty in CommitHelper -> postRefresh, so we need to mark others
+ VcsDirtyScopeManager dirtyManager = VcsDirtyScopeManager.getInstance(myProject);
+ for (HgFile hgFile : changedFilesNotInCommit) {
+ dirtyManager.fileDirty(hgFile.toFilePath());
+ }
}
// else : all was included, or it was OK to commit everything,
// so no need to set the files on the command, because then mercurial will complain
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java
index 75387b221b02..4052b34a60d5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java
@@ -103,7 +103,7 @@ public class HgUpdateEnvironment implements UpdateEnvironment {
}
public JComponent createComponent() {
- updateDialog = new HgUpdateDialog(updateConfiguration);
+ updateDialog = new HgUpdateDialog();
return updateDialog.getContentPanel();
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
index 133bfc7ce869..f73375f9c791 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
@@ -24,11 +24,9 @@ import org.zmlx.hg4idea.HgNameWithHashInfo;
import java.util.*;
-/**
- * @author Nadya Zabrodina
- */
public class HgRepoInfo {
@NotNull private String myCurrentBranch = HgRepository.DEFAULT_BRANCH;
+ @Nullable private final String myTipRevision;
@Nullable private final String myCurrentRevision;
@NotNull private final Repository.State myState;
@Nullable private String myCurrentBookmark = null;
@@ -39,14 +37,16 @@ public class HgRepoInfo {
public HgRepoInfo(@NotNull String currentBranch,
@Nullable String currentRevision,
+ @Nullable String currentTipRevision,
@NotNull Repository.State state,
- @NotNull Map<String,Set<Hash>> branches,
+ @NotNull Map<String, Set<Hash>> branches,
@NotNull Collection<HgNameWithHashInfo> bookmarks,
@Nullable String currentBookmark,
@NotNull Collection<HgNameWithHashInfo> tags,
@NotNull Collection<HgNameWithHashInfo> localTags) {
myCurrentBranch = currentBranch;
myCurrentRevision = currentRevision;
+ myTipRevision = currentTipRevision;
myState = state;
myBranches = branches;
myBookmarks = new LinkedHashSet<HgNameWithHashInfo>(bookmarks);
@@ -81,6 +81,11 @@ public class HgRepoInfo {
}
@Nullable
+ public String getTipRevision() {
+ return myTipRevision;
+ }
+
+ @Nullable
public String getCurrentRevision() {
return myCurrentRevision;
}
@@ -103,6 +108,7 @@ public class HgRepoInfo {
HgRepoInfo info = (HgRepoInfo)o;
if (myState != info.myState) return false;
+ if (myTipRevision != null ? !myTipRevision.equals(info.myTipRevision) : info.myTipRevision != null) return false;
if (myCurrentRevision != null ? !myCurrentRevision.equals(info.myCurrentRevision) : info.myCurrentRevision != null) return false;
if (!myCurrentBranch.equals(info.myCurrentBranch)) return false;
if (myCurrentBookmark != null ? !myCurrentBookmark.equals(info.myCurrentBookmark) : info.myCurrentBookmark != null) return false;
@@ -116,7 +122,8 @@ public class HgRepoInfo {
@Override
public int hashCode() {
- return Objects.hashCode(myCurrentBranch, myCurrentRevision, myCurrentBookmark, myState, myBranches, myBookmarks, myTags, myLocalTags);
+ return Objects.hashCode(myCurrentBranch, myCurrentRevision, myTipRevision, myCurrentBookmark, myState, myBranches, myBookmarks, myTags,
+ myLocalTags);
}
@Override
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
index 5b968795221c..8a5c4fc81e53 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
@@ -65,6 +65,9 @@ public interface HgRepository extends Repository {
@Nullable
String getCurrentBookmark();
+ @Nullable
+ String getTipRevision();
+
@NotNull
HgConfig getRepositoryConfig();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java
index 7c97f07fbfbe..179788bc80ba 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java
@@ -36,6 +36,7 @@ public class HgRepositoryFiles {
public static final String MERGE = "merge";
public static final String REBASE = "rebase"; //rebasestate
public static final String BRANCH = "branch";
+ public static final String DIRSTATE = "dirstate";
public static final String BOOKMARKS = "bookmarks";
public static final String LOCAL_TAGS = "localtags";
public static final String TAGS = ".hgtags";
@@ -48,6 +49,7 @@ public class HgRepositoryFiles {
@NotNull private final String myMergePath;
@NotNull private final String myRebasePath;
@NotNull private final String myBranchPath;
+ @NotNull private final String myDirstatePath;
@NotNull private final String myBookmarksPath;
@NotNull private final String myTagsPath;
@NotNull private final String myLocalTagsPath;
@@ -63,6 +65,7 @@ public class HgRepositoryFiles {
myBranchHeadsPath = hgDir.getPath() + slash(BRANCHHEADS);
myBranchHeadsDirPath = hgDir.getPath() + slash(BRANCHEADSDIR);
myBranchPath = hgDir.getPath() + slash(BRANCH);
+ myDirstatePath = hgDir.getPath() + slash(DIRSTATE);
myMergePath = hgDir.getPath() + slash(MERGE);
myRebasePath = hgDir.getPath() + slash(REBASE);
myBookmarksPath = hgDir.getPath() + slash(BOOKMARKS);
@@ -98,6 +101,10 @@ public class HgRepositoryFiles {
return filePath.equals(myBranchPath);
}
+ public boolean isDirstateFile(String filePath) {
+ return filePath.equals(myDirstatePath);
+ }
+
public boolean isMergeFile(String filePath) {
return filePath.startsWith(myMergePath);
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index fb0036185ebf..77c81ee80993 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -108,6 +108,11 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
return myInfo.getCurrentRevision();
}
+ @Nullable
+ public String getTipRevision() {
+ return myInfo.getTipRevision();
+ }
+
@Override
@NotNull
public Map<String, Set<Hash>> getBranches() {
@@ -185,7 +190,8 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
myIsFresh = myIsFresh && myReader.isFresh();
//in GitRepositoryImpl there are temporary state object for reader fields storing! Todo Check;
return
- new HgRepoInfo(myReader.readCurrentBranch(), myReader.readCurrentRevision(), myReader.readState(), myReader.readBranches(),
+ new HgRepoInfo(myReader.readCurrentBranch(), myReader.readCurrentRevision(), myReader.readCurrentTipRevision(), myReader.readState(),
+ myReader.readBranches(),
myReader.readBookmarks(), myReader.readCurrentBookmark(), myReader.readTags(), myReader.readLocalTags());
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
index 7c0c37a84c8a..923087d0b3b2 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
@@ -19,8 +19,10 @@ import com.intellij.dvcs.repo.RepoStateException;
import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryUtil;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsLogObjectsFactory;
+import org.apache.commons.codec.binary.Hex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
@@ -28,6 +30,9 @@ import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.util.HgVersion;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -53,6 +58,7 @@ public class HgRepositoryReader {
@NotNull private final File myCurrentBookmark; //.hg/bookmarks.current
@NotNull private final File myTagsFile; //.hgtags - not in .hg directory!!!
@NotNull private final File myLocalTagsFile; // .hg/localtags
+ @NotNull private final File myDirStateFile; // .hg/dirstate
@NotNull private final VcsLogObjectsFactory myVcsObjectsFactory;
private final boolean myStatusInBranchFile;
@NotNull final HgVcs myVcs;
@@ -70,6 +76,7 @@ public class HgRepositoryReader {
myCurrentBookmark = new File(myHgDir, "bookmarks.current");
myLocalTagsFile = new File(myHgDir, "localtags");
myTagsFile = new File(myHgDir.getParentFile(), ".hgtags");
+ myDirStateFile = new File(myHgDir, "dirstate");
myVcsObjectsFactory = ServiceManager.getService(vcs.getProject(), VcsLogObjectsFactory.class);
}
@@ -98,6 +105,36 @@ public class HgRepositoryReader {
*/
@Nullable
public String readCurrentRevision() {
+ if (!isDirStateInfoAvailable()) return null;
+ try {
+ return Hex.encodeHexString(readBytesFromFile(myDirStateFile, 20));
+ }
+ catch (IOException e) {
+ // dirState exists if not fresh, if we could not load dirState info repository must be corrupted
+ throw new RepoStateException("IOException while trying to read current repository state information.", e);
+ }
+ }
+
+ @NotNull
+ public byte[] readBytesFromFile(@NotNull File file, int len) throws IOException {
+ byte[] bytes;
+ final InputStream stream = new FileInputStream(file);
+ try {
+ bytes = FileUtil.loadBytes(stream, len);
+ }
+ finally {
+ stream.close();
+ }
+ return bytes;
+ }
+
+ /**
+ * Finds tip revision value.
+ *
+ * @return The tip revision hash, or <b>{@code null}</b> if tip revision is unknown - it is the initial repository state.
+ */
+ @Nullable
+ public String readCurrentTipRevision() {
if (!isBranchInfoAvailable()) return null;
String[] branchesWithHeads = RepositoryUtil.tryLoadFile(myBranchHeadsFile).split("\n");
String head = branchesWithHeads[0];
@@ -113,6 +150,10 @@ public class HgRepositoryReader {
return !isFresh() && myBranchHeadsFile.exists();
}
+ private boolean isDirStateInfoAvailable() {
+ return myDirStateFile.exists();
+ }
+
/**
* Return current branch
*/
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java
index 39a3106b8761..f8ccf7cf130e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java
@@ -34,8 +34,6 @@ import java.util.List;
/**
* Listens to .hg service files changes and updates {@link HgRepository} when needed.
- *
- * @author Nadya Zabrodina
*/
final class HgRepositoryUpdater implements Disposable, BulkFileListener {
@NotNull private final HgRepositoryFiles myRepositoryFiles;
@@ -90,6 +88,7 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener {
// which files in .hg were changed
boolean branchHeadsChanged = false;
boolean branchFileChanged = false;
+ boolean dirstateFileChanged = false;
boolean mergeFileChanged = false;
boolean rebaseFileChanged = false;
boolean bookmarksFileChanged = false;
@@ -109,6 +108,9 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener {
branchFileChanged = true;
RepositoryUtil.visitAllChildrenRecursively(myBranchHeadsDir);
}
+ else if (myRepositoryFiles.isDirstateFile(filePath)) {
+ dirstateFileChanged = true;
+ }
else if (myRepositoryFiles.isMergeFile(filePath)) {
mergeFileChanged = true;
}
@@ -135,6 +137,7 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener {
if (branchHeadsChanged ||
branchFileChanged ||
+ dirstateFileChanged ||
mergeFileChanged ||
rebaseFileChanged ||
bookmarksFileChanged ||
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java
index 16fb9b4ddeec..a399fc4174e6 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java
@@ -36,10 +36,11 @@ public class HgUpdateDialog {
private JRadioButton myRebaseRadioButton;
- public HgUpdateDialog(@NotNull HgUpdateConfigurationSettings updateSettings) {
- myContentPanel = createCenterPanel(updateSettings);
+ public HgUpdateDialog() {
+ myContentPanel = createCenterPanel();
}
+ @NotNull
public JComponent getContentPanel() {
return myContentPanel;
}
@@ -48,7 +49,7 @@ public class HgUpdateDialog {
myCommitAfterMergeCheckBox.setEnabled(myMergeRadioButton.isSelected());
}
- public void applyTo(HgUpdateConfigurationSettings updateConfiguration) {
+ public void applyTo(@NotNull HgUpdateConfigurationSettings updateConfiguration) {
updateConfiguration.setShouldPull(myPullCheckBox.isSelected());
if (myOnlyUpdateButton.isSelected()) {
updateConfiguration.setUpdateType(HgUpdateType.ONLY_UPDATE);
@@ -62,14 +63,15 @@ public class HgUpdateDialog {
updateConfiguration.setShouldCommitAfterMerge(myCommitAfterMergeCheckBox.isSelected());
}
- public JComponent createCenterPanel(HgUpdateConfigurationSettings updateSettings) {
+ @NotNull
+ public JComponent createCenterPanel() {
MigLayout migLayout = new MigLayout("flowy,ins 0, fill");
JPanel contentPane = new JPanel(migLayout);
myPullCheckBox = new JBCheckBox("Pull", true);
myPullCheckBox.setMnemonic('p');
myPullCheckBox.setToolTipText("Pull from the default remote repository");
- myPullCheckBox.setSelected(updateSettings.shouldPull());
+ myPullCheckBox.setSelected(true);
myOnlyUpdateButton = new JRadioButton("Only Update", true);
myOnlyUpdateButton.setMnemonic('u');
@@ -88,7 +90,7 @@ public class HgUpdateDialog {
myCommitAfterMergeCheckBox = new JCheckBox("Commit after merge without conflicts", false);
myCommitAfterMergeCheckBox.setMnemonic('c');
myCommitAfterMergeCheckBox.setToolTipText("Commit automatically after the merge");
- myCommitAfterMergeCheckBox.setSelected(updateSettings.shouldCommitAfterMerge());
+ myCommitAfterMergeCheckBox.setSelected(false);
myRebaseRadioButton = new JRadioButton("Rebase", false);
myRebaseRadioButton.setToolTipText("Rebase changesets to a branch tip as destination");
@@ -97,7 +99,7 @@ public class HgUpdateDialog {
contentPane.add(myPullCheckBox, "left");
JPanel strategyPanel = new JPanel(migLayout);
- strategyPanel.setBorder(IdeBorderFactory.createTitledBorder("Update Strategy"));
+ strategyPanel.setBorder(IdeBorderFactory.createTitledBorder("Update Strategy", false));
strategyPanel.add(myOnlyUpdateButton, "left");
strategyPanel.add(myMergeRadioButton, "left");
strategyPanel.add(myCommitAfterMergeCheckBox, "gapx 5%");
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
index b24b59de88f1..1cc100efb029 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
@@ -73,6 +73,7 @@ public abstract class HgUtil {
private static final Logger LOG = Logger.getInstance(HgUtil.class);
public static final String DOT_HG = ".hg";
public static final String TIP_REFERENCE = "tip";
+ public static final String HEAD_REFERENCE = "HEAD";
public static File copyResourceToTempFile(String basename, String extension) throws IOException {
final InputStream in = HgUtil.class.getClassLoader().getResourceAsStream("python/" + basename + extension);
diff --git a/plugins/hg4idea/testData/repo/dot_hg/dirstate b/plugins/hg4idea/testData/repo/dot_hg/dirstate
new file mode 100644
index 000000000000..5840278dfd5f
--- /dev/null
+++ b/plugins/hg4idea/testData/repo/dot_hg/dirstate
Binary files differ
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java b/plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java
index ac64812f6239..5cb02e06ca62 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/HgPlatformTest.java
@@ -90,8 +90,13 @@ public abstract class HgPlatformTest extends UsefulTestCase {
@Override
protected void tearDown() throws Exception {
- myProjectFixture.tearDown();
- super.tearDown();
+ try {
+ myProjectFixture.tearDown();
+ clearFields(this);
+ }
+ finally {
+ super.tearDown();
+ }
}
private static void setUpHgrc(@NotNull VirtualFile repositoryRoot) throws IOException {
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
index 9aeda2bda272..bffe04a5e62e 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
@@ -51,6 +51,7 @@ public class HgRepositoryReaderTest extends HgPlatformTest {
File testHgDir = new File(pluginRoot, FileUtil.toSystemDependentName(pathToHg));
File cacheDir = new File(testHgDir, "cache");
+ File testDirStateFile = new File(testHgDir, "dirstate");
File testBranchFile = new File(testHgDir, "branch");
File testBookmarkFile = new File(testHgDir, "bookmarks");
File testCurrentBookmarkFile = new File(testHgDir, "bookmarks.current");
@@ -58,6 +59,7 @@ public class HgRepositoryReaderTest extends HgPlatformTest {
File testLocalTagFile = new File(testHgDir, "localtags");
FileUtil.copyDir(cacheDir, new File(myHgDir, "cache"));
FileUtil.copy(testBranchFile, new File(myHgDir, "branch"));
+ FileUtil.copy(testDirStateFile, new File(myHgDir, "dirstate"));
FileUtil.copy(testBookmarkFile, new File(myHgDir, "bookmarks"));
FileUtil.copy(testCurrentBookmarkFile, new File(myHgDir, "bookmarks.current"));
FileUtil.copy(testTagFile, new File(myHgDir.getParentFile(), ".hgtags"));
@@ -70,8 +72,12 @@ public class HgRepositoryReaderTest extends HgPlatformTest {
myLocalTags = readRefs(testLocalTagFile);
}
- public void testHEAD() {
- assertEquals("25e44c95b2612e3cdf29a704dabf82c77066cb67", myRepositoryReader.readCurrentRevision());
+ public void testCurrentRecision() {
+ assertEquals("33ef48b940a9797973c3becd9d3a181593f5b57a", myRepositoryReader.readCurrentRevision());
+ }
+
+ public void testTip() {
+ assertEquals("25e44c95b2612e3cdf29a704dabf82c77066cb67", myRepositoryReader.readCurrentTipRevision());
}
public void testCurrentBranch() {
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/validator/HgReferenceValidatorTest.java b/plugins/hg4idea/testSrc/hg4idea/test/validator/HgReferenceValidatorTest.java
index 3bec11a46585..f724952eb0e8 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/validator/HgReferenceValidatorTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/validator/HgReferenceValidatorTest.java
@@ -26,8 +26,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryImpl;
import org.zmlx.hg4idea.util.HgReferenceValidator;
-import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
@@ -51,7 +51,7 @@ public class HgReferenceValidatorTest extends HgPlatformTest {
public void setUp() throws Exception {
super.setUp();
HgTestUtil.updateDirectoryMappings(myProject, myRepository);
- HgRepository hgRepository = HgUtil.getRepositoryManager(myProject).getRepositoryForRoot(myRepository);
+ HgRepository hgRepository = HgRepositoryImpl.getInstance(myRepository, myProject, myProject);
assertNotNull(hgRepository);
myValidator = HgReferenceValidator.newInstance(hgRepository);
cd(myRepository);
diff --git a/plugins/java-decompiler/java-decompiler.iml b/plugins/java-decompiler/java-decompiler.iml
new file mode 100644
index 000000000000..cf37a2991f2f
--- /dev/null
+++ b/plugins/java-decompiler/java-decompiler.iml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="java-psi-api" />
+ <orderEntry type="module" module-name="java-psi-impl" />
+ <orderEntry type="module" module-name="util" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/fernflower.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
+ <orderEntry type="library" name="asm5" level="project" />
+ </component>
+</module>
+
diff --git a/plugins/java-decompiler/lib/fernflower.jar b/plugins/java-decompiler/lib/fernflower.jar
new file mode 100644
index 000000000000..85b1c40002b5
--- /dev/null
+++ b/plugins/java-decompiler/lib/fernflower.jar
Binary files differ
diff --git a/plugins/java-decompiler/src/META-INF/plugin.xml b/plugins/java-decompiler/src/META-INF/plugin.xml
new file mode 100644
index 000000000000..2eacf248c370
--- /dev/null
+++ b/plugins/java-decompiler/src/META-INF/plugin.xml
@@ -0,0 +1,20 @@
+<idea-plugin version="2">
+
+ <id>org.jetbrains.java.decompiler</id>
+ <name>Java Bytecode Decompiler</name>
+ <description>
+ The plugin extends standard IDEA .class file viewer with powerful Fernflower decompiler -
+ no more dull "{ /* compiled code */ }" in method bodies!
+ </description>
+ <version>0.1</version>
+ <vendor email="support@jetbrains.com" url="http://www.jetbrains.com">JetBrains</vendor>
+
+ <idea-version since-build="135"/>
+
+ <module value="com.intellij.modules.java"/>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <psi.classFileDecompiler implementation="org.jetbrains.java.decompiler.IdeaDecompiler" order="last"/>
+ </extensions>
+
+</idea-plugin> \ No newline at end of file
diff --git a/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaDecompiler.java b/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaDecompiler.java
new file mode 100644
index 000000000000..bf0454fd6670
--- /dev/null
+++ b/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaDecompiler.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.java.decompiler;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.DefaultProjectFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.compiled.ClassFileDecompilers;
+import com.intellij.psi.impl.compiled.ClsFileImpl;
+import com.intellij.util.containers.ContainerUtil;
+import de.fernflower.main.decompiler.IdeDecompiler;
+import de.fernflower.main.extern.IBytecodeProvider;
+import de.fernflower.main.extern.IDecompilatSaver;
+import de.fernflower.main.extern.IFernflowerLogger;
+import de.fernflower.main.extern.IFernflowerPreferences;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.Manifest;
+
+public class IdeaDecompiler extends ClassFileDecompilers.Light {
+ private static final Logger LOG = Logger.getInstance(IdeaDecompiler.class);
+
+ private static final String BANNER =
+ "//\n" +
+ "// Source code recreated from a .class file by IntelliJ IDEA\n" +
+ "// (powered by Fernflower decompiler)\n" +
+ "//\n\n";
+
+ private final IFernflowerLogger myLogger = new IdeaLogger();
+ private final HashMap<String, Object> myOptions = new HashMap<String, Object>();
+
+ public IdeaDecompiler() {
+ myOptions.put(IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR, "0");
+ myOptions.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1");
+ myOptions.put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1");
+ myOptions.put(IFernflowerPreferences.REMOVE_BRIDGE, "1");
+ myOptions.put(IFernflowerPreferences.LITERALS_AS_IS, "1");
+ myOptions.put(IFernflowerPreferences.NEW_LINE_SEPARATOR, "1");
+
+ Project project = DefaultProjectFactory.getInstance().getDefaultProject();
+ CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
+ CommonCodeStyleSettings.IndentOptions options = settings.getIndentOptions(JavaFileType.INSTANCE);
+ myOptions.put(IFernflowerPreferences.INDENT_STRING, StringUtil.repeat(" ", options.INDENT_SIZE));
+ }
+
+ @Override
+ public boolean accepts(@NotNull VirtualFile file) {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public CharSequence getText(@NotNull VirtualFile file) {
+ if (!canHandle(file)) {
+ return ClsFileImpl.decompile(file);
+ }
+
+ try {
+ Map<String, VirtualFile> files = ContainerUtil.newLinkedHashMap();
+ files.put(file.getPath(), file);
+ String mask = file.getNameWithoutExtension() + "$";
+ for (VirtualFile child : file.getParent().getChildren()) {
+ if (child.getNameWithoutExtension().startsWith(mask) && file.getFileType() == StdFileTypes.CLASS) {
+ files.put(child.getPath(), child);
+ }
+ }
+ MyByteCodeProvider provider = new MyByteCodeProvider(files);
+ MyResultSaver saver = new MyResultSaver();
+
+ IdeDecompiler decompiler = new IdeDecompiler(provider, saver, myLogger, myOptions);
+ for (String path : files.keySet()) {
+ decompiler.addSpace(new File(path), true);
+ }
+ decompiler.decompileContext();
+
+ return BANNER + saver.myResult;
+ }
+ catch (Exception e) {
+ LOG.error(file.getUrl(), e);
+ return ClsFileImpl.decompile(file);
+ }
+ }
+
+ private static boolean canHandle(VirtualFile file) {
+ if ("package-info.class".equals(file.getName())) {
+ LOG.info("skipped: " + file.getUrl());
+ return false;
+ }
+
+ final Ref<Boolean> isGroovy = Ref.create(false);
+ try {
+ new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(Opcodes.ASM5) {
+ @Override
+ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ for (String anInterface : interfaces) {
+ if ("groovy/lang/GroovyObject".equals(anInterface)) {
+ isGroovy.set(true);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void visitSource(String source, String debug) {
+ if (source != null && source.endsWith(".groovy")) {
+ isGroovy.set(true);
+ }
+ }
+ }, ClassReader.SKIP_CODE);
+ }
+ catch (IOException ignore) { }
+ if (isGroovy.get()) {
+ LOG.info("skipped Groovy class: " + file.getUrl());
+ return false;
+ }
+
+ return true;
+ }
+
+ private static class MyByteCodeProvider implements IBytecodeProvider {
+ private final Map<String, VirtualFile> myFiles;
+
+ private MyByteCodeProvider(@NotNull Map<String, VirtualFile> files) {
+ myFiles = files;
+ }
+
+ @Override
+ public InputStream getBytecodeStream(String externalPath, String internalPath) {
+ try {
+ String path = FileUtil.toSystemIndependentName(externalPath);
+ VirtualFile file = myFiles.get(path);
+ assert file != null : path;
+ return file.getInputStream();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private static class MyResultSaver implements IDecompilatSaver {
+ private String myResult = "";
+
+ @Override
+ public void saveClassFile(String path, String qualifiedName, String entryName, String content) {
+ if (myResult.isEmpty()) {
+ myResult = content;
+ }
+ }
+
+ @Override
+ public void copyFile(String source, String destPath, String destFileName) { }
+
+ @Override
+ public void saveFolder(String path) { }
+
+ @Override
+ public void saveFile(String path, String filename, String content) { }
+
+ @Override
+ public void createArchive(String path, String archiveName, Manifest manifest) { }
+
+ @Override
+ public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) { }
+
+ @Override
+ public void saveEntry(String path, String archiveName, String entryName, String content) { }
+
+ @Override
+ public void copyEntry(String source, String destPath, String archiveName, String entry) { }
+
+ @Override
+ public void closeArchive(String path, String archiveName) { }
+ }
+}
diff --git a/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaLogger.java b/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaLogger.java
new file mode 100644
index 000000000000..904af9bf31b3
--- /dev/null
+++ b/plugins/java-decompiler/src/org/jetbrains/java/decompiler/IdeaLogger.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.java.decompiler;
+
+import com.intellij.openapi.diagnostic.Logger;
+import de.fernflower.main.extern.IFernflowerLogger;
+
+public class IdeaLogger implements IFernflowerLogger {
+ private final static Logger LOG = Logger.getInstance(IdeaDecompiler.class);
+
+ public static class InternalException extends RuntimeException {
+ public InternalException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ @Override
+ public void writeMessage(String message, int severity) {
+ if (severity >= ERROR) LOG.error(message);
+ else if (severity == WARNING) LOG.warn(message);
+ else if (severity == INFO) LOG.info(message);
+ else LOG.debug(message);
+ }
+
+ @Override
+ public void writeMessage(String message, Throwable t) {
+ if (t instanceof InternalException) throw (InternalException)t;
+ else throw new InternalException(message, t);
+ }
+
+ @Override
+ public void startClass(String className) {
+ LOG.debug("processing class " + className);
+ }
+
+ @Override
+ public void endClass() {
+ LOG.debug("... class processed");
+ }
+
+ @Override
+ public void startWriteClass(String className) {
+ LOG.debug("writing class " + className);
+ }
+
+ @Override
+ public void endWriteClass() {
+ LOG.debug("... class written");
+ }
+
+ @Override
+ public void startMethod(String method) {
+ LOG.debug("processing method " + method);
+ }
+
+ @Override
+ public void endMethod() {
+ LOG.debug("... method processed");
+ }
+
+ @Override
+ public int getSeverity() {
+ return WARNING;
+ }
+
+ @Override
+ public void setSeverity(int ignore) { }
+}
diff --git a/plugins/java-decompiler/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.java b/plugins/java-decompiler/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.java
new file mode 100644
index 000000000000..9367fc066f30
--- /dev/null
+++ b/plugins/java-decompiler/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.java.decompiler;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.StandardFileSystems;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.compiled.ClsFileImpl;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+public class IdeaDecompilerTest extends LightCodeInsightFixtureTestCase {
+ public void testSimple() {
+ String path = PlatformTestUtil.getRtJarPath() + "!/java/lang/String.class";
+ VirtualFile file = StandardFileSystems.jar().findFileByPath(path);
+ assertNotNull(path, file);
+
+ CharSequence text = new IdeaDecompiler().getText(file);
+ assertNotNull(text);
+
+ String decompiled = text.toString();
+ assertTrue(decompiled, decompiled.contains("public final class String"));
+ assertTrue(decompiled, decompiled.contains("@deprecated"));
+ assertTrue(decompiled, decompiled.contains("private static class CaseInsensitiveComparator"));
+ assertFalse(decompiled, decompiled.contains("{ /* compiled code */ }"));
+ assertFalse(decompiled, decompiled.contains("synthetic"));
+ }
+
+ public void testEnum() { doTestDecompiler(); }
+ public void testDeprecations() { doTestDecompiler(); }
+ public void testExtendsList() { doTestDecompiler(); }
+ public void testParameters() { doTestDecompiler(); }
+ public void testConstants() { doTestDecompiler(); }
+ public void testAnonymous() { doTestDecompiler(); }
+
+ private void doTestDecompiler() {
+ String name = PluginPathManager.getPluginHomePath("java-decompiler") + "/testData/" + getName().substring(4);
+ String path = name + ".class";
+ VirtualFile file = StandardFileSystems.local().findFileByPath(path);
+ assertNotNull(path, file);
+ file.getParent().getChildren();
+ file.getParent().refresh(false, true);
+
+ try {
+ CharSequence text = new IdeaDecompiler().getText(file);
+ assertNotNull(text);
+ String expected = FileUtil.loadFile(new File(name + ".txt"), "UTF-8");
+ assertEquals(StringUtil.convertLineSeparators(expected), text.toString());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void testStubCompatibilityRt() {
+ String path = PlatformTestUtil.getRtJarPath() + "!/";
+ VirtualFile dir = StandardFileSystems.jar().findFileByPath(path);
+ assertNotNull(path, dir);
+ doTestStubCompatibility(dir);
+ }
+
+ public void testStubCompatibilityIdea() {
+ String path = PathManager.getHomePath() + "/out/production";
+ if (!new File(path).exists()) path = PathManager.getHomePath() + "/out/classes/production";
+ VirtualFile dir = StandardFileSystems.local().refreshAndFindFileByPath(path);
+ assertNotNull(path, dir);
+ doTestStubCompatibility(dir);
+ }
+
+ private void doTestStubCompatibility(VirtualFile root) {
+ doTestStubCompatibility(root, null);
+ }
+
+ private void doTestStubCompatibility(VirtualFile root, @Nullable final String textPath) {
+ final int pathStart = root.getPath().length();
+ final boolean compare = textPath != null && new File(textPath).exists();
+
+ VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor() {
+ @Override
+ public boolean visitFile(@NotNull VirtualFile file) {
+ if (file.getName().equals("Jps.class")) return true; // temp. fix
+ if (!file.isDirectory() && file.getFileType() == StdFileTypes.CLASS && !file.getName().contains("$")) {
+ PsiFile clsFile = getPsiManager().findFile(file);
+ assertNotNull(file.getPath(), clsFile);
+
+ PsiElement mirror = ((ClsFileImpl)clsFile).getMirror().copy();
+ if (textPath != null) {
+ collapseCodeBlocks(mirror);
+ }
+ String decompiled = mirror.getText();
+ assertTrue(file.getPath(), decompiled.contains(file.getNameWithoutExtension()));
+
+ if (textPath != null) {
+ try {
+ File txtFile = new File(textPath, file.getPath().substring(pathStart));
+ if (!compare) {
+ FileUtil.writeToFile(txtFile, decompiled.getBytes("UTF-8"));
+ }
+ else {
+ String expected = FileUtil.loadFile(txtFile, "UTF-8");
+ assertEquals(file.getPath(), expected, decompiled);
+ }
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private static void collapseCodeBlocks(PsiElement original) {
+ final PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(original.getProject());
+ original.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitMethod(PsiMethod method) {
+ PsiCodeBlock body = method.getBody();
+ if (body != null) {
+ body.replace(factory.createCodeBlockFromText("{ /* collapsed */}", null));
+ }
+ }
+
+ @Override
+ public void visitClass(PsiClass aClass) {
+ for (PsiClassInitializer initializer : aClass.getInitializers()) {
+ PsiCodeBlock body = initializer.getBody();
+ body.replace(factory.createCodeBlockFromText("{ /* collapsed */}", null));
+ }
+ super.visitClass(aClass);
+ }
+ });
+ }
+}
diff --git a/plugins/java-decompiler/testData/Anonymous$1.class b/plugins/java-decompiler/testData/Anonymous$1.class
new file mode 100644
index 000000000000..338c04840be2
--- /dev/null
+++ b/plugins/java-decompiler/testData/Anonymous$1.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Anonymous.class b/plugins/java-decompiler/testData/Anonymous.class
new file mode 100644
index 000000000000..df67a5858753
--- /dev/null
+++ b/plugins/java-decompiler/testData/Anonymous.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Anonymous.java b/plugins/java-decompiler/testData/Anonymous.java
new file mode 100644
index 000000000000..6f4a89389a27
--- /dev/null
+++ b/plugins/java-decompiler/testData/Anonymous.java
@@ -0,0 +1,13 @@
+public class Anonymous {
+ private int count = 0;
+
+ public Object produce() {
+ final int id = count++;
+ return new Object() {
+ @Override
+ public String toString() {
+ return "anonymous_" + id;
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/java-decompiler/testData/Anonymous.txt b/plugins/java-decompiler/testData/Anonymous.txt
new file mode 100644
index 000000000000..a7cea92713b7
--- /dev/null
+++ b/plugins/java-decompiler/testData/Anonymous.txt
@@ -0,0 +1,24 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+
+public class Anonymous {
+
+ private int count = 0;
+
+
+ public Anonymous() {
+ }
+
+ public Object produce() {
+ ++this.count;
+ final int var1 = this.count;
+ return new Object() {
+ public String toString() {
+ return "anonymous_" + var1;
+ }
+ };
+ }
+}
diff --git a/plugins/java-decompiler/testData/Constants$A.class b/plugins/java-decompiler/testData/Constants$A.class
new file mode 100644
index 000000000000..d4d8df39443a
--- /dev/null
+++ b/plugins/java-decompiler/testData/Constants$A.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Constants.class b/plugins/java-decompiler/testData/Constants.class
new file mode 100644
index 000000000000..a8ad40e7b158
--- /dev/null
+++ b/plugins/java-decompiler/testData/Constants.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Constants.java b/plugins/java-decompiler/testData/Constants.java
new file mode 100644
index 000000000000..b2b59a5728c6
--- /dev/null
+++ b/plugins/java-decompiler/testData/Constants.java
@@ -0,0 +1,47 @@
+public class Constants {
+ static final boolean T = true;
+ static final boolean F = false;
+
+ static final char C0 = '\n';
+ static final char C1 = 'a';
+ static final char C2 = 512;
+
+ static final byte BMin = Byte.MIN_VALUE;
+ static final byte BMax = Byte.MAX_VALUE;
+
+ static final short SMin = Short.MIN_VALUE;
+ static final short SMax = Short.MAX_VALUE;
+
+ static final int IMin = Integer.MIN_VALUE;
+ static final int IMax = Integer.MAX_VALUE;
+
+ static final long LMin = Long.MIN_VALUE;
+ static final long LMax = Long.MAX_VALUE;
+
+ static final float FNan = Float.NaN;
+ static final float FNeg = Float.NEGATIVE_INFINITY;
+ static final float FPos = Float.POSITIVE_INFINITY;
+ static final float FMin = Float.MIN_VALUE;
+ static final float FMax = Float.MAX_VALUE;
+
+ static final double DNan = Double.NaN;
+ static final double DNeg = Double.NEGATIVE_INFINITY;
+ static final double DPos = Double.POSITIVE_INFINITY;
+ static final double DMin = Double.MIN_VALUE;
+ static final double DMax = Double.MAX_VALUE;
+
+ static @interface A {
+ Class<?> value();
+ }
+
+ @A(byte.class) void m1() { }
+ @A(char.class) void m2() { }
+ @A(double.class) void m3() { }
+ @A(float.class) void m4() { }
+ @A(int.class) void m5() { }
+ @A(long.class) void m6() { }
+ @A(short.class) void m7() { }
+ @A(boolean.class) void m8() { }
+ @A(void.class) void m9() { }
+ @A(java.util.Date.class) void m10() { }
+} \ No newline at end of file
diff --git a/plugins/java-decompiler/testData/Constants.txt b/plugins/java-decompiler/testData/Constants.txt
new file mode 100644
index 000000000000..9665582396c0
--- /dev/null
+++ b/plugins/java-decompiler/testData/Constants.txt
@@ -0,0 +1,82 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+import java.util.Date;
+
+public class Constants {
+
+ static final boolean T = true;
+ static final boolean F = false;
+ static final char C0 = '\n';
+ static final char C1 = 'a';
+ static final char C2 = 'È€';
+ static final byte BMin = -128;
+ static final byte BMax = 127;
+ static final short SMin = -32768;
+ static final short SMax = 32767;
+ static final int IMin = -2147483648;
+ static final int IMax = 2147483647;
+ static final long LMin = -9223372036854775808L;
+ static final long LMax = 9223372036854775807L;
+ static final float FNan = 0.0F / 0.0;
+ static final float FNeg = -1.0F / 0.0;
+ static final float FPos = 1.0F / 0.0;
+ static final float FMin = 1.4E-45F;
+ static final float FMax = 3.4028235E38F;
+ static final double DNan = 0.0D / 0.0;
+ static final double DNeg = -1.0D / 0.0;
+ static final double DPos = 1.0D / 0.0;
+ static final double DMin = 4.9E-324D;
+ static final double DMax = 1.7976931348623157E308D;
+
+
+ public Constants() {
+ }
+
+ @Constants(byte.class)
+ void m1() {
+ }
+
+ @Constants(char.class)
+ void m2() {
+ }
+
+ @Constants(double.class)
+ void m3() {
+ }
+
+ @Constants(float.class)
+ void m4() {
+ }
+
+ @Constants(int.class)
+ void m5() {
+ }
+
+ @Constants(long.class)
+ void m6() {
+ }
+
+ @Constants(short.class)
+ void m7() {
+ }
+
+ @Constants(boolean.class)
+ void m8() {
+ }
+
+ @Constants(void.class)
+ void m9() {
+ }
+
+ @Constants(Date.class)
+ void m10() {
+ }
+
+ @interface A {
+
+ Class<?> value();
+ }
+}
diff --git a/plugins/java-decompiler/testData/Deprecations$ByAnno.class b/plugins/java-decompiler/testData/Deprecations$ByAnno.class
new file mode 100644
index 000000000000..4fcd96c2259e
--- /dev/null
+++ b/plugins/java-decompiler/testData/Deprecations$ByAnno.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Deprecations$ByComment.class b/plugins/java-decompiler/testData/Deprecations$ByComment.class
new file mode 100644
index 000000000000..e04dcf79a0f2
--- /dev/null
+++ b/plugins/java-decompiler/testData/Deprecations$ByComment.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Deprecations.class b/plugins/java-decompiler/testData/Deprecations.class
new file mode 100644
index 000000000000..aa6de359a4aa
--- /dev/null
+++ b/plugins/java-decompiler/testData/Deprecations.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Deprecations.java b/plugins/java-decompiler/testData/Deprecations.java
new file mode 100644
index 000000000000..838ff68131de
--- /dev/null
+++ b/plugins/java-decompiler/testData/Deprecations.java
@@ -0,0 +1,19 @@
+public class Deprecations {
+ /** @deprecated */
+ public int byComment;
+
+ @Deprecated
+ public int byAnno;
+
+ /** @deprecated */
+ public void byComment() { }
+
+ @Deprecated
+ public void byAnno() { }
+
+ /** @deprecated */
+ public static class ByComment { }
+
+ @Deprecated
+ public static class ByAnno { }
+} \ No newline at end of file
diff --git a/plugins/java-decompiler/testData/Deprecations.txt b/plugins/java-decompiler/testData/Deprecations.txt
new file mode 100644
index 000000000000..bb1340e83799
--- /dev/null
+++ b/plugins/java-decompiler/testData/Deprecations.txt
@@ -0,0 +1,42 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+
+public class Deprecations {
+
+ /** @deprecated */
+ public int byComment;
+ /** @deprecated */
+ @Deprecated
+ public int byAnno;
+
+
+ public Deprecations() {
+ }
+
+ /** @deprecated */
+ public void byComment() {
+ }
+
+ /** @deprecated */
+ @Deprecated
+ public void byAnno() {
+ }
+
+ /** @deprecated */
+ @Deprecated
+ public static class ByAnno {
+
+ public ByAnno() {
+ }
+ }
+
+ /** @deprecated */
+ public static class ByComment {
+
+ public ByComment() {
+ }
+ }
+}
diff --git a/plugins/java-decompiler/testData/Enum$1.class b/plugins/java-decompiler/testData/Enum$1.class
new file mode 100644
index 000000000000..e52b1899a716
--- /dev/null
+++ b/plugins/java-decompiler/testData/Enum$1.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Enum$2.class b/plugins/java-decompiler/testData/Enum$2.class
new file mode 100644
index 000000000000..c86cdd2a95d1
--- /dev/null
+++ b/plugins/java-decompiler/testData/Enum$2.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Enum.class b/plugins/java-decompiler/testData/Enum.class
new file mode 100644
index 000000000000..45123e255eab
--- /dev/null
+++ b/plugins/java-decompiler/testData/Enum.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Enum.java b/plugins/java-decompiler/testData/Enum.java
new file mode 100644
index 000000000000..b61c069e0e19
--- /dev/null
+++ b/plugins/java-decompiler/testData/Enum.java
@@ -0,0 +1,19 @@
+public enum Enum {
+ E1,
+ E2() {
+ @Override
+ public void m() { }
+ },
+ E3("-"),
+ E4("+") {
+ @Override
+ public void m() { }
+ };
+
+ public void m() { }
+
+ private String s;
+
+ private Enum() { this("?"); }
+ private Enum(@Deprecated String s) { this.s = s; }
+}
diff --git a/plugins/java-decompiler/testData/Enum.txt b/plugins/java-decompiler/testData/Enum.txt
new file mode 100644
index 000000000000..1156c8214d78
--- /dev/null
+++ b/plugins/java-decompiler/testData/Enum.txt
@@ -0,0 +1,33 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+
+public enum Enum {
+
+ E1,
+ E2 {
+ public void m() {
+ }
+ },
+ E3("-"),
+ E4("+") {
+ public void m() {
+ }
+ };
+ private String s;
+
+
+ public void m() {
+ }
+
+ private Enum() {
+ this((String)"?");
+ }
+
+ private Enum(@Deprecated String var3) {
+ this.s = var3;
+ }
+
+}
diff --git a/plugins/java-decompiler/testData/ExtendsList.class b/plugins/java-decompiler/testData/ExtendsList.class
new file mode 100644
index 000000000000..7d4eb9c69265
--- /dev/null
+++ b/plugins/java-decompiler/testData/ExtendsList.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/ExtendsList.java b/plugins/java-decompiler/testData/ExtendsList.java
new file mode 100644
index 000000000000..19fbe6d66705
--- /dev/null
+++ b/plugins/java-decompiler/testData/ExtendsList.java
@@ -0,0 +1,9 @@
+public class ExtendsList {
+ static <T extends Comparable<? super T>> T m1(T t) {
+ return null;
+ }
+
+ static <T extends Object & Comparable<? super T>> T m2(T t) {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/java-decompiler/testData/ExtendsList.txt b/plugins/java-decompiler/testData/ExtendsList.txt
new file mode 100644
index 000000000000..6996123b6a3d
--- /dev/null
+++ b/plugins/java-decompiler/testData/ExtendsList.txt
@@ -0,0 +1,19 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+
+public class ExtendsList {
+
+ public ExtendsList() {
+ }
+
+ static <T extends Comparable<? super T>> T m1(T var0) {
+ return null;
+ }
+
+ static <T extends Object & Comparable<? super T>> T m2(T var0) {
+ return null;
+ }
+}
diff --git a/plugins/java-decompiler/testData/Parameters$1Local.class b/plugins/java-decompiler/testData/Parameters$1Local.class
new file mode 100644
index 000000000000..a9c187cc05d7
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters$1Local.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Parameters$C1.class b/plugins/java-decompiler/testData/Parameters$C1.class
new file mode 100644
index 000000000000..882226ceb63c
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters$C1.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Parameters$C2.class b/plugins/java-decompiler/testData/Parameters$C2.class
new file mode 100644
index 000000000000..85a98c6f72dd
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters$C2.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Parameters.class b/plugins/java-decompiler/testData/Parameters.class
new file mode 100644
index 000000000000..f29432cf1fd0
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters.class
Binary files differ
diff --git a/plugins/java-decompiler/testData/Parameters.java b/plugins/java-decompiler/testData/Parameters.java
new file mode 100644
index 000000000000..be18b4e6e06f
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters.java
@@ -0,0 +1,23 @@
+public class Parameters {
+ Parameters(@Deprecated int p01) { }
+ void m1(@Deprecated int p02) { }
+ static void m2(@Deprecated int p03) { }
+
+ class C1 {
+ C1(@Deprecated int p11) { }
+ void m(@Deprecated int p12) { }
+ }
+
+ static class C2 {
+ C2(@Deprecated int p21) { }
+ void m1(@Deprecated int p22) { }
+ static void m2(@Deprecated int p23) { }
+ }
+
+ void local() {
+ class Local {
+ Local(@Deprecated int p31) { }
+ void m(@Deprecated int p32) { }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/java-decompiler/testData/Parameters.txt b/plugins/java-decompiler/testData/Parameters.txt
new file mode 100644
index 000000000000..45a856abdd89
--- /dev/null
+++ b/plugins/java-decompiler/testData/Parameters.txt
@@ -0,0 +1,50 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+
+public class Parameters {
+
+ Parameters(@Deprecated int var1) {
+ }
+
+ void m1(@Deprecated int var1) {
+ }
+
+ static void m2(@Deprecated int var0) {
+ }
+
+ void local() {
+ class Local {
+
+ Local(@Deprecated int var2) {
+ }
+
+ void m(@Deprecated int var1) {
+ }
+ }
+
+ }
+
+ static class C2 {
+
+ C2(@Deprecated int var1) {
+ }
+
+ void m1(@Deprecated int var1) {
+ }
+
+ static void m2(@Deprecated int var0) {
+ }
+ }
+
+ class C1 {
+
+ C1(@Deprecated int var2) {
+ }
+
+ void m(@Deprecated int var1) {
+ }
+ }
+}
diff --git a/plugins/java-i18n/java-i18n.iml b/plugins/java-i18n/java-i18n.iml
index 08852084e604..b2f011fe2f7c 100644
--- a/plugins/java-i18n/java-i18n.iml
+++ b/plugins/java-i18n/java-i18n.iml
@@ -21,6 +21,7 @@
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
<orderEntry type="module" module-name="properties-psi-api" />
<orderEntry type="module" module-name="properties-psi-impl" />
+ <orderEntry type="module" module-name="ui-designer" scope="TEST" />
</component>
</module>
diff --git a/plugins/java-i18n/src/META-INF/plugin.xml b/plugins/java-i18n/src/META-INF/plugin.xml
index 399a14245c2e..b352a2f78e08 100644
--- a/plugins/java-i18n/src/META-INF/plugin.xml
+++ b/plugins/java-i18n/src/META-INF/plugin.xml
@@ -24,7 +24,7 @@
implementationClass="com.intellij.lang.properties.PropertiesReferenceProvider"/>
<psi.referenceContributor implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaReferenceContributor"/>
<psi.referenceContributor implementation="com.intellij.lang.properties.PropertiesReferenceContributor"/>
- <lang.foldingBuilder language="JAVA" implementationClass="com.intellij.codeInspection.i18n.folding.PropertyFoldingBuilder" />
+ <lang.foldingBuilder language="JAVA" implementationClass="com.intellij.codeInspection.i18n.folding.PropertyFoldingBuilder" order="FIRST"/>
<gotoDeclarationHandler implementation="com.intellij.codeInspection.i18n.folding.I18nMessageGotoDeclarationHandler" order="FIRST"/>
<localInspection shortName="HardCodedStringLiteral" bundle="messages.CodeInsightBundle" key="inspection.i18n.display.name"
diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentPropertiesEndsInspectionProvider.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentPropertiesEndsInspectionProvider.java
index ff1e8b6c1daf..9b5b96a035f3 100644
--- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentPropertiesEndsInspectionProvider.java
+++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentPropertiesEndsInspectionProvider.java
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefManager;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.BidirectionalMap;
import com.intellij.util.containers.ContainerUtil;
@@ -65,7 +66,7 @@ public class InconsistentPropertiesEndsInspectionProvider implements Inconsisten
final IProperty property = file.findPropertyByKey(commonKey);
assert property != null;
final String propertyValue = property.getValue();
- if (propertyValue == null) {
+ if (StringUtil.isEmptyOrSpaces(propertyValue)) {
continue;
}
final char lastChar = propertyValue.charAt(propertyValue.length() - 1);
diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java
index 48f4b05adfb2..1e71e5d1ce50 100644
--- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java
+++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/inconsistentResourceBundle/InconsistentResourceBundleInspection.java
@@ -144,7 +144,7 @@ public class InconsistentResourceBundleInspection extends GlobalSimpleInspection
ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
assert visitedBundles != null;
if (!visitedBundles.add(resourceBundle)) return;
- List<PropertiesFile> files = resourceBundle.getPropertiesFiles(manager.getProject());
+ List<PropertiesFile> files = resourceBundle.getPropertiesFiles();
if (files.size() < 2) return;
BidirectionalMap<PropertiesFile, PropertiesFile> parents = new BidirectionalMap<PropertiesFile, PropertiesFile>();
for (PropertiesFile f : files) {
diff --git a/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceContributor.java b/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceContributor.java
index a322d400b95f..bce0f3683c6e 100644
--- a/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceContributor.java
+++ b/plugins/java-i18n/src/com/intellij/lang/properties/PropertiesReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -37,7 +37,7 @@ public class PropertiesReferenceContributor extends PsiReferenceContributor{
}
};
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(literalExpression(), new PropertiesReferenceProvider(true));
registrar.registerReferenceProvider(literalExpression().withParent(
psiNameValuePair().withName(AnnotationUtil.PROPERTY_KEY_RESOURCE_BUNDLE_PARAMETER)),
diff --git a/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java b/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java
index a97a2fb69718..b38f94079933 100644
--- a/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java
+++ b/plugins/java-i18n/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaReferenceContributor.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.codeInsight.AnnotationUtil;
@@ -6,6 +21,7 @@ import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.position.FilterPattern;
+import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@@ -17,7 +33,7 @@ import static com.intellij.patterns.XmlPatterns.xmlTag;
* @author peter
*/
public class JavaReferenceContributor extends PsiReferenceContributor{
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
final JavaClassListReferenceProvider classListProvider = new JavaClassListReferenceProvider();
registrar.registerReferenceProvider(xmlAttributeValue(), classListProvider, PsiReferenceRegistrar.LOWER_PRIORITY);
diff --git a/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/expected.xml b/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/expected.xml
new file mode 100644
index 000000000000..6727b98349bd
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/expected.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>6</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Duplicate String Literal</problem_class>
+ <description>&lt;html&gt;&lt;body&gt;Duplicate string literal found in&lt;br&gt;'Test'&lt;/body&gt;&lt;/html&gt;</description>
+ </problem>
+
+ <problem>
+ <file>Test.java</file>
+ <line>10</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Duplicate String Literal</problem_class>
+ <description>&lt;html&gt;&lt;body&gt;Duplicate string literal found in&lt;br&gt;'Test'&lt;/body&gt;&lt;/html&gt;</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/src/Test.java b/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/src/Test.java
new file mode 100644
index 000000000000..48560e51fc28
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/duplicateStringLiteral/propertyKey/src/Test.java
@@ -0,0 +1,13 @@
+import org.jetbrains.annotations.*;
+
+@SuppressWarnings({"HardCodedStringLiteral"})
+class Test {
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ String s = "abcdefghhijklmnop";
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ void f(@PropertyKey(resourceBundle = "xxx.yyy") String key) {
+ String s = "abcdefghhijklmnop";
+ f("abcdefghhijklmnop"); //no way
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/annotationArgument/expected.xml b/plugins/java-i18n/testData/inspections/i18n/annotationArgument/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/annotationArgument/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/annotationArgument/src/Foo.java b/plugins/java-i18n/testData/inspections/i18n/annotationArgument/src/Foo.java
new file mode 100644
index 000000000000..7bbdc7d09cd3
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/annotationArgument/src/Foo.java
@@ -0,0 +1,11 @@
+@interface Language {
+ @org.jetbrains.annotations.NonNls
+ java.lang.String value();
+}
+
+class Foo {
+ void foo() {
+ @Language("abcdefgh")
+ String s;
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/expected.xml b/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/expected.xml
new file mode 100644
index 000000000000..fe72ddee8876
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>8</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/src/Test.java
new file mode 100644
index 000000000000..dbd2e469ac2c
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/anonymousClassConstructorParameter/src/Test.java
@@ -0,0 +1,14 @@
+class Test {
+ private class InnerTest {
+ public InnerTest(String s) { }
+ public abstract void run();
+ }
+
+ public void foo(String s) {
+ bar(new InnerTest("Literal") { public void run() { } });
+ }
+
+ public void bar(InnerTest t) {
+
+ }
+}
diff --git a/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/expected.xml b/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/src/Test.java
new file mode 100644
index 000000000000..ba265eccd255
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/constructorCallOfNonNlsVariable/src/Test.java
@@ -0,0 +1,6 @@
+class Test {
+ void foo() {
+ @org.jetbrains.annotations.NonNls StringBuffer buffer = new StringBuffer("text");
+ buffer = new StringBuffer("text");
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/enum/expected.xml b/plugins/java-i18n/testData/inspections/i18n/enum/expected.xml
new file mode 100644
index 000000000000..4bc4c6551605
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/enum/expected.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>2</line>
+ <description>Hard coded string literal</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>3</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/enum/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/enum/src/Test.java
new file mode 100644
index 000000000000..0f167a69984e
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/enum/src/Test.java
@@ -0,0 +1,21 @@
+enum Test {
+ CHECKIN("Text1"),
+ ADD("Rext2");
+
+ Test(final String id) {
+ myId = id;
+ }
+
+ private final String myId;
+}
+
+enum Test2 {
+ CHECKIN("Text1"),
+ ADD("Rext2");
+
+ Test2(@org.jetbrains.annotations.NonNls final String id) {
+ myId = id;
+ }
+
+ private final String myId;
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/fields/expected.xml b/plugins/java-i18n/testData/inspections/i18n/fields/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/fields/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/fields/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/fields/src/Test.java
new file mode 100644
index 000000000000..eb902100eda3
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/fields/src/Test.java
@@ -0,0 +1,7 @@
+class Foo {
+ @org.jetbrains.annotations.NonNls String field;
+ @org.jetbrains.annotations.NonNls String field2 = "text1";
+ void foo() {
+ field = "text2";
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/expected.xml b/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/expected.xml
new file mode 100644
index 000000000000..9501f4944ff6
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.form</file>
+ <line>1</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/src/Test.form b/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/src/Test.form
new file mode 100644
index 000000000000..c560e0f8cd0d
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/formTabbedPaneTitle/src/Test.form
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1">
+ <tabbedpane id="de448" class="com.intellij.ui.components.JBTabbedPane">
+ <constraints>
+ <xy x="84" y="134" width="200" height="200"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200"/>
+ </grid>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <scrollpane id="38bd0">
+ <constraints>
+ <tabbedpane title="Literal"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children/>
+ </scrollpane>
+ </children>
+ </tabbedpane>
+</form>
diff --git a/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/expected.xml b/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/expected.xml
new file mode 100644
index 000000000000..c93de21f0c36
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Foo.java</file>
+ <line>3</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/src/Foo.java b/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/src/Foo.java
new file mode 100644
index 000000000000..833bfdada65d
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/hardCodedStringLiteralAsParameter/src/Foo.java
@@ -0,0 +1,5 @@
+class Foo {
+ void foo(String s) {
+ foo("text");
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/expected.xml b/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/expected.xml
new file mode 100644
index 000000000000..b66d698faee3
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/expected.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>7</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/src/Test.java
new file mode 100644
index 000000000000..01f27af477f9
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/initializerInAnonymousClass/src/Test.java
@@ -0,0 +1,14 @@
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+public class Test {
+ public static void main(String[] args){
+ ActionListener listener = new ActionListener(){
+ {
+ final String test = "problem reported twice";
+ }
+ public void actionPerformed(final ActionEvent e) {
+
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/localVariables/expected.xml b/plugins/java-i18n/testData/inspections/i18n/localVariables/expected.xml
new file mode 100644
index 000000000000..8e7958ce9451
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/localVariables/expected.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>3</line>
+ <description>Hard coded string literal</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>8</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/localVariables/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/localVariables/src/Test.java
new file mode 100644
index 000000000000..51c6726e264d
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/localVariables/src/Test.java
@@ -0,0 +1,11 @@
+class Foo {
+ void foo() {
+ String v1 = "text";
+ @org.jetbrains.annotations.NonNls String v2 = "text";
+ String v3;
+ @org.jetbrains.annotations.NonNls String v4;
+
+ v3 = "text";
+ v4 = "text";
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/expected.xml b/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/src/Test.java
new file mode 100644
index 000000000000..073910f6e79e
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/nonNlsArray/src/Test.java
@@ -0,0 +1,9 @@
+class Foo {
+ @org.jetbrains.annotations.NonNls String[] myArray = new String[] {"text1", "text2"};
+ @org.jetbrains.annotations.NonNls Stirng[] foo() {
+ myArray = new String[] {"text3", "text4"};
+ myArray[0] = "text5";
+
+ return new String[] {"text6"};
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/expected.xml b/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/expected.xml
new file mode 100644
index 000000000000..e296a5c15fdf
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/expected.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Foo.java</file>
+ <line>4</line>
+ <problem_class>Hard coded strings</problem_class>
+ <description>Hard coded string literal: 'xxxxx'</description>
+ </problem>
+ <problem>
+ <file>Foo.java</file>
+ <line>9</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Hard coded strings</problem_class>
+ <description>Hard coded string literal: 'MYNON-NLS'</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/src/Foo.java b/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/src/Foo.java
new file mode 100644
index 000000000000..d028b09721aa
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/nonNlsComment/src/Foo.java
@@ -0,0 +1,12 @@
+class Foo {
+ void foo(String... s) {
+ foo("literal", "literal"); // MYNON-NLS0
+ String d = "xxxxx"; // NON-NLS
+ String d0 = "xxxxx", d01="sssss"; //MYNON-NLS
+ String d1 = "xxxxx"; // MYNON-NLS?
+
+ String d2 = "xxxxx"; /* MYNON-NLS ??? */
+ String wtf="MYNON-NLS";
+ String dw2 = "xxxxx"; String wtw="MYNON-NLS"; /* MYNON-NLS ??? */
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/expected.xml b/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/src/Test.java
new file mode 100644
index 000000000000..46a6b8db81f3
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/parameterInNewAnonymousClass/src/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ public static final Test TEST = new Test("text") {
+ public void foo() {}
+ };
+
+ public Test(@org.jetbrains.annotations.NonNls String p) {
+
+ }
+
+ public abstract void foo();
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/expected.xml b/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/src/Test.java
new file mode 100644
index 000000000000..06a7501ac22e
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/parameterInheritsNonNlsAnnotationFromSuper/src/Test.java
@@ -0,0 +1,17 @@
+class A {
+ void foo(@org.jetbrains.annotations.NonNls String p){
+
+ }
+}
+
+class B extends A{
+ void foo(String p){
+
+ }
+}
+
+class C extends B{
+ void foo(String p){
+ foo("text");
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/expected.xml b/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/expected.xml
new file mode 100644
index 000000000000..a8e3c1edbb25
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/expected.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>2</line>
+ <description>Hard coded string literal</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>6</line>
+ <description>Hard coded string literal</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>11</line>
+ <description>Hard coded string literal</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>12</line>
+ <description>Hard coded string literal</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/src/Test.java
new file mode 100644
index 000000000000..fa637486fae2
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/recursiveInheritance/src/Test.java
@@ -0,0 +1,14 @@
+class A extends C{
+ String foo(String p){ return "text";}
+}
+
+class B extends A{
+ String foo(String p){ return "text";}
+}
+
+class C extends A{
+ String foo(String p){
+ foo("text");
+ return "text";
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/expected.xml b/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/src/Test.java
new file mode 100644
index 000000000000..4e1d8de48f39
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/returnTypeInheritsNonNlsAnnotationFromParent/src/Test.java
@@ -0,0 +1,17 @@
+interface I {
+ @org.jetbrains.annotations.NonNls String foo();
+}
+
+class B implements I{
+ public String foo() {
+ return "text";
+ }
+}
+
+class A {
+ B inner = new B() {
+ public String foo() {
+ return "text";
+ }
+ };
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/expected.xml b/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/src/Bar.java b/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/src/Bar.java
new file mode 100644
index 000000000000..c29888bb8aad
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/stringBufferNonNls/src/Bar.java
@@ -0,0 +1,12 @@
+import java.util.Collection;
+
+class SBTest {
+ void foo(@org.jetbrains.annotations.NonNls Collection coll) {
+ coll.add("aaa");
+ }
+
+ void foo(@org.jetbrains.annotations.NonNls StringBuffer buffer) {
+ buffer.append("aaa");
+ buffer.append("aaa").append("bbb").append("do not i18n this too");
+ }
+}
diff --git a/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/expected.xml b/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/src/Test.java b/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/src/Test.java
new file mode 100644
index 000000000000..72b5aea70436
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/switchOnNonNlsString/src/Test.java
@@ -0,0 +1,8 @@
+class Test {
+ void foo(@org.jetbrains.annotations.NonNls String s) {
+ switch (s) {
+ case "foooooo":
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/expected.xml b/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/expected.xml
new file mode 100644
index 000000000000..d704d58ed391
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/expected.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/src/Foo.java b/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/src/Foo.java
new file mode 100644
index 000000000000..eb89d7544a85
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/i18n/varargNonNlsParameter/src/Foo.java
@@ -0,0 +1,5 @@
+class Foo {
+ void foo(@org.jetbrains.annotations.NonNls String... s) {
+ foo("literal", "literal");
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/expected.xml b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/expected.xml
new file mode 100644
index 000000000000..0f402a094699
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/expected.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.java</file>
+ <line>6</line>
+ <description>String literal 'bollocks' doesn't appear to be valid property key</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>7</line>
+ <description>Property 'with.params' expected 3 parameters, passed 2</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>11</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Invalid property key</problem_class>
+ <description>Property 'weird' expected 4 parameters, passed 3</description>
+ </problem>
+ <problem>
+ <file>Test.java</file>
+ <line>14</line>
+ <description>Property 'with.params' expected 3 parameters, passed 0</description>
+ </problem>
+</problems>
diff --git a/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu.properties b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu.properties
new file mode 100644
index 000000000000..7efee976cf73
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu.properties
@@ -0,0 +1,3 @@
+defaultKey=default
+with.params=some {0} text with {1} parameters {2}
+weird={0} {3} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu_fr.properties b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu_fr.properties
new file mode 100644
index 000000000000..31d2bcef49f7
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Bu_fr.properties
@@ -0,0 +1,3 @@
+frenchKey=french
+with.params=some {0} text with {1} parameters {2}
+weird={0} {3} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/IBundle.java b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/IBundle.java
new file mode 100644
index 000000000000..e2ba266963b8
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/IBundle.java
@@ -0,0 +1,25 @@
+package x;
+
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.util.ResourceBundle;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: cdr
+ * Date: Oct 9, 2006
+ * Time: 6:22:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class IBundle {
+
+ public static String message(@org.jetbrains.annotations.NotNull @PropertyKey(resourceBundle = BUNDLE) String key,
+ @org.jetbrains.annotations.NotNull Object... params) {
+ return "";
+ }
+
+ @NonNls
+ public static final String BUNDLE = "x.Bu";
+ private static final ResourceBundle ourBundle = ResourceBundle.getBundle(bundleClassName);
+}
diff --git a/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Test.java b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Test.java
new file mode 100644
index 000000000000..fee7630f925c
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/invalidPropertyKey/simple/src/x/Test.java
@@ -0,0 +1,21 @@
+package x;
+import org.jetbrains.annotations.PropertyKey;
+class Test {
+ String s0 = IBundle.message("defaultKey");
+ String s1 = IBundle.message("frenchKey");
+ String s2 = IBundle.message("bollocks");
+ String s3 = IBundle.message("with.params", "a", "b");
+
+ String computable = IBundle.message(this + "bollocks");
+ String computable2 = IBundle.message((("defaultKey")));
+ String weird = IBundle.message("weird", 0,1,2);
+ boolean b = "aaa".contains("with.params");
+
+ String ss1 = f1("with.params");
+ String ss2 = f1("with.params", "", "", "");
+ String ss3 = f2("with.params");
+ String ss4 = IBundle.message("with.params", new Object[3]); // don't check if array passed
+
+ String f1(@PropertyKey(resourceBundle = IBundle.BUNDLE) String s, Object...params) {return "";}
+ String f2(@PropertyKey(resourceBundle = IBundle.BUNDLE) String s) {return "";}
+}
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/expected.xml b/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/expected.xml
new file mode 100644
index 000000000000..e8aa67c8d014
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/expected.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems></problems>
+
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/src/Test.properties b/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/src/Test.properties
new file mode 100644
index 000000000000..c2040a02198c
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/corruptedValue/src/Test.properties
@@ -0,0 +1 @@
+key=value {1 \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/regexp/expected.xml b/plugins/java-i18n/testData/inspections/unusedParameter/regexp/expected.xml
new file mode 100644
index 000000000000..6acb931e4826
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/regexp/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.properties</file>
+ <line>1</line>
+ <description>Using</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/regexp/src/Test.properties b/plugins/java-i18n/testData/inspections/unusedParameter/regexp/src/Test.properties
new file mode 100644
index 000000000000..f621e3fdcbba
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/regexp/src/Test.properties
@@ -0,0 +1,2 @@
+key=[a-z]{2,}
+key.regexp=[a-z]{2,} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/expected.xml b/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/expected.xml
new file mode 100644
index 000000000000..6acb931e4826
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.properties</file>
+ <line>1</line>
+ <description>Using</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/src/Test.properties b/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/src/Test.properties
new file mode 100644
index 000000000000..ff80536ccea3
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/simpleString/src/Test.properties
@@ -0,0 +1 @@
+key=value {1} \ No newline at end of file
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/expected.xml b/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/expected.xml
new file mode 100644
index 000000000000..6acb931e4826
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/expected.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.properties</file>
+ <line>1</line>
+ <description>Using</description>
+ </problem>
+</problems>
+
diff --git a/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/src/Test.properties b/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/src/Test.properties
new file mode 100644
index 000000000000..fbba21142c99
--- /dev/null
+++ b/plugins/java-i18n/testData/inspections/unusedParameter/withChoiceFormat/src/Test.properties
@@ -0,0 +1 @@
+key=value {1, choice, 1#|2#} \ No newline at end of file
diff --git a/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/DuplicateStringLiteralInspectionTest.java b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/DuplicateStringLiteralInspectionTest.java
new file mode 100644
index 000000000000..0cf9f36e1859
--- /dev/null
+++ b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/DuplicateStringLiteralInspectionTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2005 JetBrains s.r.o. All Rights Reserved.
+ */
+package com.intellij.codeInspection.i18n;
+
+import com.intellij.codeInspection.duplicateStringLiteral.DuplicateStringLiteralInspection;
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.InspectionTestCase;
+
+public class DuplicateStringLiteralInspectionTest extends InspectionTestCase {
+ private final DuplicateStringLiteralInspection myInspection = new DuplicateStringLiteralInspection();
+
+ private void doTest() throws Exception {
+ doTest("duplicateStringLiteral/"+getTestName(true), new LocalInspectionToolWrapper(myInspection), "java 1.5");
+ }
+
+ public void testPropertyKey() throws Exception{ myInspection.IGNORE_PROPERTY_KEYS = true; doTest(); }
+
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("java-i18n") + "/testData/inspections";
+ }
+} \ No newline at end of file
diff --git a/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/I18NInspectionTest.java b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/I18NInspectionTest.java
new file mode 100644
index 000000000000..dd0a1ac39fa1
--- /dev/null
+++ b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/I18NInspectionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005 JetBrains s.r.o. All Rights Reserved.
+ */
+package com.intellij.codeInspection.i18n;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.testFramework.InspectionTestCase;
+
+/**
+ * @author lesya
+ */
+public class I18NInspectionTest extends InspectionTestCase {
+ private void doTest() throws Exception {
+ doTest(new I18nInspection());
+ }
+ private void doTest(I18nInspection tool) throws Exception {
+ doTest("i18n/" + getTestName(true), tool);
+ }
+
+ public void testHardCodedStringLiteralAsParameter() throws Exception{ doTest(); }
+ public void testReturnTypeInheritsNonNlsAnnotationFromParent() throws Exception{ doTest(); }
+ public void testRecursiveInheritance() throws Exception { doTest(); }
+ public void testParameterInheritsNonNlsAnnotationFromSuper() throws Exception { doTest(); }
+ public void testLocalVariables() throws Exception { doTest(); }
+ public void testFields() throws Exception{ doTest(); }
+ public void testAnonymousClassConstructorParameter() throws Exception { doTest(); }
+ public void testStringBufferNonNls() throws Exception { doTest(); }
+ public void testEnum() throws Exception {
+ final JavaPsiFacade facade = getJavaFacade();
+ final LanguageLevel effectiveLanguageLevel = LanguageLevelProjectExtension.getInstance(facade.getProject()).getLanguageLevel();
+ LanguageLevelProjectExtension.getInstance(facade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
+ try {
+ doTest();
+ }
+ finally {
+ LanguageLevelProjectExtension.getInstance(facade.getProject()).setLanguageLevel(effectiveLanguageLevel);
+ }
+ }
+
+ public void testFormTabbedPaneTitle() throws Exception { doTest(); }
+ public void testVarargNonNlsParameter() throws Exception { doTest(); }
+ public void testInitializerInAnonymousClass() throws Exception{ doTest(); }
+ public void testNonNlsArray() throws Exception{ doTest(); }
+ public void testParameterInNewAnonymousClass() throws Exception{ doTest(); }
+ public void testConstructorCallOfNonNlsVariable() throws Exception{ doTest(); }
+ public void testSwitchOnNonNlsString() throws Exception{ doTest(); }
+ public void testNonNlsComment() throws Exception{
+ I18nInspection inspection = new I18nInspection();
+ inspection.nonNlsCommentPattern = "MYNON-NLS";
+ inspection.cacheNonNlsCommentPattern();
+ doTest(inspection);
+ }
+ public void testAnnotationArgument() throws Exception{ doTest(); }
+
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("java-i18n") + "/testData/inspections";
+ }
+}
diff --git a/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspectionTest.java b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspectionTest.java
new file mode 100644
index 000000000000..e5e9c9695f6a
--- /dev/null
+++ b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/InvalidPropertyKeyInspectionTest.java
@@ -0,0 +1,33 @@
+package com.intellij.codeInspection.i18n;
+
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.ide.startup.impl.StartupManagerImpl;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.impl.ModuleManagerImpl;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.InspectionTestCase;
+
+public class InvalidPropertyKeyInspectionTest extends InspectionTestCase {
+ private void doTest() throws Exception {
+ LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(new InvalidPropertyKeyInspection());
+ doTest("invalidPropertyKey/" + getTestName(true), tool, "java 1.5");
+ }
+
+ @Override
+ protected void setupRootModel(final String testDir, final VirtualFile[] sourceDir, final String jdkName) {
+ super.setupRootModel(testDir, sourceDir, jdkName);
+ ((ModuleManagerImpl)ModuleManager.getInstance(getProject())).projectOpened();
+ ((StartupManagerImpl)StartupManager.getInstance(getProject())).runPostStartupActivities();
+ }
+
+ public void testSimple() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("java-i18n") + "/testData/inspections";
+ }
+}
diff --git a/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/UnusedMessageFormatParameterInspectionTest.java b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/UnusedMessageFormatParameterInspectionTest.java
new file mode 100644
index 000000000000..0b8138a31172
--- /dev/null
+++ b/plugins/java-i18n/testSrc/com/intellij/codeInspection/i18n/UnusedMessageFormatParameterInspectionTest.java
@@ -0,0 +1,36 @@
+package com.intellij.codeInspection.i18n;
+
+import com.intellij.lang.properties.UnusedMessageFormatParameterInspection;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.InspectionTestCase;
+
+/**
+ * User: anna
+ * Date: 09-Sep-2005
+ */
+public class UnusedMessageFormatParameterInspectionTest extends InspectionTestCase {
+ private void doTest() throws Exception {
+ doTest("unusedParameter/" + getTestName(true), new UnusedMessageFormatParameterInspection());
+ }
+
+ public void testSimpleString() throws Exception {
+ doTest();
+ }
+
+ public void testCorruptedValue() throws Exception{
+ doTest();
+ }
+
+ public void testWithChoiceFormat() throws Exception{
+ doTest();
+ }
+
+ public void testRegexp() throws Exception {
+ doTest();
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("java-i18n") + "/testData/inspections";
+ }
+}
diff --git a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar
index b18abec35c9b..1e9d59a57086 100644
--- a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar
+++ b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar
Binary files differ
diff --git a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java
index 65b15576c6a3..ba484bf35fa3 100644
--- a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java
+++ b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java
@@ -120,8 +120,12 @@ public class SceneBuilderImpl implements SceneBuilder {
@Override
public void close() {
if (myEditorController != null) {
- myEditorController.getSelection().revisionProperty().removeListener(mySelectionListener);
- myEditorController.getJobManager().revisionProperty().removeListener(myListener);
+ if (mySelectionListener != null) {
+ myEditorController.getSelection().revisionProperty().removeListener(mySelectionListener);
+ }
+ if (myListener != null) {
+ myEditorController.getJobManager().revisionProperty().removeListener(myListener);
+ }
}
}
diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
index 7d902cfbae0f..840151315836 100644
--- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
+++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
@@ -87,6 +87,10 @@ public class JavaFXHighlightingTest extends AbstractJavaFXTestCase {
doTestIdController();
}
+ public void testEventHandlers() throws Exception {
+ myFixture.testHighlighting(false, false, false, getTestName(true) + ".fxml");
+ }
+
public void testPackageLocalController() throws Exception {
doTest(getTestName(false) + ".java");
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
index 3274603f3fc0..ea482b0d0ce7 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
@@ -270,6 +270,14 @@ public class JavaFxPsiUtil {
if (!(currentTagClass instanceof PsiClass)) return false;
final PsiField handlerField = ((PsiClass)currentTagClass).findFieldByName(attributeName, true);
if (handlerField == null) {
+ final String suggestedSetterName = PropertyUtil.suggestSetterName(attributeName);
+ final PsiMethod[] existingSetters = ((PsiClass)currentTagClass).findMethodsByName(suggestedSetterName, true);
+ for (PsiMethod setter : existingSetters) {
+ final PsiParameter[] parameters = setter.getParameterList().getParameters();
+ if (parameters.length == 1 && InheritanceUtil.isInheritor(parameters[0].getType(), JavaFxCommonClassNames.JAVAFX_EVENT_EVENT_HANDLER)) {
+ return true;
+ }
+ }
return false;
}
final PsiClass objectPropertyClass = getPropertyClass(handlerField);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java
index 9c3fe6914a73..01dc2e06e364 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/intentions/JavaFxInjectPageLanguageIntention.java
@@ -35,6 +35,7 @@ import com.intellij.psi.xml.XmlProcessingInstruction;
import com.intellij.psi.xml.XmlProlog;
import com.intellij.ui.components.JBList;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.NotNull;
@@ -130,6 +131,9 @@ public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAc
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ if (ContainerUtil.isEmpty(getAvailableLanguages(project))) {
+ return false;
+ }
setText(getFamilyName());
return element.isValid();
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java
index 3f2f0344049c..98c7f067630c 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java
@@ -235,7 +235,7 @@ public class JavaFxClassBackedElementDescriptor implements XmlElementDescriptor,
}
private <T> void collectProperties(final List<T> children, final Function<PsiMember, T> factory, final boolean acceptPrimitive) {
- final List<PsiMember> fieldList =
+ final List<PsiMember> fieldList = myPsiClass == null ? null :
CachedValuesManager.getCachedValue(myPsiClass, new CachedValueProvider<List<PsiMember>>() {
@Nullable
@Override
@@ -273,10 +273,8 @@ public class JavaFxClassBackedElementDescriptor implements XmlElementDescriptor,
private boolean acceptablePropertyType(PsiType fieldType) {
return fieldType.equalsToText(CommonClassNames.JAVA_LANG_STRING) ||
(acceptPrimitive && fieldType instanceof PsiPrimitiveType) ||
- InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_OBSERVABLE_LIST_PROPERTY) && JavaGenericsUtil
- .getCollectionItemType(
- fieldType, myPsiClass
- .getResolveScope()) != null;
+ InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_OBSERVABLE_LIST_PROPERTY) && JavaGenericsUtil.getCollectionItemType(fieldType, myPsiClass.getResolveScope()) != null ||
+ InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_EVENT_EVENT_HANDLER);
}
});
if (fieldList != null) {
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
index baaa54da2d77..454022ae3448 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
@@ -41,7 +41,7 @@ public class FxmlReferencesContributor extends PsiReferenceContributor {
public static final JavaClassReferenceProvider CLASS_REFERENCE_PROVIDER = new JavaClassReferenceProvider();
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
final XmlAttributeValuePattern attributeValueInFxml = XmlPatterns.xmlAttributeValue().inVirtualFile(
virtualFile().withExtension(JavaFxFileTypeFactory.FXML_EXTENSION));
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_CONTROLLER))
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java
index 46e73c213558..f6e64f068547 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java
@@ -22,6 +22,7 @@ import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.position.FilterPattern;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.JavaFxFileReferenceProvider;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
@@ -125,7 +126,7 @@ public class JavaFxReferencesContributor extends PsiReferenceContributor {
}));
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(FXML_PATTERN, new JavaFxFileReferenceProvider(JavaFxFileTypeFactory.FXML_EXTENSION));
registrar.registerReferenceProvider(STYLESHEET_PATTERN, new JavaFxFileReferenceProvider("css") {
@Override
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java
index 97832c4888f7..c20e4d9336ba 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderCreatorImpl.java
@@ -96,6 +96,13 @@ public class SceneBuilderCreatorImpl implements SceneBuilderCreator {
urls.add(new File(home, "plugins/JavaFX/FxBuilderEmbedder/lib/embedder.jar").toURI().toURL());
}
}
+
+ final String rtPath = PathUtil.getJarPathForClass(String.class);
+ final File javaFxJar = new File(new File(new File(rtPath).getParentFile(), "ext"), "jfxrt.jar");
+ if (javaFxJar.isFile()) {
+ urls.add(javaFxJar.toURI().toURL());
+ }
+
return new URLClassLoader(urls.toArray(new URL[urls.size()]), SceneBuilderCreatorImpl.class.getClassLoader());
}
} \ No newline at end of file
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java
index ae36f912a177..f0c1eccd86f1 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderEditor.java
@@ -13,6 +13,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.HyperlinkLabel;
import org.jetbrains.annotations.NotNull;
@@ -24,7 +25,6 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.beans.PropertyChangeListener;
import java.io.File;
-import java.net.URL;
/**
* @author Alexander Lobas
@@ -49,7 +49,6 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
private final ExternalChangeListener myChangeListener;
private SceneBuilderCreator myBuilderCreator;
- private URL myFileURL;
private SceneBuilder mySceneBuilder;
public SceneBuilderEditor(@NotNull Project project, @NotNull VirtualFile file, SceneBuilderProvider creatorProvider) {
@@ -99,7 +98,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
myErrorLabel.setHyperlinkText("Error: " + e.getMessage(), "", "");
myErrorLabel.setIcon(Messages.getErrorIcon());
- LOG.error(e);
+ LOG.info(e);
}
myLayout.show(myPanel, ERROR_CARD);
}
@@ -109,6 +108,11 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
if (mySceneBuilder != null) {
+
+ if (!myDocument.isWritable() && ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(myFile).hasReadonlyFiles()) {
+ return;
+ }
+
try {
myChangeListener.setRunState(false);
@@ -172,11 +176,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
try {
FileDocumentManager.getInstance().saveDocument(myDocument);
- if (myFileURL == null) {
- myFileURL = new File(myFile.getPath()).toURI().toURL();
- }
-
- mySceneBuilder = myBuilderCreator.create(myFileURL, this);
+ mySceneBuilder = myBuilderCreator.create(new File(myFile.getPath()).toURI().toURL(), this);
myPanel.add(mySceneBuilder.getPanel(), SCENE_CARD);
myLayout.show(myPanel, SCENE_CARD);
@@ -188,13 +188,6 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
}
}
- private void updateSceneBuilder() {
- if (mySceneBuilder != null) {
- FileDocumentManager.getInstance().saveDocument(myDocument);
- mySceneBuilder.reloadFile();
- }
- }
-
private void removeSceneBuilder() {
myChangeListener.stop();
@@ -317,7 +310,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
public void checkContent() {
if (!myRunState && !myDocument.getText().equals(myContent)) {
- updateSceneBuilder();
+ addSceneBuilder();
start();
}
}
@@ -325,7 +318,7 @@ public class SceneBuilderEditor extends UserDataHolderBase implements FileEditor
@Override
public void documentChanged(DocumentEvent e) {
if (myRunState) {
- updateSceneBuilder();
+ addSceneBuilder();
}
}
}
diff --git a/plugins/javaFX/testData/highlighting/eventHandlers.fxml b/plugins/javaFX/testData/highlighting/eventHandlers.fxml
new file mode 100644
index 000000000000..e54a756ceee1
--- /dev/null
+++ b/plugins/javaFX/testData/highlighting/eventHandlers.fxml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.control.*?>
+
+<GridPane xmlns:fx="http://javafx.com/fxml">
+ <Button fx:id="btn" onMouseClicked=<error descr="No controller specified for top level element">"#foo"</error>/>
+</GridPane> \ No newline at end of file
diff --git a/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java b/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java
index 89590887cbbb..274c2797540d 100644
--- a/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java
+++ b/plugins/junit/src/com/intellij/execution/ConfigurationUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,17 +19,12 @@ package com.intellij.execution;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.execution.junit.TestClassFilter;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.PsiElementProcessor;
-import com.intellij.psi.search.PsiElementProcessorAdapter;
-import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiUtilCore;
@@ -47,7 +42,7 @@ public class ConfigurationUtil {
final Project project = manager.getProject();
GlobalSearchScope projectScopeWithoutLibraries = GlobalSearchScope.projectScope(project);
final GlobalSearchScope scope = projectScopeWithoutLibraries.intersectWith(testClassFilter.getScope());
- ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
+ ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true, true, false).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull final PsiClass aClass) {
if (testClassFilter.isAccepted(aClass)) found.add(aClass);
return true;
@@ -113,7 +108,7 @@ public class ConfigurationUtil {
found.add(containingClass);
isJUnit4.set(Boolean.TRUE);
}
- ClassInheritorsSearch.search(containingClass, scope, true)
+ ClassInheritorsSearch.search(containingClass, scope, true, true, false)
.forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull final PsiClass aClass) {
if (testClassFilter.isAccepted(aClass)) {
diff --git a/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java b/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java
index b99c2f0c91ba..843e81e457a6 100644
--- a/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java
+++ b/plugins/junit/src/com/intellij/execution/junit/TestDirectory.java
@@ -31,7 +31,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.GlobalSearchScopes;
+import com.intellij.psi.search.GlobalSearchScopesCore;
import java.util.Collection;
@@ -53,8 +53,7 @@ class TestDirectory extends TestPackage {
public SourceScope getSourceScope() {
final String dirName = myConfiguration.getPersistentData().getDirName();
final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(dirName));
- final GlobalSearchScope globalSearchScope = file == null ? GlobalSearchScope.EMPTY_SCOPE : GlobalSearchScopes
- .directoryScope(myProject, file, true);
+ final GlobalSearchScope globalSearchScope = file == null ? GlobalSearchScope.EMPTY_SCOPE : GlobalSearchScopesCore.directoryScope(myProject, file, true);
return new SourceScope() {
@Override
public GlobalSearchScope getGlobalSearchScope() {
@@ -69,8 +68,7 @@ class TestDirectory extends TestPackage {
@Override
public GlobalSearchScope getLibrariesScope() {
final Module module = myConfiguration.getConfigurationModule().getModule();
- LOG.assertTrue(module != null);
- return GlobalSearchScope.moduleWithLibrariesScope(module);
+ return module != null ? GlobalSearchScope.moduleWithLibrariesScope(module) : GlobalSearchScope.allScope(myProject);
}
@Override
diff --git a/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java b/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java
index c4954f09b1dc..7277c5e5369d 100644
--- a/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java
+++ b/plugins/junit/src/com/intellij/execution/junit/TestsPattern.java
@@ -44,7 +44,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
-import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -69,7 +68,7 @@ public class TestsPattern extends TestPackage {
public Task findTests() {
final JUnitConfiguration.Data data = myConfiguration.getPersistentData();
final Project project = myConfiguration.getProject();
- final Set<String> classNames = new HashSet<String>();
+ final Set<String> classNames = new LinkedHashSet<String>();
for (String className : data.getPatterns()) {
final PsiClass psiClass = getTestClass(project, className);
if (psiClass != null&& JUnitUtil.isTestClass(psiClass)) {
diff --git a/plugins/junit/src/com/intellij/execution/junit2/FilterCache.java b/plugins/junit/src/com/intellij/execution/junit2/FilterCache.java
index 8d00b0215661..1c04789102cb 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/FilterCache.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/FilterCache.java
@@ -45,9 +45,13 @@ class FilterCache {
return Collections.unmodifiableList(myList);
}
- public void add(final TestProxy test) {
- myList.add(test);
- mySet.add(test);
+ public void insert(TestProxy child, int idx) {
+ if (idx >= 0) {
+ myList.add(idx, child);
+ } else {
+ myList.add(child);
+ }
+ mySet.add(child);
resetCache();
}
diff --git a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java
index 412d0d18e74d..1d306493b081 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/TestProxy.java
@@ -181,11 +181,15 @@ public class TestProxy extends AbstractTestProxy {
}
public void addChild(final TestProxy child) {
+ addChild(child, -1);
+ }
+
+ public void addChild(final TestProxy child, final int idx) {
if (myChildren.contains(child))
return;
if (child.getParent() != null)
return;//todo throw new RuntimeException("Test: "+child + " already has parent: " + child.getParent());
- myChildren.add(child);
+ myChildren.insert(child, idx);
child.myParent = this;
addLast(child);
child.setPrinter(myPrinter);
@@ -194,6 +198,19 @@ public class TestProxy extends AbstractTestProxy {
myNotifier.onChildAdded(this, child);
}
+ public void insertNextRunningChild(final TestProxy child) {
+ int idx = -1;
+ List<TestProxy> list = myChildren.getList();
+ for (int i = 0; i < list.size(); i++) {
+ TestProxy proxy = list.get(i);
+ if (!proxy.getState().isFinal()) {
+ idx = i;
+ break;
+ }
+ }
+ addChild(child, idx);
+ }
+
public TestInfo getInfo() {
return myInfo;
diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java
index 95303c9a1bc2..039e5219e078 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java
@@ -178,7 +178,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable {
final TestProxy testProxy = reader.readObject();
if (testProxy.getParent() == null) { //model.getRoot() == testProxy
- getDynamicParent(myModel, testProxy).addChild(testProxy);
+ getDynamicParent(myModel, testProxy).insertNextRunningChild(testProxy);
}
final int state = reader.readInt();
diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java
index e82c79169d28..2a1eb7de6f86 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/ui/properties/JUnitConsoleProperties.java
@@ -45,6 +45,6 @@ public class JUnitConsoleProperties extends JavaAwareTestConsoleProperties {
@Override
protected GlobalSearchScope initScope() {
final SourceScope sourceScope = myConfiguration.getPersistentData().getScope().getSourceScope(myConfiguration);
- return sourceScope != null ? sourceScope.getLibrariesScope() : GlobalSearchScope.allScope(getProject());
+ return sourceScope != null ? sourceScope.getGlobalSearchScope() : GlobalSearchScope.allScope(getProject());
}
}
diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java
index ded8fa37a958..66a5943211c7 100644
--- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java
+++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java
@@ -559,10 +559,16 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
MavenProject mavenProject = result.getMavenProject();
if (mavenProject == null) return new MavenServerExecutionResult(null, problems, unresolvedArtifacts);
- MavenModel model = MavenModelConverter
- .convertModel(mavenProject.getModel(), mavenProject.getCompileSourceRoots(), mavenProject.getTestCompileSourceRoots(),
- mavenProject.getArtifacts(), (rootNode == null ? Collections.emptyList() : rootNode.getChildren()),
- mavenProject.getExtensionArtifacts(), getLocalRepositoryFile());
+ MavenModel model = null;
+ try {
+ model = MavenModelConverter
+ .convertModel(mavenProject.getModel(), mavenProject.getCompileSourceRoots(), mavenProject.getTestCompileSourceRoots(),
+ mavenProject.getArtifacts(), (rootNode == null ? Collections.emptyList() : rootNode.getChildren()),
+ mavenProject.getExtensionArtifacts(), getLocalRepositoryFile());
+ }
+ catch (Exception e) {
+ validate(mavenProject.getFile(), Collections.singleton(e), problems, null);
+ }
RemoteNativeMavenProjectHolder holder = new RemoteNativeMavenProjectHolder(mavenProject);
try {
@@ -580,26 +586,37 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
return new MavenServerExecutionResult(data, problems, unresolvedArtifacts);
}
- private static Collection<String> collectActivatedProfiles(MavenProject mavenProject) {
+ private static Collection<String> collectActivatedProfiles(MavenProject mavenProject)
+ throws RemoteException {
// for some reason project's active profiles do not contain parent's profiles - only local and settings'.
// parent's profiles do not contain settings' profiles.
List<Profile> profiles = new ArrayList<Profile>();
- while (mavenProject != null) {
- profiles.addAll(mavenProject.getActiveProfiles());
- mavenProject = mavenProject.getParent();
+ try {
+ while (mavenProject != null) {
+ profiles.addAll(mavenProject.getActiveProfiles());
+ mavenProject = mavenProject.getParent();
+ }
+ }
+ catch (Exception e) {
+ // don't bother user if maven failed to build parent project
+ Maven3ServerGlobals.getLogger().info(e);
}
return collectProfilesIds(profiles);
}
- private void validate(File file,
- Collection<Exception> exceptions,
- Collection<MavenProjectProblem> problems,
- Collection<MavenId> unresolvedArtifacts) throws RemoteException {
- for (Exception each : exceptions) {
+ private void validate(@NotNull File file,
+ @NotNull Collection<Exception> exceptions,
+ @NotNull Collection<MavenProjectProblem> problems,
+ @Nullable Collection<MavenId> unresolvedArtifacts) throws RemoteException {
+ for (Throwable each : exceptions) {
Maven3ServerGlobals.getLogger().info(each);
+ if(each instanceof IllegalStateException && each.getCause() != null) {
+ each = each.getCause();
+ }
+
if (each instanceof InvalidProjectModelException) {
ModelValidationResult modelValidationResult = ((InvalidProjectModelException)each).getValidationResult();
if (modelValidationResult != null) {
@@ -619,7 +636,9 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
problems.add(MavenProjectProblem.createStructureProblem(file.getPath(), each.getMessage()));
}
}
- unresolvedArtifacts.addAll(retrieveUnresolvedArtifactIds());
+ if (unresolvedArtifacts != null) {
+ unresolvedArtifacts.addAll(retrieveUnresolvedArtifactIds());
+ }
}
private Set<MavenId> retrieveUnresolvedArtifactIds() {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java
index 985d406d6c1b..68905ea2c3db 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenDependenciesCompletionProvider.java
@@ -17,6 +17,7 @@ import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
@@ -28,7 +29,7 @@ import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
public class MavenDependenciesCompletionProvider extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiElement xmlText = parameters.getPosition().getParent();
if (!(xmlText instanceof XmlText)) return;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java
index 8fde37fbdf79..9e28f2e60598 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenPomXmlCompletionTagListenerContributor.java
@@ -16,6 +16,7 @@ import com.intellij.util.Consumer;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileDescription;
import com.intellij.util.xml.DomManager;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenDomProjectModelDescription;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
@@ -31,7 +32,7 @@ public class MavenPomXmlCompletionTagListenerContributor extends CompletionContr
private final Set<String> myHandledTags = ImmutableSet.of("dependency");
@Override
- public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (TemplateManager.getInstance(parameters.getOriginalFile().getProject()).getActiveTemplate(parameters.getEditor()) != null) {
return; // Don't brake the template.
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenSmartCompletionContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenSmartCompletionContributor.java
index f56ec2685bd3..6284009779fe 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenSmartCompletionContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenSmartCompletionContributor.java
@@ -39,7 +39,7 @@ import java.util.Collections;
public class MavenSmartCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.SMART) return;
Collection<?> variants = getVariants(parameters);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenVersionCompletionContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenVersionCompletionContributor.java
index 9c8884676db4..f02c7ab5f92c 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenVersionCompletionContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/model/completion/MavenVersionCompletionContributor.java
@@ -46,7 +46,7 @@ import java.util.Set;
public class MavenVersionCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC) return;
PsiElement element = parameters.getPosition();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyCompletionContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyCompletionContributor.java
index 2a3d6871b4b6..d37c9ae16370 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyCompletionContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyCompletionContributor.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
@@ -33,7 +34,7 @@ import java.util.Collection;
public class MavenPropertyCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile psiFile = parameters.getOriginalFile();
Project project = psiFile.getProject();
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReferenceContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReferenceContributor.java
index 2ce633c361e4..6ea57e425bf9 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReferenceContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,11 +21,12 @@ import com.intellij.patterns.PlatformPatterns;
import com.intellij.patterns.XmlPatterns;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.MavenDomProperties;
public class MavenPropertyPsiReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
ElementPattern pattern = XmlPatterns.xmlTag().withParent(DomPatterns.withDom(DomPatterns.domElement(MavenDomProperties.class)));
registrar.registerReferenceProvider(pattern, new MavenPropertyPsiReferenceProvider(), PsiReferenceRegistrar.DEFAULT_PRIORITY);
registrar.registerReferenceProvider(PlatformPatterns.psiElement(),
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginParamReferenceContributor.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginParamReferenceContributor.java
index 298bc9f30ea9..6e7dfdf8b966 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginParamReferenceContributor.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenPluginParamReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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 @@ import static org.jetbrains.idea.maven.plugins.api.MavenPluginParamInfo.ParamInf
public class MavenPluginParamReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(
PlatformPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS).withParent(
XmlPatterns.xmlText().inFile(XmlPatterns.xmlFile().withName("pom.xml"))
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenModificationTracker.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenModificationTracker.java
index 6aa7e728e19f..a983e06cc6db 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenModificationTracker.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenModificationTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,8 +15,8 @@
*/
package org.jetbrains.idea.maven.project;
-import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.SimpleModificationTracker;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
@@ -25,55 +25,44 @@ import java.util.List;
/**
* @author Konstantin Bulenkov
*/
-public class MavenModificationTracker implements ModificationTracker {
- private long myCounter = 0;
-
+public class MavenModificationTracker extends SimpleModificationTracker {
public MavenModificationTracker(MavenProjectsManager manager) {
manager.addProjectsTreeListener(new MavenProjectsTree.Listener() {
@Override
public void profilesChanged() {
- inc();
+ incModificationCount();
}
@Override
public void projectsIgnoredStateChanged(List<MavenProject> ignored, List<MavenProject> unignored, boolean fromImport) {
- inc();
+ incModificationCount();
}
@Override
public void projectsUpdated(List<Pair<MavenProject, MavenProjectChanges>> updated, List<MavenProject> deleted) {
- inc();
+ incModificationCount();
}
@Override
public void projectResolved(Pair<MavenProject, MavenProjectChanges> projectWithChanges,
@Nullable NativeMavenProjectHolder nativeMavenProject) {
- inc();
+ incModificationCount();
}
@Override
public void pluginsResolved(MavenProject project) {
- inc();
+ incModificationCount();
}
@Override
public void foldersResolved(Pair<MavenProject, MavenProjectChanges> projectWithChanges) {
- inc();
+ incModificationCount();
}
@Override
public void artifactsDownloaded(MavenProject project) {
- inc();
+ incModificationCount();
}
});
}
-
- private void inc() {
- myCounter++;
- }
-
- @Override
- public long getModificationCount() {
- return myCounter;
- }
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
index 3ca187609ba3..499b6dd99d2d 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachDialog.java
@@ -42,7 +42,6 @@ import com.intellij.util.PairProcessor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.AsyncProcessIcon;
import com.intellij.xml.util.XmlStringUtil;
-import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,29 +62,33 @@ import java.util.List;
public class RepositoryAttachDialog extends DialogWrapper {
@NonNls private static final String PROPERTY_DOWNLOAD_TO_PATH = "Downloaded.Files.Path";
+ @NonNls private static final String PROPERTY_DOWNLOAD_TO_PATH_ENABLED = "Downloaded.Files.Path.Enabled";
@NonNls private static final String PROPERTY_ATTACH_JAVADOC = "Repository.Attach.JavaDocs";
@NonNls private static final String PROPERTY_ATTACH_SOURCES = "Repository.Attach.Sources";
+ private final Project myProject;
+
private JBLabel myInfoLabel;
private JCheckBox myJavaDocCheckBox;
private JCheckBox mySourcesCheckBox;
- private final Project myProject;
private AsyncProcessIcon myProgressIcon;
private ComboboxWithBrowseButton myComboComponent;
private JPanel myPanel;
+ private TextFieldWithBrowseButton myDirectoryField;
+ private JBCheckBox myDownloadToCheckBox;
private JBLabel myCaptionLabel;
- private final THashMap<String, Pair<MavenArtifactInfo, MavenRepositoryInfo>> myCoordinates
- = new THashMap<String, Pair<MavenArtifactInfo, MavenRepositoryInfo>>();
- private final Map<String, MavenRepositoryInfo> myRepositories = new TreeMap<String, MavenRepositoryInfo>();
- private final ArrayList<String> myShownItems = new ArrayList<String>();
+
private final JComboBox myCombobox;
- private TextFieldWithBrowseButton myDirectoryField;
- private JBCheckBox myDownloadToCheckBox;
+ private final Map<String, Pair<MavenArtifactInfo, MavenRepositoryInfo>> myCoordinates = ContainerUtil.newTroveMap();
+ private final Map<String, MavenRepositoryInfo> myRepositories = new TreeMap<String, MavenRepositoryInfo>();
+ private final List<String> myShownItems = ContainerUtil.newArrayList();
+ private final String myDefaultDownloadFolder;
+
private String myFilterString;
private boolean myInUpdate;
- public RepositoryAttachDialog(Project project, final @Nullable String initialFilter) {
+ public RepositoryAttachDialog(@NotNull Project project, final @Nullable String initialFilter) {
super(project, true);
myProject = project;
myProgressIcon.suspend();
@@ -137,29 +140,22 @@ public class RepositoryAttachDialog extends DialogWrapper {
}
}
});
+ VirtualFile baseDir = !myProject.isDefault() ? myProject.getBaseDir() : null;
+ myDefaultDownloadFolder = baseDir != null ? FileUtil.toSystemDependentName(baseDir.getPath() + "/lib") : "";
+
PropertiesComponent storage = PropertiesComponent.getInstance(myProject);
- boolean pathValueSet = storage.isValueSet(PROPERTY_DOWNLOAD_TO_PATH);
- if (pathValueSet) {
- myDownloadToCheckBox.setSelected(true);
- myDirectoryField.setText(storage.getValue(PROPERTY_DOWNLOAD_TO_PATH));
- }
- else {
- myDownloadToCheckBox.setSelected(false);
- }
+ myDownloadToCheckBox.setSelected(storage.isTrueValue(PROPERTY_DOWNLOAD_TO_PATH_ENABLED));
+ myDirectoryField.setText(StringUtil.notNullize(StringUtil.nullize(storage.getValue(PROPERTY_DOWNLOAD_TO_PATH)), myDefaultDownloadFolder));
+ myDirectoryField.setEnabled(myDownloadToCheckBox.isSelected());
myDownloadToCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myDirectoryField.setEnabled(myDownloadToCheckBox.isSelected());
}
});
- myJavaDocCheckBox.setSelected(storage.isValueSet(PROPERTY_ATTACH_JAVADOC) && storage.isTrueValue(PROPERTY_ATTACH_JAVADOC));
- mySourcesCheckBox.setSelected(storage.isValueSet(PROPERTY_ATTACH_SOURCES) && storage.isTrueValue(PROPERTY_ATTACH_SOURCES));
- if (!pathValueSet && myProject != null && !myProject.isDefault()) {
- final VirtualFile baseDir = myProject.getBaseDir();
- if (baseDir != null) {
- myDirectoryField.setText(FileUtil.toSystemDependentName(baseDir.getPath() + "/lib"));
- }
- }
+ myJavaDocCheckBox.setSelected(storage.isTrueValue(PROPERTY_ATTACH_JAVADOC));
+ mySourcesCheckBox.setSelected(storage.isTrueValue(PROPERTY_ATTACH_SOURCES));
+
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.putUserData(FileChooserDialog.PREFER_LAST_OVER_TO_SELECT, Boolean.TRUE);
myDirectoryField.addBrowseFolderListener(ProjectBundle.message("file.chooser.directory.for.downloaded.libraries.title"),
@@ -243,14 +239,15 @@ public class RepositoryAttachDialog extends DialogWrapper {
myCombobox.setPopupVisible(false);
}
if (!myCombobox.isPopupVisible()) {
- myCombobox.setPopupVisible(filtered);
+ myCombobox.setPopupVisible(true);
}
}
}
private boolean performSearch() {
final String text = getCoordinateText();
- if (myCoordinates.contains(text)) return false;
+ if (StringUtil.isEmptyOrSpaces(text)) return false;
+ if (myCoordinates.containsKey(text)) return false;
if (myProgressIcon.isRunning()) return false;
myProgressIcon.resume();
RepositoryAttachHandler.searchArtifacts(myProject, text, new PairProcessor<Collection<Pair<MavenArtifactInfo, MavenRepositoryInfo>>, Boolean>() {
@@ -317,10 +314,11 @@ public class RepositoryAttachDialog extends DialogWrapper {
@Override
protected void dispose() {
Disposer.dispose(myProgressIcon);
- final PropertiesComponent storage = PropertiesComponent.getInstance(myProject);
- if (myDownloadToCheckBox.isSelected()) {
- storage.setValue(PROPERTY_DOWNLOAD_TO_PATH, myDirectoryField.getText());
- }
+ PropertiesComponent storage = PropertiesComponent.getInstance(myProject);
+ storage.setValue(PROPERTY_DOWNLOAD_TO_PATH_ENABLED, String.valueOf(myDownloadToCheckBox.isSelected()));
+ String downloadPath = myDirectoryField.getText();
+ if (StringUtil.isEmptyOrSpaces(downloadPath)) downloadPath = myDefaultDownloadFolder;
+ storage.setValue(PROPERTY_DOWNLOAD_TO_PATH, downloadPath, myDefaultDownloadFolder);
storage.setValue(PROPERTY_ATTACH_JAVADOC, String.valueOf(myJavaDocCheckBox.isSelected()));
storage.setValue(PROPERTY_ATTACH_SOURCES, String.valueOf(mySourcesCheckBox.isSelected()));
super.dispose();
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java
index c959b6eb800f..8b33581b0eb6 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java
@@ -92,11 +92,16 @@ public abstract class MavenTestCase extends UsefulTestCase {
getMavenGeneralSettings().setMavenHome(home);
}
- restoreSettingsFile();
-
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
+ try {
+ restoreSettingsFile();
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -237,7 +242,7 @@ public abstract class MavenTestCase extends UsefulTestCase {
}
@Override
- protected void invokeTestRunnable(Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
runnable.run();
}
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/server/MavenServerManagerHelper.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/server/MavenServerManagerHelper.java
index 07478ea96aec..5aa8487d1d3c 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/server/MavenServerManagerHelper.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/server/MavenServerManagerHelper.java
@@ -15,27 +15,16 @@
*/
package org.jetbrains.idea.maven.server;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.impl.ApplicationImpl;
-
import java.rmi.RemoteException;
public class MavenServerManagerHelper {
/** {@link MavenServerManager#collectClassPathAndLibsFolder()} forces maven2 in test mode; we want maven3. */
public static MavenServer connectToMaven3Server() throws RemoteException {
- ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
MavenServerManager msm = MavenServerManager.getInstance(); // do this first, it won't work outside of unit test mode
msm.cleanup(); // in case we were previously connected to maven2
- boolean oldUnitTestMode = application.isUnitTestMode();
- application.setUnitTestMode(false);
- try {
- return msm.getOrCreateWrappee();
- }
- finally {
- application.setUnitTestMode(oldUnitTestMode);
- }
+ return msm.getOrCreateWrappee();
}
public static void disconnectFromServer() {
diff --git a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
index 0864d1e31206..06e0c2e3ae03 100644
--- a/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
+++ b/plugins/properties/properties-psi-api/resources/messages/PropertiesBundle.properties
@@ -4,7 +4,9 @@ properties.files.file.type.description=Properties files
remove.property.intention.text=Remove property
rename.bundle.enter.new.resource.bundle.base.name.prompt.text=Enter new resource bundle base name
rename.bundle.enter.new.resource.bundle.key.name.prompt.text=Enter new resource bundle key name
+rename.bundle.enter.new.resource.bundle.section.name.prompt.text=Enter new resource bundle section name
rename.resource.bundle.dialog.title=Rename Resource Bundle
+rename.resource.bundle.section.dialog.title=Rename Resource Bundle Section
rename.resource.bundle.key.dialog.title=Rename Resource Bundle Key
properties.files.inspection.group.display.name=Properties Files
unused.property.inspection.display.name=Unused Property
@@ -40,4 +42,12 @@ options.properties.attribute.descriptor.property.value=Property value
options.properties.attribute.descriptor.key.value.separator=Key/value separator
options.properties.attribute.descriptor.comment=Comment
options.properties.attribute.descriptor.valid.string.escape=Valid string escape
-options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape \ No newline at end of file
+options.properties.attribute.descriptor.invalid.string.escape=Invalid string escape
+
+new.property.dialog.title=New Property Key
+new.property.dialog.name.prompt.text=Enter new property key name
+
+resource.bundle.renamer=Rename resource bundle properties files
+resource.bundle.renamer.dialog.description=Rename resource bundle properties files with the following names to:
+resource.bundle.renamer.entity.name=Resource bundle
+resource.bundle.renamer.option=Rename bound &resource bundle \ No newline at end of file
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java
index 17858a2ca77d..a343ad34b477 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/EmptyResourceBundle.java
@@ -18,6 +18,7 @@ package com.intellij.lang.properties;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@@ -31,16 +32,30 @@ public class EmptyResourceBundle {
private static class Holder {
private static final ResourceBundle NULL = new ResourceBundle() {
@NotNull
- public List<PropertiesFile> getPropertiesFiles(final Project project) {
+ @Override
+ public List<PropertiesFile> getPropertiesFiles() {
return Collections.emptyList();
}
@NotNull
- public PropertiesFile getDefaultPropertiesFile(final Project project) {
+ @Override
+ public List<PropertiesFile> getPropertiesFiles(final Project project) {
+ return getPropertiesFiles();
+ }
+
+ @NotNull
+ @Override
+ public PropertiesFile getDefaultPropertiesFile() {
throw new IllegalStateException();
}
@NotNull
+ @Override
+ public PropertiesFile getDefaultPropertiesFile(final Project project) {
+ return getDefaultPropertiesFile();
+ }
+
+ @NotNull
public String getBaseName() {
return "";
}
@@ -49,6 +64,12 @@ public class EmptyResourceBundle {
public VirtualFile getBaseDirectory() {
throw new IllegalStateException();
}
+
+ @NotNull
+ @Override
+ public Project getProject() {
+ throw new IllegalStateException();
+ }
};
}
public static ResourceBundle getInstance() {
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
index abc281f7ea82..bb9b9449166f 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,12 +38,20 @@ import java.util.regex.Pattern;
* @author cdr
*/
public class PropertiesUtil {
- private final static Pattern LOCALE_PATTERN = Pattern.compile("(_[^\\._]{2}(_[^\\._]+){0,2})\\.[^_]+$");
+ private final static Pattern LOCALE_PATTERN = Pattern.compile("(_[a-zA-Z]{2,8}(_[a-zA-Z]{2}|[0-9]{3})?(_[\\w\\-]+)?)\\.[^_]+$");
private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
- public static boolean isPropertyComplete(final Project project, ResourceBundle resourceBundle, String propertyName) {
- List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles(project);
+ /**
+ * @deprecated use PropertiesUtil.isPropertyComplete(ResourceBundle resourceBundle, String propertyName)
+ */
+ @Deprecated
+ public static boolean isPropertyComplete(final Project project, final ResourceBundle resourceBundle, final String propertyName) {
+ return isPropertyComplete(resourceBundle, propertyName);
+ }
+
+ public static boolean isPropertyComplete(final ResourceBundle resourceBundle, final String propertyName) {
+ List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
for (PropertiesFile propertiesFile : propertiesFiles) {
if (propertiesFile.findPropertyByKey(propertyName) == null) return false;
}
@@ -50,8 +59,13 @@ public class PropertiesUtil {
}
@NotNull
- public static String getBaseName(@NotNull VirtualFile virtualFile) {
- String name = virtualFile.getName();
+ public static String getBaseName(@NotNull PsiFile file) {
+ return getBaseName(file.getContainingFile().getVirtualFile());
+ }
+
+ @NotNull
+ public static String getBaseName(@NotNull VirtualFile file) {
+ final String name = file.getName();
final Matcher matcher = LOCALE_PATTERN.matcher(name);
final String baseNameWithExtension;
if (matcher.find()) {
@@ -92,10 +106,10 @@ public class PropertiesUtil {
}
@Nullable
- public static String getFullName(final PropertiesFile psiFile) {
+ public static String getFullName(final PropertiesFile propertiesFile) {
return ApplicationManager.getApplication().runReadAction(new NullableComputable<String>() {
public String compute() {
- PsiDirectory directory = psiFile.getParent();
+ PsiDirectory directory = propertiesFile.getParent();
String packageQualifiedName = getPackageQualifiedName(directory);
if (packageQualifiedName == null) {
return null;
@@ -104,9 +118,7 @@ public class PropertiesUtil {
if (qName.length() > 0) {
qName.append(".");
}
- final VirtualFile virtualFile = psiFile.getVirtualFile();
- assert virtualFile != null;
- qName.append(getBaseName(virtualFile));
+ qName.append(getBaseName(propertiesFile.getContainingFile()));
return qName.toString();
}
});
@@ -132,7 +144,7 @@ public class PropertiesUtil {
@NotNull
public static List<IProperty> findAllProperties(Project project, @NotNull ResourceBundle resourceBundle, String key) {
List<IProperty> result = new SmartList<IProperty>();
- List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles(project);
+ List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
for (PropertiesFile propertiesFile : propertiesFiles) {
result.addAll(propertiesFile.findPropertiesByKey(key));
}
diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
index d4a43a522b04..7ea56269949d 100644
--- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
+++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/ResourceBundle.java
@@ -26,6 +26,7 @@ import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -34,9 +35,23 @@ public abstract class ResourceBundle {
public static final DataKey<ResourceBundle[]> ARRAY_DATA_KEY = DataKey.create("resource.bundle.array");
@NotNull
+ public abstract List<PropertiesFile> getPropertiesFiles();
+
+ /**
+ * @deprecated, use getPropertiesFiles() instead this method
+ */
+ @Deprecated
+ @NotNull
public abstract List<PropertiesFile> getPropertiesFiles(final Project project);
@NotNull
+ public abstract PropertiesFile getDefaultPropertiesFile();
+
+ /**
+ * @deprecated, use getDefaultPropertiesFile() instead this method
+ */
+ @Deprecated
+ @NotNull
public abstract PropertiesFile getDefaultPropertiesFile(final Project project);
@NotNull
@@ -44,4 +59,7 @@ public abstract class ResourceBundle {
@NotNull
public abstract VirtualFile getBaseDirectory();
+
+ @NotNull
+ public abstract Project getProject();
}
diff --git a/plugins/properties/properties-psi-impl/src/META-INF/PropertiesPlugin.xml b/plugins/properties/properties-psi-impl/src/META-INF/PropertiesPlugin.xml
deleted file mode 100644
index 6b2c0c71af46..000000000000
--- a/plugins/properties/properties-psi-impl/src/META-INF/PropertiesPlugin.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<idea-plugin version="2">
- <id>com.intellij.properties</id>
- <name>Properties Support</name>
- <depends>com.intellij.modules.xml</depends>
- <description>
- This plugin enables smart editing of properties files.
- </description>
- <vendor>JetBrains</vendor>
-
- <extensionPoints>
- <extensionPoint name="implicitPropertyUsageProvider" interface="com.intellij.codeInspection.unused.ImplicitPropertyUsageProvider"/>
- </extensionPoints>
-
- <extensions defaultExtensionNs="com.intellij">
- <typeIcon className="com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile" icon="AllIcons.Nodes.ResourceBundle"/>
- <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
- <applicationService serviceInterface="com.intellij.lang.properties.LastSelectedPropertiesFileStore"
- serviceImplementation="com.intellij.lang.properties.LastSelectedPropertiesFileStore"/>
- <applicationService serviceInterface="com.intellij.lang.properties.PropertiesQuickFixFactory"
- serviceImplementation="com.intellij.lang.properties.PropertiesQuickFixFactoryImpl"/>
- <applicationService
- serviceImplementation="com.intellij.lang.properties.refactoring.PropertiesRefactoringSettings"/>
- <annotator language="Properties" implementationClass="com.intellij.lang.properties.PropertiesAnnotator"/>
- <completion.contributor language="any" implementationClass="com.intellij.lang.properties.references.PropertiesCompletionContributor"
- id="propertiesCompletion" order="before javaClassReference"/>
- <lang.refactoringSupport language="Properties" implementationClass="com.intellij.lang.properties.refactoring.PropertiesRefactoringSupportProvider"/>
- <lang.documentationProvider language="Properties" implementationClass="com.intellij.lang.properties.PropertiesDocumentationProvider"/>
- <lang.findUsagesProvider language="Properties"
- implementationClass="com.intellij.lang.properties.findUsages.PropertiesFindUsagesProvider"/>
- <lang.elementManipulator forClass="com.intellij.lang.properties.psi.impl.PropertyValueImpl"
- implementationClass="com.intellij.lang.properties.PropertyValueManipulator"/>
- <lang.elementManipulator forClass="com.intellij.lang.properties.psi.impl.PropertyImpl"
- implementationClass="com.intellij.lang.properties.PropertyManipulator"/>
- <applicationService serviceInterface="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"
- serviceImplementation="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"/>
- <codeInsight.wordCompletionFilter language="Properties"
- implementationClass="com.intellij.lang.properties.PropertiesWordCompletionFilter"/>
- <lang.psiStructureViewFactory language="Properties"
- implementationClass="com.intellij.lang.properties.structureView.PropertiesStructureViewBuilderFactory"/>
- <lang.ast.factory language="Properties" implementationClass="com.intellij.lang.properties.psi.impl.PropertiesASTFactory"/>
- <joinLinesHandler implementation="com.intellij.lang.properties.PropertiesJoinLinesHandler"/>
-
- <enterHandlerDelegate implementation="com.intellij.codeInsight.editorActions.enter.EnterInPropertiesFileHandler"/>
-
- <lang.parserDefinition language="Properties" implementationClass="com.intellij.lang.properties.parsing.PropertiesParserDefinition"/>
- <renameHandler implementation="com.intellij.lang.properties.refactoring.ResourceBundleRenameHandler"/>
- <renameHandler implementation="com.intellij.lang.properties.refactoring.ResourceBundleKeyRenameHandler"/>
- <renameHandler implementation="com.intellij.lang.properties.refactoring.PropertyRenameHandler"/>
- <stubElementTypeHolder class="com.intellij.lang.properties.parsing.PropertiesElementTypes"/>
- <renamePsiElementProcessor implementation="com.intellij.lang.properties.refactoring.RenamePropertyProcessor"/>
- <lang.commenter language="Properties" implementationClass="com.intellij.lang.properties.PropertiesCommenter"/>
- <stubIndex implementation="com.intellij.lang.properties.psi.PropertyKeyIndex"/>
- <lang.namesValidator language="Properties" implementationClass="com.intellij.lang.properties.PropertiesNamesValidator"/>
- <refactoring.safeDeleteProcessor implementation="com.intellij.lang.properties.refactoring.PropertiesSafeDeleteProcessor"/>
- <refactoring.moveHandler implementation="com.intellij.lang.properties.projectView.ResourceBundleMoveProvider"/>
- <colorSettingsPage implementation="com.intellij.openapi.options.colors.pages.PropertiesColorsPage"/>
- <treeStructureProvider implementation="com.intellij.lang.properties.projectView.ResourceBundleGrouper"/>
- <elementDescriptionProvider implementation="com.intellij.lang.properties.PropertiesDescriptionProvider"/>
- <fileTypeFactory implementation="com.intellij.lang.properties.PropertiesFileTypeFactory"/>
- <fileTypeFactory implementation="com.intellij.lang.properties.editor.ResourceBundleEditorProvider" />
- <favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.ResourcesFavoriteNodeProvider"/>
-
- <localInspection language="Properties" shortName="UnusedProperty" bundle="messages.PropertiesBundle" key="unused.property.inspection.display.name"
- groupKey="properties.files.inspection.group.display.name" enabledByDefault="true" level="WARNING"
- implementationClass="com.intellij.codeInspection.unused.UnusedPropertyInspection"/>
- <globalInspection shortName="DuplicatePropertyInspection" bundle="messages.InspectionsBundle" key="duplicate.property.display.name"
- groupKey="group.names.properties.files" enabledByDefault="false" level="WARNING"
- implementationClass="com.intellij.codeInspection.duplicatePropertyInspection.DuplicatePropertyInspection"/>
- <localInspection language="Properties" shortName="TrailingSpacesInProperty" bundle="messages.PropertiesBundle"
- key="trail.spaces.property.inspection.display.name" groupKey="properties.files.inspection.group.display.name"
- enabledByDefault="true" level="WARNING"
- implementationClass="com.intellij.codeInspection.TrailingSpacesInPropertyInspection"/>
-
- <idIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesIdIndexer"/>
- <todoIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesTodoIndexer"/>
-
- <projectService serviceImplementation="com.intellij.lang.properties.PropertiesReferenceManager"/>
-
- <fileEditorProvider implementation="com.intellij.lang.properties.editor.ResourceBundleEditorProvider"/>
- <spellchecker.support language="Properties" implementationClass="com.intellij.lang.properties.spellchecker.PropertiesSpellcheckingStrategy"/>
-
- <fileBasedIndex implementation="com.intellij.lang.properties.xml.XmlPropertiesIndex"/>
- <standardResource url="http://java.sun.com/dtd/properties.dtd" path="schemas/properties.dtd"/>
- <iconProvider implementation="com.intellij.lang.properties.xml.XmlPropertiesIconProvider"/>
- <psi.referenceContributor language="XML" implementation="com.intellij.lang.properties.xml.XmlPropertiesReferenceContributor"/>
- <lang.foldingBuilder language="Properties" implementationClass="com.intellij.lang.properties.editor.PropertiesFoldingBuilder" />
- <gotoRelatedProvider implementation="com.intellij.lang.properties.editor.GotoResourceBundleLocalizationsProvider"/>
- </extensions>
-
- <project-components>
- <component>
- <implementation-class>com.intellij.lang.properties.PropertiesFilesManager</implementation-class>
- <skipForDefaultProject/>
- </component>
- </project-components>
-</idea-plugin>
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
index 43ffb513a4b2..ebe28b38b37e 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/BundleNameEvaluator.java
@@ -15,7 +15,6 @@
*/
package com.intellij.lang.properties;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.Nullable;
@@ -26,11 +25,6 @@ public interface BundleNameEvaluator {
@Nullable
public String evaluateBundleName(final PsiFile psiFile) {
- final VirtualFile virtualFile = psiFile == null ? null : psiFile.getOriginalFile().getVirtualFile();
- if (virtualFile == null) {
- return null;
- }
-
final PsiDirectory directory = psiFile.getParent();
if (directory == null) {
return null;
@@ -43,7 +37,7 @@ public interface BundleNameEvaluator {
if (qName.length() > 0) {
qName.append(".");
}
- qName.append(PropertiesUtil.getBaseName(virtualFile));
+ qName.append(PropertiesUtil.getBaseName(psiFile));
return qName.toString();
}
return null;
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
index 118437e942aa..5908219098b7 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java
@@ -23,44 +23,64 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
/**
* @author Konstantin Bulenkov
*/
public class PropertiesImplUtil extends PropertiesUtil {
- public static ResourceBundle getResourceBundle(final PsiFile containingFile) {
- VirtualFile virtualFile = containingFile.getVirtualFile();
- if (!containingFile.isValid() || virtualFile == null) {
+
+ @Nullable
+ public static ResourceBundle getResourceBundle(@NotNull final PropertiesFile representative) {
+ final PsiFile containingFile = representative.getContainingFile();
+ if (!containingFile.isValid()) {
return EmptyResourceBundle.getInstance();
}
- String baseName = getBaseName(virtualFile);
- PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
+ final String baseName = getBaseName(containingFile);
+ final PsiDirectory directory = ApplicationManager.getApplication().runReadAction(new Computable<PsiDirectory>() {
@Nullable
public PsiDirectory compute() {
return containingFile.getContainingDirectory();
}});
if (directory == null) return EmptyResourceBundle.getInstance();
+ return getResourceBundle(baseName, directory);
+ }
- return new ResourceBundleImpl(directory.getVirtualFile(), baseName);
+ @Nullable
+ private static ResourceBundle getResourceBundle(@NotNull final String baseName, @NotNull final PsiDirectory baseDirectory) {
+ PropertiesFile defaultPropertiesFile = null;
+ for (final PsiFile psiFile : baseDirectory.getFiles()) {
+ if (baseName.equals(getBaseName(psiFile))) {
+ final PropertiesFile propertiesFile = getPropertiesFile(psiFile);
+ if (propertiesFile != null) {
+ if (defaultPropertiesFile == null || defaultPropertiesFile.getName().compareTo(propertiesFile.getName()) < 0) {
+ defaultPropertiesFile = propertiesFile;
+ }
+ }
+ }
+ }
+ if (defaultPropertiesFile == null) {
+ return null;
+ }
+ return new ResourceBundleImpl(defaultPropertiesFile);
}
- public static boolean isPropertiesFile(VirtualFile file, Project project) {
+ public static boolean isPropertiesFile(@NotNull VirtualFile file, @NotNull Project project) {
return getPropertiesFile(PsiManager.getInstance(project).findFile(file)) != null;
}
- public static boolean isPropertiesFile(PsiFile file) {
+ public static boolean isPropertiesFile(@Nullable PsiFile file) {
return getPropertiesFile(file) != null;
}
@@ -70,8 +90,6 @@ public class PropertiesImplUtil extends PropertiesUtil {
return file instanceof PropertiesFile ? (PropertiesFile)file : XmlPropertiesFileImpl.getPropertiesFile(file);
}
-
-
@NotNull
public static List<IProperty> findPropertiesByKey(final Project project, final String key) {
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
@@ -94,4 +112,23 @@ public class PropertiesImplUtil extends PropertiesUtil {
return properties;
}
+ @Nullable
+ public static ResourceBundle createByUrl(final @NotNull String url, final @NotNull Project project) {
+ if (!url.startsWith(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX)) return null;
+
+ final String defaultPropertiesUrl = url.substring(ResourceBundleImpl.RESOURCE_BUNDLE_PREFIX.length());
+ final int idx = defaultPropertiesUrl.lastIndexOf('/');
+ if (idx == -1) return null;
+ final String baseDirectoryName = defaultPropertiesUrl.substring(0, idx);
+ final String baseName = defaultPropertiesUrl.substring(idx + 1);
+ final VirtualFile baseDirectoryVirtualFile = VirtualFileManager.getInstance().findFileByUrl(baseDirectoryName);
+ if (baseDirectoryVirtualFile == null) {
+ return null;
+ }
+ final PsiFile baseDirectory = PsiManager.getInstance(project).findFile(baseDirectoryVirtualFile);
+ if (baseDirectory == null || !(baseDirectory instanceof PsiDirectory)) {
+ return null;
+ }
+ return getResourceBundle(baseName, (PsiDirectory)baseDirectory);
+ }
}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
index 1ac96a96f6af..d257824166e9 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/ResourceBundleImpl.java
@@ -23,36 +23,32 @@ import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import java.util.Comparator;
import java.util.List;
public class ResourceBundleImpl extends ResourceBundle {
- @NonNls private static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:";
- @NotNull protected final VirtualFile myBaseDirectory;
- @NotNull protected final String myBaseName;
+ @NonNls public static final String RESOURCE_BUNDLE_PREFIX = "resourceBundle:";
+ @NotNull private final PropertiesFile myDefaultPropertiesFile;
- public ResourceBundleImpl(@NotNull VirtualFile baseDirectory, @NotNull String baseName) {
- myBaseDirectory = baseDirectory;
- myBaseName = baseName;
+ public ResourceBundleImpl(@NotNull final PropertiesFile defaultPropertiesFile) {
+ myDefaultPropertiesFile = defaultPropertiesFile;
}
@NotNull
- public List<PropertiesFile> getPropertiesFiles(final Project project) {
- VirtualFile[] children = myBaseDirectory.getChildren();
+ @Override
+ public List<PropertiesFile> getPropertiesFiles() {
+ PsiFile[] children = myDefaultPropertiesFile.getParent().getFiles();
+ final String baseName = getBaseName();
List<PropertiesFile> result = new SmartList<PropertiesFile>();
- PsiManager psiManager = PsiManager.getInstance(project);
- for (VirtualFile file : children) {
- if (!file.isValid() || file.getExtension() == null) continue;
- if (Comparing.strEqual(PropertiesUtil.getBaseName(file), myBaseName)) {
- PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(file));
+ for (PsiFile file : children) {
+ if (!file.isValid() || file.getVirtualFile().getExtension() == null) continue;
+ if (Comparing.strEqual(PropertiesUtil.getBaseName(file), baseName)) {
+ PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
if (propertiesFile != null) {
result.add(propertiesFile);
}
@@ -62,20 +58,38 @@ public class ResourceBundleImpl extends ResourceBundle {
}
@NotNull
+ @Override
+ public List<PropertiesFile> getPropertiesFiles(final Project project) {
+ return getPropertiesFiles();
+ }
+
+ @NotNull
+ @Override
+ public PropertiesFile getDefaultPropertiesFile() {
+ return myDefaultPropertiesFile;
+ }
+
+ @NotNull
+ @Override
public PropertiesFile getDefaultPropertiesFile(final Project project) {
- List<PropertiesFile> files = getPropertiesFiles(project);
- // put default properties file first
- ContainerUtil.quickSort(files, new Comparator<PropertiesFile>() {
- public int compare(final PropertiesFile o1, final PropertiesFile o2) {
- return Comparing.compare(o1.getName(), o2.getName());
- }
- });
- return files.get(0);
+ return getDefaultPropertiesFile();
}
@NotNull
+ @Override
public String getBaseName() {
- return myBaseName;
+ return PropertiesUtil.getBaseName(myDefaultPropertiesFile.getContainingFile());
+ }
+
+ @NotNull
+ public VirtualFile getBaseDirectory() {
+ return myDefaultPropertiesFile.getParent().getVirtualFile();
+ }
+
+ @NotNull
+ @Override
+ public Project getProject() {
+ return myDefaultPropertiesFile.getProject();
}
public boolean equals(final Object o) {
@@ -83,42 +97,15 @@ public class ResourceBundleImpl extends ResourceBundle {
if (o == null || getClass() != o.getClass()) return false;
final ResourceBundleImpl resourceBundle = (ResourceBundleImpl)o;
-
- if (!myBaseDirectory.equals(resourceBundle.myBaseDirectory)) return false;
- if (!myBaseName.equals(resourceBundle.myBaseName)) return false;
-
+ if (!myDefaultPropertiesFile.equals(resourceBundle.myDefaultPropertiesFile)) return false;
return true;
}
public int hashCode() {
- int result = myBaseDirectory.hashCode();
- result = 29 * result + myBaseName.hashCode();
- return result;
- }
-
- @Nullable
- public static ResourceBundle createByUrl(String url) {
- if (!url.startsWith(RESOURCE_BUNDLE_PREFIX)) return null;
-
- String defaultPropertiesUrl = url.substring(RESOURCE_BUNDLE_PREFIX.length());
- final int idx = defaultPropertiesUrl.lastIndexOf('/');
- if (idx == -1) return null;
- String baseDir = defaultPropertiesUrl.substring(0, idx);
- String baseName = defaultPropertiesUrl.substring(idx + 1);
- VirtualFile baseDirectory = VirtualFileManager.getInstance().findFileByUrl(baseDir);
- if (baseDirectory != null) {
- return new ResourceBundleImpl(baseDirectory, baseName);
- }
- return null;
+ return myDefaultPropertiesFile.hashCode();
}
public String getUrl() {
- return RESOURCE_BUNDLE_PREFIX +getBaseDirectory() + "/" + getBaseName();
- }
-
- @NotNull
- public VirtualFile getBaseDirectory() {
- return myBaseDirectory;
+ return RESOURCE_BUNDLE_PREFIX + getBaseDirectory() + "/" + getBaseName();
}
-
} \ No newline at end of file
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
index f46d207dc935..36915e7e6962 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleAsVirtualFile.java
@@ -19,31 +19,50 @@
*/
package com.intellij.lang.properties.editor;
+import com.intellij.ide.presentation.Presentation;
+import com.intellij.lang.properties.PropertiesImplUtil;
+import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
+import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+@Presentation(icon = "AllIcons.Nodes.ResourceBundle")
public class ResourceBundleAsVirtualFile extends VirtualFile {
- private final ResourceBundle myResourceBundle;
+ private final VirtualFile myBasePropertiesFile;
- public ResourceBundleAsVirtualFile(@NotNull ResourceBundle resourceBundle) {
- myResourceBundle = resourceBundle;
+ private ResourceBundleAsVirtualFile(@NotNull final VirtualFile basePropertiesFile) {
+ myBasePropertiesFile = basePropertiesFile;
}
@NotNull
- public ResourceBundle getResourceBundle() {
- return myResourceBundle;
+ public static ResourceBundleAsVirtualFile fromResourceBundle(final @NotNull ResourceBundle resourceBundle) {
+ return new ResourceBundleAsVirtualFile(resourceBundle.getDefaultPropertiesFile().getVirtualFile());
+ }
+
+ @Nullable
+ public ResourceBundle getResourceBundle(final Project project) {
+ final PsiManager psiManager = PsiManager.getInstance(project);
+ final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(psiManager.findFile(myBasePropertiesFile));
+ if (file == null) {
+ return null;
+ }
+ return PropertiesImplUtil.getResourceBundle(file);
}
@Override
@NotNull
public VirtualFileSystem getFileSystem() {
- return myResourceBundle.getBaseDirectory().getFileSystem();
+ return LocalFileSystem.getInstance();
}
@Override
@@ -55,7 +74,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
@Override
@NotNull
public String getName() {
- return myResourceBundle.getBaseName();
+ return PropertiesUtil.getBaseName(myBasePropertiesFile);
}
public boolean equals(final Object o) {
@@ -64,17 +83,18 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
final ResourceBundleAsVirtualFile resourceBundleAsVirtualFile = (ResourceBundleAsVirtualFile)o;
- if (!myResourceBundle.equals(resourceBundleAsVirtualFile.myResourceBundle)) return false;
+ if (!myBasePropertiesFile.equals(resourceBundleAsVirtualFile.myBasePropertiesFile)) return false;
return true;
}
public int hashCode() {
- return myResourceBundle.hashCode();
+ return myBasePropertiesFile.hashCode();
}
@Override
public void rename(Object requestor, @NotNull String newName) throws IOException {
+ throw new UnsupportedOperationException();
}
@Override
@@ -94,7 +114,7 @@ public class ResourceBundleAsVirtualFile extends VirtualFile {
@Override
public VirtualFile getParent() {
- return myResourceBundle.getBaseDirectory();
+ return myBasePropertiesFile.getParent();
}
@Override
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java
new file mode 100644
index 000000000000..00c21d8d3811
--- /dev/null
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleEditorViewElement.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.editor;
+
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public interface ResourceBundleEditorViewElement {
+
+ PsiElement[] getPsiElements(@NotNull Project project);
+
+}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java
index 2a1f94af4c95..25220d35311a 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleFileStructureViewElement.java
@@ -26,6 +26,9 @@ import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -34,36 +37,35 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement {
- private final Project myProject;
+public class ResourceBundleFileStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
private final ResourceBundle myResourceBundle;
- public ResourceBundleFileStructureViewElement(final Project project, final ResourceBundle resourceBundle) {
- myProject = project;
+ public ResourceBundleFileStructureViewElement(final ResourceBundle resourceBundle) {
myResourceBundle = resourceBundle;
}
+ @Override
public ResourceBundle getValue() {
return myResourceBundle;
}
@NotNull
public StructureViewTreeElement[] getChildren() {
- List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(myProject);
+ List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
Map<String, IProperty> propertyNames = new LinkedHashMap<String, IProperty>();
for (PropertiesFile propertiesFile : propertiesFiles) {
List<IProperty> properties = propertiesFile.getProperties();
for (IProperty property : properties) {
- String name = property.getUnescapedKey();
+ String name = property.getKey();
if (!propertyNames.containsKey(name)) {
propertyNames.put(name, property);
}
}
}
List<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>(propertyNames.size());
- for (String property : propertyNames.keySet()) {
- //result.add(new PropertiesStructureViewElement(property));
- result.add(new ResourceBundlePropertyStructureViewElement(myProject, myResourceBundle, property));
+ for (Map.Entry<String, IProperty> propertyEntry : propertyNames.entrySet()) {
+ //result.add(new PropertiesStructureViewElement(propertyEntry));
+ result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, propertyEntry.getValue()));
}
return result.toArray(new StructureViewTreeElement[result.size()]);
}
@@ -85,6 +87,17 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
};
}
+ @Override
+ public PsiElement[] getPsiElements(@NotNull Project project) {
+ final List<PropertiesFile> propertiesFiles = getValue().getPropertiesFiles();
+ return ContainerUtil.map2Array(propertiesFiles, new PsiElement[propertiesFiles.size()], new Function<PropertiesFile, PsiElement>() {
+ @Override
+ public PsiElement fun(PropertiesFile propertiesFile) {
+ return propertiesFile.getContainingFile();
+ }
+ });
+ }
+
public void navigate(boolean requestFocus) {
}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
index e521047cb9ba..8b387e802597 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundlePropertyStructureViewElement.java
@@ -20,6 +20,7 @@
package com.intellij.lang.properties.editor;
import com.intellij.ide.structureView.StructureViewTreeElement;
+import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesHighlighter;
import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
@@ -29,16 +30,16 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement {
- private final String myPropertyName;
- private final Project myProject;
+public class ResourceBundlePropertyStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
private final ResourceBundle myResourceBundle;
+ private final IProperty myProperty;
private String myPresentableName;
private static final TextAttributesKey INCOMPLETE_PROPERTY_KEY;
@@ -49,10 +50,19 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
INCOMPLETE_PROPERTY_KEY = TextAttributesKey.createTextAttributesKey("INCOMPLETE_PROPERTY_KEY", textAttributes);
}
- public ResourceBundlePropertyStructureViewElement(final Project project, final ResourceBundle resourceBundle, String propertyName) {
- myProject = project;
+
+ public ResourceBundlePropertyStructureViewElement(final ResourceBundle resourceBundle, final IProperty property) {
myResourceBundle = resourceBundle;
- myPropertyName = propertyName;
+ myProperty = property;
+ }
+
+ public IProperty getProperty() {
+ return myProperty;
+ }
+
+ @Override
+ public PsiElement[] getPsiElements(final @NotNull Project project) {
+ return new PsiElement[] {getProperty().getPsiElement()};
}
public void setPresentableName(final String presentableName) {
@@ -61,7 +71,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
@Override
public String getValue() {
- return myPropertyName;
+ return myProperty.getName();
}
@Override
@@ -76,7 +86,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
return new ColoredItemPresentation() {
@Override
public String getPresentableText() {
- return myPresentableName == null ? myPropertyName : myPresentableName;
+ return myPresentableName == null ? myProperty.getName() : myPresentableName;
}
@Override
@@ -91,7 +101,7 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
@Override
public TextAttributesKey getTextAttributesKey() {
- boolean isComplete = PropertiesUtil.isPropertyComplete(myProject, myResourceBundle, myPropertyName);
+ boolean isComplete = PropertiesUtil.isPropertyComplete(myResourceBundle, myProperty.getName());
if (isComplete) {
return PropertiesHighlighter.PROPERTY_KEY;
@@ -115,5 +125,4 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
public boolean canNavigateToSource() {
return false;
}
-
}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java
index 24ba3c513c38..fc1aa60d4ac9 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewModel.java
@@ -25,7 +25,6 @@ import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.structureView.GroupByWordPrefixes;
import com.intellij.lang.properties.structureView.PropertiesSeparatorManager;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
@@ -33,23 +32,24 @@ import org.jetbrains.annotations.NotNull;
*/
public class ResourceBundleStructureViewModel implements PropertiesGroupingStructureViewModel, StructureViewModel.ExpandInfoProvider {
private final ResourceBundle myResourceBundle;
- private final GroupByWordPrefixes myGroupByWordPrefixes;
+ private final GroupByWordPrefixes myByWordPrefixesGrouper;
private final StructureViewTreeElement myRoot;
- public ResourceBundleStructureViewModel(final Project project, ResourceBundle root) {
+ public ResourceBundleStructureViewModel(ResourceBundle root) {
myResourceBundle = root;
- String separator = PropertiesSeparatorManager.getInstance().getSeparator(project, new ResourceBundleAsVirtualFile(myResourceBundle));
- myGroupByWordPrefixes = new GroupByWordPrefixes(separator);
- myRoot = new ResourceBundleFileStructureViewElement(project, myResourceBundle);
+ String separator = PropertiesSeparatorManager.getInstance(root.getProject()).
+ getSeparator(myResourceBundle);
+ myByWordPrefixesGrouper = new GroupByWordPrefixes(separator);
+ myRoot = new ResourceBundleFileStructureViewElement(myResourceBundle);
}
public void setSeparator(String separator) {
- myGroupByWordPrefixes.setSeparator(separator);
- PropertiesSeparatorManager.getInstance().setSeparator(new ResourceBundleAsVirtualFile(myResourceBundle), separator);
+ myByWordPrefixesGrouper.setSeparator(separator);
+ PropertiesSeparatorManager.getInstance(myResourceBundle.getProject()).setSeparator(myResourceBundle, separator);
}
public String getSeparator() {
- return myGroupByWordPrefixes.getSeparator();
+ return myByWordPrefixesGrouper.getSeparator();
}
@NotNull
@@ -59,7 +59,7 @@ public class ResourceBundleStructureViewModel implements PropertiesGroupingStruc
@NotNull
public Grouper[] getGroupers() {
- return new Grouper[]{myGroupByWordPrefixes};
+ return new Grouper[]{myByWordPrefixesGrouper};
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
index 53a9bd4dc31a..e4a35e7e677c 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/editor/ResourceBundleUtil.java
@@ -54,10 +54,10 @@ public class ResourceBundleUtil {
if (virtualFile == null) {
return null;
}
- if (virtualFile instanceof ResourceBundleAsVirtualFile) {
- return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle();
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (virtualFile instanceof ResourceBundleAsVirtualFile && project != null) {
+ return ((ResourceBundleAsVirtualFile)virtualFile).getResourceBundle(project);
}
- Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project != null) {
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (psiFile instanceof PropertiesFile) {
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
index 77be36abc7a7..759ce6cb46fb 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/psi/impl/PropertiesFileImpl.java
@@ -114,7 +114,7 @@ public class PropertiesFileImpl extends PsiFileBase implements PropertiesFile {
@Override
@NotNull
public ResourceBundle getResourceBundle() {
- return PropertiesImplUtil.getResourceBundle(getContainingFile());
+ return PropertiesImplUtil.getResourceBundle(this);
}
@Override
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java
index a740d8ece66f..2cc4851b012f 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/references/PropertyReferenceBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2009 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.
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java
index d0a203a7644f..432739c9df96 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewElement.java
@@ -18,9 +18,12 @@ package com.intellij.lang.properties.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.lang.properties.IProperty;
+import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement;
import com.intellij.lang.properties.psi.Property;
import com.intellij.lang.properties.psi.impl.PropertiesFileImpl;
import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -31,7 +34,7 @@ import java.util.List;
/**
* @author max
*/
-public class PropertiesFileStructureViewElement extends PsiTreeElementBase<PropertiesFileImpl> {
+public class PropertiesFileStructureViewElement extends PsiTreeElementBase<PropertiesFileImpl> implements ResourceBundleEditorViewElement {
protected PropertiesFileStructureViewElement(PropertiesFileImpl propertiesFile) {
super(propertiesFile);
@@ -48,6 +51,11 @@ public class PropertiesFileStructureViewElement extends PsiTreeElementBase<Prope
return elements;
}
+ @Override
+ public PsiElement[] getPsiElements(@NotNull Project project) {
+ return new PsiElement[] {getValue()};
+ }
+
public String getPresentableText() {
return getElement().getName();
}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java
index 0b36e14bd802..f013839553c6 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesFileStructureViewModel.java
@@ -37,7 +37,7 @@ import java.util.Comparator;
*/
public class PropertiesFileStructureViewModel extends TextEditorBasedStructureViewModel implements PropertiesGroupingStructureViewModel {
private final PropertiesFileImpl myPropertiesFile;
- private final GroupByWordPrefixes myGroupByWordPrefixes;
+ private final GroupByWordPrefixes myByWordPrefixesGrouper;
@NonNls public static final String KIND_SORTER_ID = "KIND_SORTER";
private static final Sorter KIND_SORTER = new Sorter() {
@NotNull
@@ -70,17 +70,17 @@ public class PropertiesFileStructureViewModel extends TextEditorBasedStructureVi
public PropertiesFileStructureViewModel(final PropertiesFileImpl root) {
super(root);
myPropertiesFile = root;
- String separator = PropertiesSeparatorManager.getInstance().getSeparator(root.getProject(), root.getVirtualFile());
- myGroupByWordPrefixes = new GroupByWordPrefixes(separator);
+ String separator = PropertiesSeparatorManager.getInstance(root.getProject()).getSeparator(root.getResourceBundle());
+ myByWordPrefixesGrouper = new GroupByWordPrefixes(separator);
}
public void setSeparator(String separator) {
- myGroupByWordPrefixes.setSeparator(separator);
- PropertiesSeparatorManager.getInstance().setSeparator(myPropertiesFile.getVirtualFile(), separator);
+ myByWordPrefixesGrouper.setSeparator(separator);
+ PropertiesSeparatorManager.getInstance(myPropertiesFile.getProject()).setSeparator(myPropertiesFile.getResourceBundle(), separator);
}
public String getSeparator() {
- return myGroupByWordPrefixes.getSeparator();
+ return myByWordPrefixesGrouper.getSeparator();
}
@NotNull
@@ -90,7 +90,7 @@ public class PropertiesFileStructureViewModel extends TextEditorBasedStructureVi
@NotNull
public Grouper[] getGroupers() {
- return new Grouper[]{myGroupByWordPrefixes};
+ return new Grouper[]{myByWordPrefixesGrouper};
}
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java
index ac94b1a1e4ac..8aedbcbbd85d 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesPrefixGroup.java
@@ -19,11 +19,18 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.util.treeView.smartTree.Group;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.lang.properties.IProperty;
+import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement;
import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement;
import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.Function;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
@@ -33,19 +40,36 @@ import java.util.List;
/**
* @author cdr
*/
-public class PropertiesPrefixGroup implements Group {
+public class PropertiesPrefixGroup implements Group, ResourceBundleEditorViewElement {
private final Collection<TreeElement> myProperties;
private final @NotNull String myPrefix;
private final String myPresentableName;
private final @NotNull String mySeparator;
- public PropertiesPrefixGroup(final Collection<TreeElement> properties, String prefix, String presentableName, final String separator) {
+ public PropertiesPrefixGroup(final Collection<TreeElement> properties,
+ final @NotNull String prefix,
+ final String presentableName,
+ final @NotNull String separator) {
myProperties = properties;
myPrefix = prefix;
myPresentableName = presentableName;
mySeparator = separator;
}
+ public String getPresentableName() {
+ return myPresentableName;
+ }
+
+ @NotNull
+ public String getSeparator() {
+ return mySeparator;
+ }
+
+ @NotNull
+ public String getPrefix() {
+ return myPrefix;
+ }
+
@NotNull
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@@ -112,8 +136,24 @@ public class PropertiesPrefixGroup implements Group {
return result;
}
- public String getPrefix() {
- return myPrefix;
+ @Override
+ public PsiElement[] getPsiElements(final @NotNull Project project) {
+ final List<PsiElement> elements = ContainerUtil.mapNotNull(getChildren(), new NullableFunction<TreeElement, PsiElement>() {
+ @Nullable
+ @Override
+ public PsiElement fun(final TreeElement treeElement) {
+ if (treeElement instanceof PropertiesStructureViewElement) {
+ PropertiesStructureViewElement propertiesElement = (PropertiesStructureViewElement)treeElement;
+ IProperty property = propertiesElement.getValue();
+ return property.getPsiElement();
+ }
+ else if (treeElement instanceof ResourceBundlePropertyStructureViewElement) {
+ return ((ResourceBundlePropertyStructureViewElement)treeElement).getPsiElements(project)[0];
+ }
+ return null;
+ }
+ });
+ return elements.toArray(new PsiElement[elements.size()]);
}
public boolean equals(final Object o) {
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java
index f5e636811b92..cb60de04bc4f 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesSeparatorManager.java
@@ -19,28 +19,18 @@
*/
package com.intellij.lang.properties.structureView;
-import com.intellij.lang.properties.IProperty;
-import com.intellij.lang.properties.PropertiesLanguage;
-import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.ResourceBundleImpl;
-import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
+import com.intellij.lang.properties.*;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
-import com.intellij.psi.FileViewProvider;
-import com.intellij.psi.PsiManager;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.TIntLongHashMap;
import gnu.trove.TIntProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -48,45 +38,42 @@ import java.util.Map;
name="PropertiesSeparatorManager",
storages= {
@Storage(
- file = StoragePathMacros.APP_CONFIG + "/other.xml"
+ file = StoragePathMacros.PROJECT_FILE
)}
)
public class PropertiesSeparatorManager implements PersistentStateComponent<Element> {
@NonNls private static final String FILE_ELEMENT = "file";
@NonNls private static final String URL_ELEMENT = "url";
@NonNls private static final String SEPARATOR_ATTR = "separator";
+ private final Project myProject;
- public static PropertiesSeparatorManager getInstance() {
- return ServiceManager.getService(PropertiesSeparatorManager.class);
+ public static PropertiesSeparatorManager getInstance(final Project project) {
+ return ServiceManager.getService(project, PropertiesSeparatorManager.class);
}
- private final Map<VirtualFile, String> mySeparators = new THashMap<VirtualFile, String>();
+ private final Map<String, String> mySeparators = new THashMap<String, String>();
- public String getSeparator(Project project, VirtualFile file) {
- String separator = mySeparators.get(file);
+ public PropertiesSeparatorManager(final Project project) {
+ myProject = project;
+ }
+
+ @NotNull
+ public String getSeparator(final ResourceBundle resourceBundle) {
+ if (!(resourceBundle instanceof ResourceBundleImpl)) {
+ return ".";
+ }
+ String separator = mySeparators.get(((ResourceBundleImpl)resourceBundle).getUrl());
if (separator == null) {
- separator = guessSeparator(project, file);
- setSeparator(file, separator);
+ separator = guessSeparator((ResourceBundleImpl)resourceBundle);
+ setSeparator(resourceBundle, separator);
}
return separator;
}
//returns most probable separator in properties files
- private static String guessSeparator(final Project project, final VirtualFile file) {
- Collection<PropertiesFile> files;
- if (file instanceof ResourceBundleAsVirtualFile) {
- files = ((ResourceBundleAsVirtualFile)file).getResourceBundle().getPropertiesFiles(project);
- }
- else {
- PsiManager psiManager = PsiManager.getInstance(project);
- final FileViewProvider provider = psiManager.findViewProvider(file);
- files = new SmartList<PropertiesFile>();
- if (provider != null) {
- ContainerUtil.addIfNotNull((PropertiesFile)provider.getPsi(PropertiesLanguage.INSTANCE), files);
- }
- }
+ private static String guessSeparator(final ResourceBundleImpl resourceBundle) {
final TIntLongHashMap charCounts = new TIntLongHashMap();
- for (PropertiesFile propertiesFile : files) {
+ for (PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
if (propertiesFile == null) continue;
List<IProperty> properties = propertiesFile.getProperties();
for (IProperty property : properties) {
@@ -119,8 +106,10 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
return Character.toString(mostProbableChar[0]);
}
- public void setSeparator(VirtualFile file, String separator) {
- mySeparators.put(file, separator);
+ public void setSeparator(ResourceBundle resourceBundle, String separator) {
+ if (resourceBundle instanceof ResourceBundleImpl) {
+ mySeparators.put(((ResourceBundleImpl)resourceBundle).getUrl(), separator);
+ }
}
public void loadState(final Element element) {
@@ -132,16 +121,9 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
if (separator == null) {
continue;
}
- VirtualFile file;
- ResourceBundle resourceBundle = ResourceBundleImpl.createByUrl(url);
+ ResourceBundle resourceBundle = PropertiesImplUtil.createByUrl(url, myProject);
if (resourceBundle != null) {
- file = new ResourceBundleAsVirtualFile(resourceBundle);
- }
- else {
- file = VirtualFileManager.getInstance().findFileByUrl(url);
- }
- if (file != null) {
- mySeparators.put(file, separator);
+ mySeparators.put(url, separator);
}
}
}
@@ -178,16 +160,8 @@ public class PropertiesSeparatorManager implements PersistentStateComponent<Elem
public Element getState() {
Element element = new Element("PropertiesSeparatorManager");
- for (VirtualFile file : mySeparators.keySet()) {
- String url;
- if (file instanceof ResourceBundleAsVirtualFile) {
- ResourceBundle resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle();
- url = ((ResourceBundleImpl)resourceBundle).getUrl();
- }
- else {
- url = file.getUrl();
- }
- String separator = mySeparators.get(file);
+ for (final String url: mySeparators.keySet()) {
+ String separator = mySeparators.get(url);
StringBuilder encoded = new StringBuilder(separator.length());
for (int i=0;i<separator.length();i++) {
char c = separator.charAt(i);
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java
index 77946f442518..2af033735706 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/structureView/PropertiesStructureViewElement.java
@@ -16,8 +16,11 @@
package com.intellij.lang.properties.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
+import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement;
import com.intellij.lang.properties.psi.Property;
import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -25,7 +28,7 @@ import javax.swing.*;
/**
* @author max
*/
-public class PropertiesStructureViewElement implements StructureViewTreeElement {
+public class PropertiesStructureViewElement implements StructureViewTreeElement, ResourceBundleEditorViewElement {
private final Property myProperty;
private String myPresentableName;
@@ -54,6 +57,11 @@ public class PropertiesStructureViewElement implements StructureViewTreeElement
return EMPTY_ARRAY;
}
+ @Override
+ public PsiElement[] getPsiElements(@NotNull Project project) {
+ return new PsiElement[] {getValue()};
+ }
+
@NotNull
public ItemPresentation getPresentation() {
return new ItemPresentation() {
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
index f9733d89279b..4b8953f47e9c 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesFileImpl.java
@@ -101,7 +101,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
@NotNull
@Override
public ResourceBundle getResourceBundle() {
- return PropertiesImplUtil.getResourceBundle(getContainingFile());
+ return PropertiesImplUtil.getResourceBundle(this);
}
@NotNull
@@ -127,6 +127,7 @@ public class XmlPropertiesFileImpl extends XmlPropertiesFile {
XmlTag rootTag = myFile.getRootTag();
XmlTag entry = rootTag.createChildTag("entry", "", value, false);
entry.setAttribute("key", key);
+ rootTag.addSubTag(entry, false);
return new XmlProperty(entry, this);
}
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesReferenceContributor.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesReferenceContributor.java
index 20fb07eeb7a7..d469f343fca0 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesReferenceContributor.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/xml/XmlPropertiesReferenceContributor.java
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
*/
public class XmlPropertiesReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withLocalName("key"),
new PsiReferenceProvider() {
@NotNull
diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
index fda8022d3b33..f946e41c26ae 100644
--- a/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
+++ b/plugins/properties/properties-psi-impl/src/com/intellij/properties/PropertiesCoreEnvironment.java
@@ -63,7 +63,6 @@ public class PropertiesCoreEnvironment {
appEnvironment.registerApplicationService(PropertiesQuickFixFactory.class, new EmptyPropertiesQuickFixFactory());
appEnvironment.registerApplicationService(PropertiesRefactoringSettings.class, new PropertiesRefactoringSettings());
- appEnvironment.registerApplicationService(PropertiesSeparatorManager.class, new PropertiesSeparatorManager());
appEnvironment.addExplicitExtension(LanguageAnnotators.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesAnnotator());
appEnvironment.addExplicitExtension(LanguageFindUsages.INSTANCE, PropertiesLanguage.INSTANCE, new PropertiesFindUsagesProvider());
@@ -87,6 +86,7 @@ public class PropertiesCoreEnvironment {
public static class ProjectEnvironment {
public ProjectEnvironment(CoreProjectEnvironment projectEnvironment) {
projectEnvironment.getProject().registerService(PropertiesReferenceManager.class);
+ projectEnvironment.getProject().registerService(PropertiesSeparatorManager.class);
}
}
}
diff --git a/plugins/properties/properties.iml b/plugins/properties/properties.iml
index 5549251d37b9..79207be504b0 100644
--- a/plugins/properties/properties.iml
+++ b/plugins/properties/properties.iml
@@ -20,6 +20,7 @@
<orderEntry type="module" module-name="xml" />
<orderEntry type="module" module-name="properties-psi-api" exported="" />
<orderEntry type="module" module-name="properties-psi-impl" exported="" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
</component>
</module>
diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml
index 73f4d81da79e..513678dcbf72 100644
--- a/plugins/properties/src/META-INF/plugin.xml
+++ b/plugins/properties/src/META-INF/plugin.xml
@@ -1,3 +1,110 @@
-<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="/META-INF/PropertiesPlugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
+<idea-plugin version="2">
+ <id>com.intellij.properties</id>
+ <name>Properties Support</name>
+ <depends>com.intellij.modules.xml</depends>
+ <description>
+ This plugin enables smart editing of properties files.
+ </description>
+ <vendor>JetBrains</vendor>
+
+ <extensionPoints>
+ <extensionPoint name="implicitPropertyUsageProvider" interface="com.intellij.codeInspection.unused.ImplicitPropertyUsageProvider"/>
+ </extensionPoints>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <typeIcon className="com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile" icon="AllIcons.Nodes.ResourceBundle"/>
+ <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+ <applicationService serviceInterface="com.intellij.lang.properties.LastSelectedPropertiesFileStore"
+ serviceImplementation="com.intellij.lang.properties.LastSelectedPropertiesFileStore"/>
+ <applicationService serviceInterface="com.intellij.lang.properties.PropertiesQuickFixFactory"
+ serviceImplementation="com.intellij.lang.properties.PropertiesQuickFixFactoryImpl"/>
+ <applicationService
+ serviceImplementation="com.intellij.lang.properties.refactoring.PropertiesRefactoringSettings"/>
+ <annotator language="Properties" implementationClass="com.intellij.lang.properties.PropertiesAnnotator"/>
+ <completion.contributor language="any" implementationClass="com.intellij.lang.properties.references.PropertiesCompletionContributor"
+ id="propertiesCompletion" order="before javaClassReference"/>
+ <lang.refactoringSupport language="Properties"
+ implementationClass="com.intellij.lang.properties.refactoring.PropertiesRefactoringSupportProvider"/>
+ <lang.documentationProvider language="Properties" implementationClass="com.intellij.lang.properties.PropertiesDocumentationProvider"/>
+ <lang.findUsagesProvider language="Properties"
+ implementationClass="com.intellij.lang.properties.findUsages.PropertiesFindUsagesProvider"/>
+ <lang.elementManipulator forClass="com.intellij.lang.properties.psi.impl.PropertyValueImpl"
+ implementationClass="com.intellij.lang.properties.PropertyValueManipulator"/>
+ <lang.elementManipulator forClass="com.intellij.lang.properties.psi.impl.PropertyImpl"
+ implementationClass="com.intellij.lang.properties.PropertyManipulator"/>
+ <projectService serviceInterface="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"
+ serviceImplementation="com.intellij.lang.properties.structureView.PropertiesSeparatorManager"/>
+ <codeInsight.wordCompletionFilter language="Properties"
+ implementationClass="com.intellij.lang.properties.PropertiesWordCompletionFilter"/>
+ <lang.psiStructureViewFactory language="Properties"
+ implementationClass="com.intellij.lang.properties.structureView.PropertiesStructureViewBuilderFactory"/>
+ <lang.ast.factory language="Properties" implementationClass="com.intellij.lang.properties.psi.impl.PropertiesASTFactory"/>
+ <joinLinesHandler implementation="com.intellij.lang.properties.PropertiesJoinLinesHandler"/>
+
+ <enterHandlerDelegate implementation="com.intellij.codeInsight.editorActions.enter.EnterInPropertiesFileHandler"/>
+
+ <lang.parserDefinition language="Properties" implementationClass="com.intellij.lang.properties.parsing.PropertiesParserDefinition"/>
+ <renameHandler implementation="com.intellij.lang.properties.refactoring.rename.ResourceBundleFromEditorRenameHandler"/>
+ <renameHandler implementation="com.intellij.lang.properties.refactoring.rename.ResourceBundleFromProjectViewRenameHandler"/>
+ <automaticRenamerFactory implementation="com.intellij.lang.properties.refactoring.rename.ResourceBundleRenamerFactory"/>
+ <renamePsiElementProcessor implementation="com.intellij.lang.properties.refactoring.rename.RenamePropertyProcessor"/>
+ <stubElementTypeHolder class="com.intellij.lang.properties.parsing.PropertiesElementTypes"/>
+ <lang.commenter language="Properties" implementationClass="com.intellij.lang.properties.PropertiesCommenter"/>
+ <stubIndex implementation="com.intellij.lang.properties.psi.PropertyKeyIndex"/>
+ <lang.namesValidator language="Properties" implementationClass="com.intellij.lang.properties.PropertiesNamesValidator"/>
+ <refactoring.safeDeleteProcessor implementation="com.intellij.lang.properties.refactoring.PropertiesSafeDeleteProcessor"/>
+ <refactoring.moveHandler implementation="com.intellij.lang.properties.projectView.ResourceBundleMoveProvider"/>
+ <colorSettingsPage implementation="com.intellij.openapi.options.colors.pages.PropertiesColorsPage"/>
+ <treeStructureProvider implementation="com.intellij.lang.properties.projectView.ResourceBundleGrouper"/>
+ <elementDescriptionProvider implementation="com.intellij.lang.properties.PropertiesDescriptionProvider"/>
+ <fileTypeFactory implementation="com.intellij.lang.properties.PropertiesFileTypeFactory"/>
+ <fileTypeFactory implementation="com.intellij.lang.properties.editor.ResourceBundleEditorProvider"/>
+ <favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.ResourcesFavoriteNodeProvider"/>
+
+ <localInspection language="Properties" shortName="UnusedProperty" bundle="messages.PropertiesBundle"
+ key="unused.property.inspection.display.name"
+ groupKey="properties.files.inspection.group.display.name" enabledByDefault="true" level="WARNING"
+ implementationClass="com.intellij.codeInspection.unused.UnusedPropertyInspection"/>
+ <globalInspection shortName="DuplicatePropertyInspection" bundle="messages.InspectionsBundle" key="duplicate.property.display.name"
+ groupKey="group.names.properties.files" enabledByDefault="false" level="WARNING"
+ implementationClass="com.intellij.codeInspection.duplicatePropertyInspection.DuplicatePropertyInspection"/>
+ <localInspection language="Properties" shortName="TrailingSpacesInProperty" bundle="messages.PropertiesBundle"
+ key="trail.spaces.property.inspection.display.name" groupKey="properties.files.inspection.group.display.name"
+ enabledByDefault="true" level="WARNING"
+ implementationClass="com.intellij.codeInspection.TrailingSpacesInPropertyInspection"/>
+
+ <idIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesIdIndexer"/>
+ <todoIndexer filetype="Properties" implementationClass="com.intellij.psi.impl.cache.impl.idCache.PropertiesTodoIndexer"/>
+
+ <projectService serviceImplementation="com.intellij.lang.properties.PropertiesReferenceManager"/>
+
+ <fileEditorProvider implementation="com.intellij.lang.properties.editor.ResourceBundleEditorProvider"/>
+ <spellchecker.support language="Properties"
+ implementationClass="com.intellij.lang.properties.spellchecker.PropertiesSpellcheckingStrategy"/>
+
+ <fileBasedIndex implementation="com.intellij.lang.properties.xml.XmlPropertiesIndex"/>
+ <standardResource url="http://java.sun.com/dtd/properties.dtd" path="schemas/properties.dtd"/>
+ <iconProvider implementation="com.intellij.lang.properties.xml.XmlPropertiesIconProvider"/>
+ <psi.referenceContributor language="XML" implementation="com.intellij.lang.properties.xml.XmlPropertiesReferenceContributor"/>
+ <lang.foldingBuilder language="Properties" implementationClass="com.intellij.lang.properties.editor.PropertiesFoldingBuilder"/>
+ <gotoRelatedProvider implementation="com.intellij.lang.properties.editor.GotoResourceBundleLocalizationsProvider"/>
+ </extensions>
+
+ <project-components>
+ <component>
+ <implementation-class>com.intellij.lang.properties.PropertiesFilesManager</implementation-class>
+ <skipForDefaultProject/>
+ </component>
+ </project-components>
+
+ <actions>
+ <action id="ChooseNextSubsequentPropertyValueEditorAction"
+ class="com.intellij.lang.properties.editor.ChooseSubsequentPropertyValueEditorAction$Next"
+ text="Choose Next Property Value Editor"
+ use-shortcut-of="MethodDown"/>
+ <action id="ChoosePrevSubsequentPropertyValueEditorAction"
+ class="com.intellij.lang.properties.editor.ChooseSubsequentPropertyValueEditorAction$Prev"
+ text="Choose Previous Property Value Editor"
+ use-shortcut-of="MethodUp"/>
+ </actions>
</idea-plugin>
diff --git a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java
index 4b6a574c2024..67ddbf2d10f2 100644
--- a/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java
+++ b/plugins/properties/src/com/intellij/ide/favoritesTreeView/ResourcesFavoriteNodeProvider.java
@@ -22,13 +22,13 @@ package com.intellij.ide.favoritesTreeView;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.ResourceBundleImpl;
import com.intellij.lang.properties.projectView.ResourceBundleNode;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -64,7 +64,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider {
public boolean elementContainsFile(final Object element, final VirtualFile vFile) {
if (element instanceof ResourceBundle) {
ResourceBundle bundle = (ResourceBundle)element;
- final List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles(myProject);
+ final List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles();
for (PropertiesFile file : propertiesFiles) {
final VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) continue;
@@ -87,7 +87,7 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider {
public boolean isInvalidElement(final Object element) {
if (element instanceof ResourceBundle) {
ResourceBundle resourceBundle = (ResourceBundle)element;
- List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles(myProject);
+ List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
if (propertiesFiles.size() == 1) {
//todo result.add(new PsiFileNode(myProject, propertiesFiles.iterator().next(), this));
return true;
@@ -113,6 +113,6 @@ public class ResourcesFavoriteNodeProvider extends FavoriteNodeProvider {
}
public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) {
- return new Object[]{ResourceBundleImpl.createByUrl(url)};
+ return new Object[]{PropertiesImplUtil.createByUrl(url, project)};
}
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ChooseSubsequentPropertyValueEditorAction.java b/plugins/properties/src/com/intellij/lang/properties/editor/ChooseSubsequentPropertyValueEditorAction.java
new file mode 100644
index 000000000000..5b60f854dbaf
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ChooseSubsequentPropertyValueEditorAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.editor;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Key;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ChooseSubsequentPropertyValueEditorAction extends AnAction {
+ public static final Key<Editor> NEXT_EDITOR_KEY = Key.create("resourceBundleEditor.nextEditor");
+ public static final Key<Editor> PREV_EDITOR_KEY = Key.create("resourceBundleEditor.prevEditor");
+
+ public final boolean myNext;
+
+ public static class Next extends ChooseSubsequentPropertyValueEditorAction {
+ public Next() {
+ super(true);
+ }
+ }
+
+ public static class Prev extends ChooseSubsequentPropertyValueEditorAction {
+ public Prev() {
+ super(false);
+ }
+ }
+
+ private ChooseSubsequentPropertyValueEditorAction(final boolean next) {
+ myNext = next;
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final Editor editor = e.getData(CommonDataKeys.EDITOR);
+ if (editor == null) {
+ return;
+ }
+ final Editor newFocusEditor = editor.getUserData(myNext ? NEXT_EDITOR_KEY : PREV_EDITOR_KEY);
+ if (newFocusEditor != null) {
+ newFocusEditor.getContentComponent().requestFocus();
+ }
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java b/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java
new file mode 100644
index 000000000000..d25b780bd769
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/NewPropertyAction.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.editor;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.lang.properties.structureView.PropertiesPrefixGroup;
+import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.InputValidator;
+import com.intellij.openapi.ui.Messages;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author Dmitry Batkovich
+*/
+class NewPropertyAction extends AnAction {
+ public NewPropertyAction() {
+ super("New Property", null, AllIcons.General.Add);
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final Project project = getEventProject(e);
+ if (project == null) {
+ return;
+ }
+ final FileEditor editor = PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext());
+ if (editor == null || !(editor instanceof ResourceBundleEditor)) {
+ return;
+ }
+ final ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)editor;
+
+ final String prefix;
+ final String separator;
+ final String place = e.getPlace();
+ if (ActionPlaces.STRUCTURE_VIEW_TOOLBAR.equals(place)) {
+ prefix = null;
+ separator = null;
+ } else {
+ final ResourceBundleEditorViewElement selectedElement = resourceBundleEditor.getSelectedElement();
+ if (selectedElement == null) {
+ return;
+ }
+ if (selectedElement instanceof PropertiesPrefixGroup) {
+ final PropertiesPrefixGroup group = (PropertiesPrefixGroup)selectedElement;
+ prefix = group.getPrefix();
+ separator = group.getSeparator();
+ }
+ else if (selectedElement instanceof ResourceBundlePropertyStructureViewElement ||
+ selectedElement instanceof ResourceBundleFileStructureViewElement) {
+ prefix = null;
+ separator = null;
+ }
+ else {
+ throw new IllegalStateException("unsupported type: " + selectedElement.getClass());
+ }
+ }
+ final ResourceBundle resourceBundle = resourceBundleEditor.getResourceBundle();
+
+ Messages.showInputDialog(project,
+ PropertiesBundle.message("new.property.dialog.name.prompt.text"),
+ PropertiesBundle.message("new.property.dialog.title"),
+ Messages.getQuestionIcon(),
+ null,
+ new NewPropertyNameValidator(resourceBundle, prefix, separator));
+ }
+
+ private static class NewPropertyNameValidator implements InputValidator {
+ private final @NotNull ResourceBundle myResourceBundle;
+ private final @Nullable String myPrefix;
+ private final @Nullable String mySeparator;
+
+
+ public NewPropertyNameValidator(final @NotNull ResourceBundle resourceBundle,
+ final @Nullable String prefix,
+ final @Nullable String separator) {
+ myResourceBundle = resourceBundle;
+ myPrefix = prefix;
+ mySeparator = separator;
+ }
+
+ @Override
+ public boolean checkInput(final String inputString) {
+ return true;
+ }
+
+ @Override
+ public boolean canClose(final String inputString) {
+ final String newPropertyName = myPrefix == null ? inputString : (myPrefix + mySeparator + inputString);
+
+ for (final PropertiesFile propertiesFile : myResourceBundle.getPropertiesFiles()) {
+ for (final String propertyName : propertiesFile.getNamesMap().keySet()) {
+ if (newPropertyName.equals(propertyName)) {
+ Messages.showErrorDialog("Can't add new property. Property with key \'" + newPropertyName + "\' already exists.", "New Property");
+ return false;
+ }
+ }
+ }
+
+ final PropertiesFile defaultPropertiesFile = myResourceBundle.getDefaultPropertiesFile();
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ @Override
+ public void run() {
+ defaultPropertiesFile.addProperty(newPropertyName, "");
+ }
+ });
+ }
+ });
+ return true;
+ }
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java
index 8765943c7c4a..733f229bc687 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/PropertiesGroupingStructureViewComponent.java
@@ -32,6 +32,7 @@ import java.util.Set;
* @author cdr
*/
public class PropertiesGroupingStructureViewComponent extends StructureViewComponent {
+
protected PropertiesGroupingStructureViewComponent(Project project,
FileEditor editor,
PropertiesGroupingStructureViewModel structureViewModel) {
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
index 5abeb70cf985..0176aa38fc6e 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditor.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.command.undo.UndoConstants;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -68,7 +69,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.TitledBorder;
-import javax.swing.event.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
@@ -100,8 +102,8 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
private VirtualFileListener myVfsListener;
private Editor mySelectedEditor;
- public ResourceBundleEditor(Project project, ResourceBundle resourceBundle) {
- myProject = project;
+ public ResourceBundleEditor(@NotNull ResourceBundle resourceBundle) {
+ myProject = resourceBundle.getProject();
final JPanel splitPanel = new JPanel();
myValuesPanel = new JPanel();
@@ -116,7 +118,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
splitPanel.add(splitter, BorderLayout.CENTER);
myResourceBundle = resourceBundle;
- myStructureViewComponent = new ResourceBundleStructureViewComponent(project, myResourceBundle, this);
+ myStructureViewComponent = new ResourceBundleStructureViewComponent(myResourceBundle, this);
myStructureViewPanel.setLayout(new BorderLayout());
myStructureViewPanel.add(myStructureViewComponent, BorderLayout.CENTER);
@@ -128,9 +130,18 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
public void valueChanged(TreeSelectionEvent e) {
// filter out temp unselect/select events
if (getSelectedPropertyName() == null) return;
- if (!Comparing.strEqual(selectedPropertyName, getSelectedPropertyName())
- || !Comparing.equal(selectedPropertiesFile, getSelectedPropertiesFile()))
- {
+ if (!Comparing.strEqual(selectedPropertyName, getSelectedPropertyName()) ||
+ !Comparing.equal(selectedPropertiesFile, getSelectedPropertiesFile())) {
+
+ if (e.getOldLeadSelectionPath() != null) {
+ for (Map.Entry<PropertiesFile, Editor> entry : myEditors.entrySet()) {
+ if (entry.getValue() == mySelectedEditor) {
+ writeEditorPropertyValue(mySelectedEditor, entry.getKey(), selectedPropertyName);
+ break;
+ }
+ }
+ }
+
selectedPropertyName = getSelectedPropertyName();
selectedPropertiesFile = getSelectedPropertiesFile();
selectionChanged();
@@ -151,7 +162,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}
myDataProviderPanel = new DataProviderPanel(splitPanel);
- project.getMessageBus().connect(project).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
+ myProject.getMessageBus().connect(myProject).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
onSelectionChanged(event);
@@ -159,6 +170,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
});
}
+ public ResourceBundle getResourceBundle() {
+ return myResourceBundle;
+ }
+
private void onSelectionChanged(@NotNull FileEditorManagerEvent event) {
// Ignore events which don't target current editor.
FileEditor oldEditor = event.getOldEditor();
@@ -192,6 +207,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}
private void setStructureViewSelection(@NotNull final String propertyName) {
+ if (myStructureViewComponent.isDisposed()) {
+ return;
+ }
JTree tree = myStructureViewComponent.getTree();
if (tree == null) {
return;
@@ -262,17 +280,24 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
@Nullable
private static String getNodeValue(@NotNull DefaultMutableTreeNode node) {
+ final ResourceBundleEditorViewElement element = getSelectedElement(node);
+ return element instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement)element).getValue()
+ : null;
+ }
+
+ @Nullable
+ private static ResourceBundleEditorViewElement getSelectedElement(@NotNull DefaultMutableTreeNode node) {
Object userObject = node.getUserObject();
if (!(userObject instanceof AbstractTreeNode)) return null;
Object value = ((AbstractTreeNode)userObject).getValue();
- return value instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement)value).getValue()
- : null;
+ return value instanceof ResourceBundleEditorViewElement ? (ResourceBundleEditorViewElement) value : null;
}
- private void writeEditorPropertyValue(final Editor editor, final PropertiesFile propertiesFile) {
+ private void writeEditorPropertyValue(final Editor editor, final PropertiesFile propertiesFile, final @Nullable String propertyName) {
final String currentValue = editor.getDocument().getText();
- final String selectedProperty = getSelectedPropertyName();
- assert selectedProperty != null;
+ final String currentSelectedProperty = propertyName == null ? getSelectedPropertyName() : propertyName;
+
+ assert currentSelectedProperty != null;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
@@ -280,10 +305,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
@Override
public void run() {
- final IProperty property = propertiesFile.findPropertyByKey(selectedProperty);
+ final IProperty property = propertiesFile.findPropertyByKey(currentSelectedProperty);
try {
if (property == null) {
- propertiesFile.addProperty(selectedProperty, currentValue);
+ propertiesFile.addProperty(currentSelectedProperty, currentValue);
}
else {
property.setValue(currentValue);
@@ -314,16 +339,26 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}, VALUES);
myValuesPanel.add(myNoPropertySelectedPanel, NO_PROPERTY_SELECTED);
- List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(myProject);
+ List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
GridBagConstraints gc = new GridBagConstraints(0, 0, 0, 0, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
new Insets(5, 5, 5, 5), 0, 0);
releaseAllEditors();
myTitledPanels.clear();
int y = 0;
+ Editor previousEditor = null;
+ Editor firstEditor = null;
for (final PropertiesFile propertiesFile : propertiesFiles) {
final Editor editor = createEditor();
final Editor oldEditor = myEditors.put(propertiesFile, editor);
+ if (firstEditor == null) {
+ firstEditor = editor;
+ }
+ if (previousEditor != null) {
+ editor.putUserData(ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor);
+ previousEditor.putUserData(ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, editor);
+ }
+ previousEditor = editor;
if (oldEditor != null) {
EditorFactory.getInstance().releaseEditor(oldEditor);
}
@@ -335,9 +370,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
@Override
public void focusLost(final Editor eventEditor) {
- writeEditorPropertyValue(editor, propertiesFile);
+ writeEditorPropertyValue(editor, propertiesFile, null);
}
});
+ editor.getDocument().putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE);
gc.gridx = 0;
gc.gridy = y++;
gc.gridheight = 1;
@@ -375,6 +411,10 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
valuesPanelComponent.add(comp, gc);
}
+ if (previousEditor != null) {
+ previousEditor.putUserData(ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, firstEditor);
+ firstEditor.putUserData(ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor);
+ }
gc.gridx = 0;
gc.gridy = y;
@@ -524,7 +564,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
}
@Nullable
- private String getSelectedPropertyName() {
+ public String getSelectedPropertyName() {
JTree tree = myStructureViewComponent.getTree();
if (tree == null) return null;
TreePath selected = tree.getSelectionModel().getSelectionPath();
@@ -532,6 +572,15 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
return getNodeValue((DefaultMutableTreeNode)selected.getLastPathComponent());
}
+ @Nullable
+ public ResourceBundleEditorViewElement getSelectedElement() {
+ JTree tree = myStructureViewComponent.getTree();
+ if (tree == null) return null;
+ TreePath selected = tree.getSelectionModel().getSelectionPath();
+ if (selected == null) return null;
+ return getSelectedElement((DefaultMutableTreeNode)selected.getLastPathComponent());
+ }
+
@Override
@NotNull
public JComponent getComponent() {
@@ -673,7 +722,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
if (mySelectedEditor != null) {
for (final Map.Entry<PropertiesFile, Editor> entry : myEditors.entrySet()) {
if (mySelectedEditor.equals(entry.getValue())) {
- writeEditorPropertyValue(mySelectedEditor, entry.getKey());
+ writeEditorPropertyValue(mySelectedEditor, entry.getKey(), null);
}
}
}
@@ -693,23 +742,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
myEditors.clear();
}
- /**
- * Renames target property if the one is available.
- * <p/>
- * <b>Note:</b> is assumed to be called under {@link WriteAction write action}.
- *
- * @param oldName old property name
- * @param newName new property name
- */
- public void renameProperty(@NotNull String oldName, @NotNull String newName) {
- for (PropertiesFile properties : myResourceBundle.getPropertiesFiles(myProject)) {
- IProperty property = properties.findPropertyByKey(oldName);
- if (property != null) {
- property.setName(newName);
- }
- }
- }
-
public static class ResourceBundleEditorState implements FileEditorState {
private final String myPropertyName;
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
index f29a9cbb7b7a..fdbc2c0c5e59 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleEditorProvider.java
@@ -42,7 +42,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil
if (!file.isValid()) return false;
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
- return propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles(project).size() > 1;
+ return propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles().size() > 1;
}
@Override
@@ -50,7 +50,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil
public FileEditor createEditor(@NotNull Project project, @NotNull final VirtualFile file){
ResourceBundle resourceBundle;
if (file instanceof ResourceBundleAsVirtualFile) {
- resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle();
+ resourceBundle = ((ResourceBundleAsVirtualFile)file).getResourceBundle(project);
}
else {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
@@ -60,7 +60,7 @@ public class ResourceBundleEditorProvider extends FileTypeFactory implements Fil
resourceBundle = PropertiesImplUtil.getPropertiesFile(psiFile).getResourceBundle();
}
- return new ResourceBundleEditor(project, resourceBundle);
+ return new ResourceBundleEditor(resourceBundle);
}
@Override
diff --git a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
index 9289eb24a4cb..ee8e47a446e4 100644
--- a/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
+++ b/plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundleStructureViewComponent.java
@@ -15,25 +15,118 @@
*/
package com.intellij.lang.properties.editor;
+import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
+import com.intellij.ide.CopyProvider;
+import com.intellij.ide.DeleteProvider;
+import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.lang.properties.psi.Property;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
+import com.intellij.ui.PopupHandler;
+import com.intellij.usages.UsageTarget;
+import com.intellij.usages.UsageView;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.datatransfer.StringSelection;
+import java.util.ArrayList;
+import java.util.List;
/**
* @author cdr
*/
class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureViewComponent {
+ private final static Logger LOG = Logger.getInstance(ResourceBundleStructureViewComponent.class);
+
private final ResourceBundle myResourceBundle;
- public ResourceBundleStructureViewComponent(Project project, ResourceBundle resourceBundle, ResourceBundleEditor editor) {
- super(project, editor, new ResourceBundleStructureViewModel(project, resourceBundle));
+ public ResourceBundleStructureViewComponent(final ResourceBundle resourceBundle, final ResourceBundleEditor editor) {
+ super(resourceBundle.getProject(), editor, new ResourceBundleStructureViewModel(resourceBundle));
myResourceBundle = resourceBundle;
+ tunePopupActionGroup();
}
- public Object getData(String dataId) {
+ @Override
+ protected void addGroupByActions(final DefaultActionGroup result) {
+ super.addGroupByActions(result);
+ result.add(new NewPropertyAction(), Constraints.FIRST);
+ }
+
+ private void tunePopupActionGroup() {
+ final DefaultActionGroup propertiesPopupGroup = new DefaultActionGroup();
+ propertiesPopupGroup.copyFromGroup((DefaultActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_STRUCTURE_VIEW_POPUP));
+ propertiesPopupGroup.add(Separator.getInstance(), Constraints.FIRST);
+ propertiesPopupGroup.add(new NewPropertyAction(), Constraints.FIRST);
+ PopupHandler.installPopupHandler(getTree(), propertiesPopupGroup, IdeActions.GROUP_STRUCTURE_VIEW_POPUP, ActionManager.getInstance());
+ }
+
+ public Object getData(final String dataId) {
if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) {
- return new ResourceBundleAsVirtualFile(myResourceBundle);
+ return ResourceBundleAsVirtualFile.fromResourceBundle(myResourceBundle);
+ } else if (PlatformDataKeys.FILE_EDITOR.is(dataId)) {
+ return getFileEditor();
+ } else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
+ final ResourceBundleEditorViewElement selectedElement = ((ResourceBundleEditor)getFileEditor()).getSelectedElement();
+ if (selectedElement != null) {
+ final Project project = CommonDataKeys.PROJECT.getData(this);
+ if (project != null) {
+ final PsiElement[] psiElements = selectedElement.getPsiElements(project);
+ if (psiElements != null) {
+ return psiElements;
+ }
+ }
+ }
+ } else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
+ final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(this);
+ if (psiElements != null && psiElements.length > 0) {
+ return new PsiElementsDeleteProvider(psiElements);
+ }
+ } else if (UsageView.USAGE_TARGETS_KEY.is(dataId)) {
+ final PsiElement[] chosenElements = (PsiElement[]) getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName());
+ if (chosenElements != null) {
+ final UsageTarget[] usageTargets = new UsageTarget[chosenElements.length];
+ for (int i = 0; i < chosenElements.length; i++) {
+ usageTargets[i] = new PsiElement2UsageTargetAdapter(chosenElements[i]);
+ }
+ return usageTargets;
+ }
+ } else if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) {
+ return new CopyProvider() {
+ @Override
+ public void performCopy(@NotNull final DataContext dataContext) {
+ final PsiElement[] selectedPsiElements = (PsiElement[])getData(LangDataKeys.PSI_ELEMENT_ARRAY.getName());
+ if (selectedPsiElements != null) {
+ final List<String> names = new ArrayList<String>(selectedPsiElements.length);
+ for (final PsiElement element : selectedPsiElements) {
+ if (element instanceof PsiNamedElement) {
+ names.add(((PsiNamedElement)element).getName());
+ }
+ }
+ CopyPasteManager.getInstance().setContents(new StringSelection(StringUtil.join(names, "\n")));
+ }
+ }
+
+ @Override
+ public boolean isCopyEnabled(@NotNull final DataContext dataContext) {
+ return true;
+ }
+
+ @Override
+ public boolean isCopyVisible(@NotNull final DataContext dataContext) {
+ return true;
+ }
+ };
}
return super.getData(dataId);
}
@@ -41,5 +134,40 @@ class ResourceBundleStructureViewComponent extends PropertiesGroupingStructureVi
protected boolean showScrollToFromSourceActions() {
return false;
}
+
+ private class PsiElementsDeleteProvider implements DeleteProvider {
+ private final PsiElement[] myElements;
+
+ private PsiElementsDeleteProvider(final PsiElement[] elements) {
+ myElements = elements;
+ }
+
+ @Override
+ public void deleteElement(@NotNull final DataContext dataContext) {
+ final List<PropertiesFile> bundlePropertiesFiles = myResourceBundle.getPropertiesFiles();
+
+ final List<PsiElement> toDelete = new ArrayList<PsiElement>();
+ for (PsiElement element : myElements) {
+ final Property property = (Property) element;
+ final String key = property.getKey();
+ if (key == null) {
+ LOG.error("key must be not null " + element);
+ } else {
+ for (PropertiesFile propertiesFile : bundlePropertiesFiles) {
+ for (final IProperty iProperty : propertiesFile.findPropertiesByKey(key)) {
+ toDelete.add(iProperty.getPsiElement());
+ }
+ }
+ }
+ }
+
+ new SafeDeleteHandler().invoke(myElements[0].getProject(), PsiUtilCore.toPsiElementArray(toDelete), dataContext);
+ }
+
+ @Override
+ public boolean canDeleteElement(@NotNull final DataContext dataContext) {
+ return true;
+ }
+ }
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java
index 7ba44a86c2bd..a681e10f3af1 100644
--- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleDeleteProvider.java
@@ -48,7 +48,7 @@ class ResourceBundleDeleteProvider implements DeleteProvider {
public void deleteElement(@NotNull DataContext dataContext) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
- List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(project);
+ List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
assert project != null;
new SafeDeleteHandler().invoke(project, ContainerUtil.map2Array(propertiesFiles, PsiElement.class, MAPPER), dataContext);
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java
index a2b1b621f068..d61282aefba2 100644
--- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleMoveProvider.java
@@ -57,7 +57,7 @@ public class ResourceBundleMoveProvider extends MoveHandlerDelegate {
final ResourceBundle[] bundles = ResourceBundle.ARRAY_DATA_KEY.getData(dataContext);
LOG.assertTrue(bundles != null);
for (ResourceBundle bundle : bundles) {
- List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles(CommonDataKeys.PROJECT.getData(dataContext));
+ List<PropertiesFile> propertiesFiles = bundle.getPropertiesFiles();
for (PropertiesFile propertiesFile : propertiesFiles) {
filesOrDirs.add(propertiesFile.getContainingFile());
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
index 7de856226e01..a415e4544aa0 100644
--- a/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
+++ b/plugins/properties/src/com/intellij/lang/properties/projectView/ResourceBundleNode.java
@@ -25,9 +25,7 @@ import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
-import com.intellij.lang.properties.PropertiesBundle;
-import com.intellij.lang.properties.PropertiesImplUtil;
-import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.*;
import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -50,7 +48,7 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
@NotNull
public Collection<AbstractTreeNode> getChildren() {
- List<PropertiesFile> propertiesFiles = getValue().getPropertiesFiles(myProject);
+ List<PropertiesFile> propertiesFiles = getValue().getPropertiesFiles();
Collection<AbstractTreeNode> children = new ArrayList<AbstractTreeNode>();
for (PropertiesFile propertiesFile : propertiesFiles) {
AbstractTreeNode node = new PsiFileNode(myProject, propertiesFile.getContainingFile(), getSettings());
@@ -63,11 +61,11 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
if (!file.isValid()) return false;
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file);
PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
- return propertiesFile != null && getValue().getPropertiesFiles(myProject).contains(propertiesFile);
+ return propertiesFile != null && getValue().getPropertiesFiles().contains(propertiesFile);
}
public VirtualFile getVirtualFile() {
- final List<PropertiesFile> list = getValue().getPropertiesFiles(myProject);
+ final List<PropertiesFile> list = getValue().getPropertiesFiles();
if (!list.isEmpty()) {
return list.get(0).getVirtualFile();
}
@@ -88,7 +86,7 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
}
public void navigate(final boolean requestFocus) {
- OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), new ResourceBundleAsVirtualFile(getValue()));
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(getProject(), ResourceBundleAsVirtualFile.fromResourceBundle(getValue()));
FileEditorManager.getInstance(getProject()).openTextEditor(descriptor, requestFocus);
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java
deleted file mode 100644
index 99355d34bc6e..000000000000
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/PropertyRenameHandler.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.lang.properties.refactoring;
-
-import com.intellij.codeInsight.TargetElementUtilBase;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ScrollType;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
-import com.intellij.refactoring.rename.PsiElementRenameHandler;
-import com.intellij.lang.properties.references.PropertyReferenceBase;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * @author Dmitry Avdeev
- */
-public class PropertyRenameHandler extends PsiElementRenameHandler {
-
- public boolean isAvailableOnDataContext(final DataContext dataContext) {
- final Editor editor = LangDataKeys.EDITOR.getData(dataContext);
- if (editor != null) {
- if (getPsiElement(editor) != null) return true;
- }
- return false;
- }
-
- @Nullable
- private static PsiElement getPsiElement(final Editor editor) {
- final PsiReference reference = TargetElementUtilBase.findReference(editor);
- if (reference instanceof PropertyReferenceBase) {
- final ResolveResult[] resolveResults = ((PropertyReferenceBase)reference).multiResolve(false);
- return resolveResults.length > 0 ? resolveResults[0].getElement() : null;
- } else if (reference instanceof PsiMultiReference) {
- final PsiReference[] references = ((PsiMultiReference)reference).getReferences();
- for (PsiReference psiReference : references) {
- if (psiReference instanceof PropertyReferenceBase) {
- final ResolveResult[] resolveResults = ((PropertyReferenceBase)psiReference).multiResolve(false);
- if (resolveResults.length > 0) return resolveResults[0].getElement();
- }
- }
- }
- return null;
- }
-
- @Override
- public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) {
- PsiElement element = getPsiElement(editor);
- editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
- final PsiElement nameSuggestionContext = file.findElementAt(editor.getCaretModel().getOffset());
- invoke(element, project, nameSuggestionContext, editor);
- }
-}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java
deleted file mode 100644
index 7d7dbc14aead..000000000000
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleKeyRenameHandler.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.lang.properties.refactoring;
-
-import com.intellij.lang.properties.IProperty;
-import com.intellij.lang.properties.PropertiesBundle;
-import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.editor.ResourceBundleEditor;
-import com.intellij.lang.properties.editor.ResourceBundleEditorUtil;
-import com.intellij.lang.properties.editor.ResourceBundleUtil;
-import com.intellij.lang.properties.psi.PropertiesFile;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileEditor.FileEditorStateLevel;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.InputValidator;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.refactoring.rename.RenameHandler;
-import com.intellij.util.containers.HashSet;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Set;
-
-/**
- * Encapsulates logic of renaming resource bundle property key.
- *
- * @author Denis Zhdanov
- * @since 11/9/10 4:13 PM
- */
-public class ResourceBundleKeyRenameHandler implements RenameHandler {
-
- @Override
- public boolean isAvailableOnDataContext(DataContext dataContext) {
- ResourceBundleEditor editor = ResourceBundleEditorUtil.getEditor(dataContext);
- if (editor == null) {
- return false;
- }
- return editor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName() != null;
- }
-
- @Override
- public boolean isRenaming(DataContext dataContext) {
- return isAvailableOnDataContext(dataContext);
- }
-
- @Override
- public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
- ResourceBundleEditor bundleEditor = ResourceBundleEditorUtil.getEditor(dataContext);
- if (bundleEditor == null) {
- return;
- }
-
- String propertyName = bundleEditor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName();
- if (propertyName == null) {
- return;
- }
-
- ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
- if (bundle == null) {
- return;
- }
- Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.key.name.prompt.text"),
- PropertiesBundle.message("rename.resource.bundle.key.dialog.title"), Messages.getQuestionIcon(), propertyName,
- new ResourceBundleKeyRenameValidator(project, bundleEditor, bundle, propertyName));
- }
-
- @Override
- public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
- invoke(project, null, null, dataContext);
- }
-
- private static class ResourceBundleKeyRenameValidator implements InputValidator {
-
- private final Set<String> myExistingProperties = new HashSet<String>();
-
- private final ResourceBundleEditor myEditor;
- private final String myOldPropertyName;
-
- ResourceBundleKeyRenameValidator(Project project, ResourceBundleEditor editor, ResourceBundle bundle, String oldPropertyName) {
- myEditor = editor;
- myOldPropertyName = oldPropertyName;
- for (PropertiesFile file : bundle.getPropertiesFiles(project)) {
- for (IProperty property : file.getProperties()) {
- myExistingProperties.add(property.getKey());
- }
- }
- myExistingProperties.remove(oldPropertyName);
- }
-
- @Override
- public boolean checkInput(String inputString) {
- return inputString != null && !inputString.isEmpty() && !myExistingProperties.contains(inputString);
- }
-
- @Override
- public boolean canClose(final String inputString) {
- if (!checkInput(inputString)) {
- return false;
- }
-
- if (myOldPropertyName.equals(inputString)) {
- return true;
- }
-
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- myEditor.renameProperty(myOldPropertyName, inputString);
- }
- });
- return true;
- }
- }
-}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java
deleted file mode 100644
index fe555a7a2ca7..000000000000
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/ResourceBundleRenameHandler.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Alexey
- */
-package com.intellij.lang.properties.refactoring;
-
-import com.intellij.codeInsight.FileModificationService;
-import com.intellij.lang.properties.PropertiesBundle;
-import com.intellij.lang.properties.ResourceBundle;
-import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
-import com.intellij.lang.properties.editor.ResourceBundleEditor;
-import com.intellij.lang.properties.editor.ResourceBundleEditorUtil;
-import com.intellij.lang.properties.editor.ResourceBundleUtil;
-import com.intellij.lang.properties.psi.PropertiesFile;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.fileEditor.FileEditorStateLevel;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.InputValidator;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.refactoring.rename.RenameHandler;
-import com.intellij.refactoring.rename.RenameProcessor;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.util.List;
-
-public class ResourceBundleRenameHandler implements RenameHandler {
- private static final Logger LOG = Logger.getInstance("#" + ResourceBundleRenameHandler.class.getName());
-
- public boolean isAvailableOnDataContext(DataContext dataContext) {
- final Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (project == null) {
- return false;
- }
- final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
- if (bundle == null) {
- return false;
- }
-
- final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
-
- ResourceBundleEditor editor = ResourceBundleEditorUtil.getEditor(dataContext);
- return (editor == null || editor.getState(FileEditorStateLevel.NAVIGATION).getPropertyName() == null /* user selected non-bundle key element */)
- && bundle.getPropertiesFiles(project).size() > 1 && (virtualFile instanceof ResourceBundleAsVirtualFile || virtualFile == null);
- }
-
- public boolean isRenaming(DataContext dataContext) {
- return isAvailableOnDataContext(dataContext);
- }
-
- public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
- ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
-
- assert resourceBundle != null;
- Messages.showInputDialog(project,
- PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.base.name.prompt.text"),
- PropertiesBundle.message("rename.resource.bundle.dialog.title"),
- Messages.getQuestionIcon(),
- resourceBundle.getBaseName(),
- new MyInputValidator(project, resourceBundle));
- }
-
- public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
- invoke(project, null, null, dataContext);
- }
-
- private static class MyInputValidator implements InputValidator {
- private final Project myProject;
- private final ResourceBundle myResourceBundle;
-
- public MyInputValidator(final Project project, final ResourceBundle resourceBundle) {
- myProject = project;
- myResourceBundle = resourceBundle;
- }
-
- public boolean checkInput(String inputString) {
- return inputString.indexOf(File.separatorChar) < 0 && inputString.indexOf('/') < 0;
- }
-
- public boolean canClose(final String inputString) {
- return doRename(inputString);
- }
- private boolean doRename(final String inputString) {
- final List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles(myProject);
- for (PropertiesFile propertiesFile : propertiesFiles) {
- if (!FileModificationService.getInstance().prepareFileForWrite(propertiesFile.getContainingFile())) return false;
- }
-
- RenameProcessor renameProcessor = null;
- String baseName = myResourceBundle.getBaseName();
- for (PropertiesFile propertiesFile : propertiesFiles) {
- final VirtualFile virtualFile = propertiesFile.getVirtualFile();
- if (virtualFile == null) {
- continue;
- }
- final String newName = inputString + virtualFile.getNameWithoutExtension().substring(baseName.length()) + "."
- + virtualFile.getExtension();
- if (renameProcessor == null) {
- renameProcessor = new RenameProcessor(myProject, propertiesFile.getContainingFile(), newName, false, false);
- continue;
- }
- renameProcessor.addElement(propertiesFile.getContainingFile(), newName);
- }
- if (renameProcessor == null) {
- LOG.assertTrue(false);
- return true;
- }
- renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.dialog.title"));
- renameProcessor.doRun();
- return true;
- }
- }
-} \ No newline at end of file
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java
index 6bdaa0957133..f3c81736673f 100644
--- a/plugins/properties/src/com/intellij/lang/properties/refactoring/RenamePropertyProcessor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/RenamePropertyProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.lang.properties.refactoring;
+package com.intellij.lang.properties.refactoring.rename;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.lang.properties.refactoring.PropertiesRefactoringSettings;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
@@ -26,6 +28,7 @@ import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.usageView.UsageInfo;
import org.jetbrains.annotations.NotNull;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -36,12 +39,17 @@ public class RenamePropertyProcessor extends RenamePsiElementProcessor {
public void prepareRenaming(final PsiElement element, final String newName,
final Map<PsiElement, String> allRenames) {
- IProperty property = (IProperty) element;
- ResourceBundle resourceBundle = property.getPropertiesFile().getResourceBundle();
- List<IProperty> properties = PropertiesUtil.findAllProperties(element.getProject(), resourceBundle, property.getUnescapedKey());
+ final Project project = element.getProject();
+ ResourceBundle resourceBundle = ((IProperty) element).getPropertiesFile().getResourceBundle();
+
+ final Map<PsiElement, String> allRenamesCopy = new LinkedHashMap<PsiElement, String>(allRenames);
allRenames.clear();
- for (IProperty otherProperty : properties) {
- allRenames.put(otherProperty.getPsiElement(), newName);
+ for (final Map.Entry<PsiElement, String> e : allRenamesCopy.entrySet()) {
+ final IProperty property = (IProperty) e.getKey();
+ final List<IProperty> properties = PropertiesUtil.findAllProperties(project, resourceBundle, property.getUnescapedKey());
+ for (final IProperty toRename : properties) {
+ allRenames.put(toRename.getPsiElement(), e.getValue());
+ }
}
}
@@ -50,14 +58,16 @@ public class RenamePropertyProcessor extends RenamePsiElementProcessor {
final String newName,
Map<? extends PsiElement, String> allRenames,
List<UsageInfo> result) {
- for (IProperty property : ((PropertiesFile)element.getContainingFile()).getProperties()) {
- if (Comparing.strEqual(newName, property.getKey())) {
- result.add(new UnresolvableCollisionUsageInfo(property.getPsiElement(), element) {
- @Override
- public String getDescription() {
- return "New property name \'" + newName + "\' hides existing property";
- }
- });
+ for (final Map.Entry<? extends PsiElement, String> e: allRenames.entrySet()) {
+ for (IProperty property : ((PropertiesFile)e.getKey().getContainingFile()).getProperties()) {
+ if (Comparing.strEqual(e.getValue(), property.getKey())) {
+ result.add(new UnresolvableCollisionUsageInfo(property.getPsiElement(), e.getKey()) {
+ @Override
+ public String getDescription() {
+ return "New property name \'" + e.getValue() + "\' hides existing property";
+ }
+ });
+ }
}
}
}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java
new file mode 100644
index 000000000000..0c04bec80620
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromEditorRenameHandler.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexey
+ */
+package com.intellij.lang.properties.refactoring.rename;
+
+import com.intellij.ide.util.treeView.smartTree.TreeElement;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.editor.*;
+import com.intellij.lang.properties.structureView.PropertiesPrefixGroup;
+import com.intellij.lang.properties.structureView.PropertiesStructureViewElement;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.rename.RenameHandler;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleFromEditorRenameHandler implements RenameHandler {
+
+ @Override
+ public boolean isAvailableOnDataContext(DataContext dataContext) {
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (project == null) {
+ return false;
+ }
+ final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
+ if (bundle == null) {
+ return false;
+ }
+ final FileEditor fileEditor = PlatformDataKeys.FILE_EDITOR.getData(dataContext);
+ if (fileEditor == null || !(fileEditor instanceof ResourceBundleEditor)) {
+ return false;
+ }
+ final VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
+ return !(virtualFile == null || !(virtualFile instanceof ResourceBundleAsVirtualFile));
+ }
+
+ @Override
+ public boolean isRenaming(DataContext dataContext) {
+ return isAvailableOnDataContext(dataContext);
+ }
+
+ @Override
+ public void invoke(final @NotNull Project project, Editor editor, final PsiFile file, DataContext dataContext) {
+ final ResourceBundleEditor resourceBundleEditor = (ResourceBundleEditor)PlatformDataKeys.FILE_EDITOR.getData(dataContext);
+ assert resourceBundleEditor != null;
+ final ResourceBundleEditorViewElement selectedElement = resourceBundleEditor.getSelectedElement();
+ if (selectedElement != null) {
+ CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
+ @Override
+ public void run() {
+ if (selectedElement instanceof PropertiesPrefixGroup) {
+ final PropertiesPrefixGroup group = (PropertiesPrefixGroup)selectedElement;
+ ResourceBundleRenameUtil.renameResourceBundleKeySection(getPsiElementsFromGroup(group),
+ group.getPresentableName(),
+ group.getPrefix().length() - group.getPresentableName().length());
+ } else if (selectedElement instanceof ResourceBundlePropertyStructureViewElement) {
+ final PsiElement psiElement = ((ResourceBundlePropertyStructureViewElement)selectedElement).getProperty().getPsiElement();
+ ResourceBundleRenameUtil.renameResourceBundleKey(psiElement, project);
+ } else if (selectedElement instanceof ResourceBundleFileStructureViewElement) {
+ ResourceBundleRenameUtil.renameResourceBundleBaseName(((ResourceBundleFileStructureViewElement)selectedElement).getValue(), project);
+ } else {
+ throw new IllegalStateException("unsupported type: " + selectedElement.getClass());
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+ invoke(project, null, null, dataContext);
+ }
+
+ private static List<PsiElement> getPsiElementsFromGroup(final PropertiesPrefixGroup propertiesPrefixGroup) {
+ return ContainerUtil.mapNotNull(propertiesPrefixGroup.getChildren(), new NullableFunction<TreeElement, PsiElement>() {
+ @Nullable
+ @Override
+ public PsiElement fun(TreeElement treeElement) {
+ if (treeElement instanceof PropertiesStructureViewElement) {
+ return ((PropertiesStructureViewElement)treeElement).getValue().getPsiElement();
+ }
+ if (treeElement instanceof ResourceBundlePropertyStructureViewElement) {
+ return ((ResourceBundlePropertyStructureViewElement)treeElement).getProperty().getPsiElement();
+ }
+ return null;
+ }
+ });
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java
new file mode 100644
index 000000000000..f2cbca033b6b
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleFromProjectViewRenameHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.refactoring.rename;
+
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.editor.*;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.RefactoringActionHandlerFactory;
+import com.intellij.refactoring.rename.RenameHandler;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleFromProjectViewRenameHandler implements RenameHandler {
+
+ @Override
+ public boolean isAvailableOnDataContext(DataContext dataContext) {
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (project == null) {
+ return false;
+ }
+ final ResourceBundle bundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
+ if (bundle == null || bundle.getPropertiesFiles().size() < 2) {
+ return false;
+ }
+ return PlatformDataKeys.FILE_EDITOR.getData(dataContext) == null && CommonDataKeys.VIRTUAL_FILE.getData(dataContext) == null;
+ }
+
+ @Override
+ public boolean isRenaming(DataContext dataContext) {
+ return isAvailableOnDataContext(dataContext);
+ }
+
+ @Override
+ public void invoke(final @NotNull Project project, Editor editor, final PsiFile file, DataContext dataContext) {
+ final ResourceBundle resourceBundle = ResourceBundleUtil.getResourceBundleFromDataContext(dataContext);
+ assert resourceBundle != null;
+ RefactoringActionHandlerFactory.getInstance().createRenameHandler().invoke(project, new PsiElement[] {resourceBundle.getDefaultPropertiesFile().getContainingFile()}, dataContext);
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
+ invoke(project, null, null, dataContext);
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java
new file mode 100644
index 000000000000..79694f7ae35a
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenameUtil.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.refactoring.rename;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.ResourceBundle;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.InputValidator;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.refactoring.rename.PsiElementRenameHandler;
+import com.intellij.refactoring.rename.RenameProcessor;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleRenameUtil {
+ private final static Logger LOG = Logger.getInstance(ResourceBundleRenameUtil.class);
+
+ public static void renameResourceBundleKey(final @NotNull PsiElement psiElement, final @NotNull Project project) {
+ PsiElementRenameHandler.invoke(psiElement, project, psiElement.getContainingFile(), null);
+ }
+
+ public static void renameResourceBundleBaseName(final @NotNull ResourceBundle resourceBundle, final @NotNull Project project) {
+ Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.base.name.prompt.text"),
+ PropertiesBundle.message("rename.resource.bundle.dialog.title"), Messages.getQuestionIcon(),
+ resourceBundle.getBaseName(), new ResourceBundleBaseNameInputValidator(project, resourceBundle));
+ }
+
+ public static void renameResourceBundleKeySection(final List<PsiElement> psiElements, final String section, final int sectionPosition) {
+ if (psiElements.isEmpty()) {
+ return;
+ }
+ final Project project = psiElements.get(0).getProject();
+ Messages.showInputDialog(project, PropertiesBundle.message("rename.bundle.enter.new.resource.bundle.section.name.prompt.text"),
+ PropertiesBundle.message("rename.resource.bundle.section.dialog.title"), Messages.getQuestionIcon(), section,
+ new ResourceBundleKeySectionInputValidator(psiElements, section, sectionPosition, project));
+ }
+
+ private static class ResourceBundleKeySectionInputValidator implements InputValidator {
+
+ private final List<PsiElement> myPsiElements;
+ private final String mySection;
+ private final int mySectionPosition;
+ private final Project myProject;
+
+ private ResourceBundleKeySectionInputValidator(final List<PsiElement> psiElements,
+ final String section,
+ final int sectionPosition,
+ final Project project) {
+ myPsiElements = psiElements;
+ mySection = section;
+ mySectionPosition = sectionPosition;
+ myProject = project;
+ }
+
+ @Override
+ public boolean checkInput(final String inputString) {
+ return inputString.indexOf('.') < 0;
+ }
+
+ @Override
+ public boolean canClose(final String inputString) {
+ RenameProcessor renameProcessor = null;
+ for (final PsiElement psiElement : myPsiElements) {
+ assert psiElement instanceof PsiNamedElement;
+ final String oldName = ((PsiNamedElement)psiElement).getName();
+ assert oldName != null;
+ final String newName =
+ oldName.substring(0, mySectionPosition) + inputString + oldName.substring(mySectionPosition + mySection.length());
+ if (renameProcessor == null) {
+ renameProcessor = new RenameProcessor(myProject, psiElement, newName, false, false);
+ }
+ else {
+ renameProcessor.addElement(psiElement, newName);
+ }
+ }
+ assert renameProcessor != null;
+ renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.section.dialog.title"));
+ renameProcessor.doRun();
+ return true;
+ }
+ }
+
+ private static class ResourceBundleBaseNameInputValidator implements InputValidator {
+ private final Project myProject;
+ private final ResourceBundle myResourceBundle;
+
+ public ResourceBundleBaseNameInputValidator(final Project project, final ResourceBundle resourceBundle) {
+ myProject = project;
+ myResourceBundle = resourceBundle;
+ }
+
+ public boolean checkInput(String inputString) {
+ return inputString.indexOf(File.separatorChar) < 0 && inputString.indexOf('/') < 0;
+ }
+
+ public boolean canClose(final String inputString) {
+ final List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
+ for (PropertiesFile propertiesFile : propertiesFiles) {
+ if (!FileModificationService.getInstance().prepareFileForWrite(propertiesFile.getContainingFile())) return false;
+ }
+
+ RenameProcessor renameProcessor = null;
+ final String baseName = myResourceBundle.getBaseName();
+ for (PropertiesFile propertiesFile : propertiesFiles) {
+ final VirtualFile virtualFile = propertiesFile.getVirtualFile();
+ if (virtualFile == null) {
+ continue;
+ }
+ final String newName =
+ inputString + virtualFile.getNameWithoutExtension().substring(baseName.length()) + "." + virtualFile.getExtension();
+ if (renameProcessor == null) {
+ renameProcessor = new RenameProcessor(myProject, propertiesFile.getContainingFile(), newName, false, false);
+ continue;
+ }
+ renameProcessor.addElement(propertiesFile.getContainingFile(), newName);
+ }
+ if (renameProcessor == null) {
+ LOG.assertTrue(false);
+ return true;
+ }
+
+ renameProcessor.setCommandName(PropertiesBundle.message("rename.resource.bundle.dialog.title"));
+ renameProcessor.doRun();
+
+ return true;
+ }
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java
new file mode 100644
index 000000000000..ab1b4391b0f6
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.refactoring.rename;
+
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.PropertiesUtil;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.refactoring.rename.naming.AutomaticRenamer;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleRenamer extends AutomaticRenamer {
+
+ public ResourceBundleRenamer(final PropertiesFile propertiesFile, final String newName) {
+ for (final PropertiesFile file : propertiesFile.getResourceBundle().getPropertiesFiles()) {
+ if (file.equals(propertiesFile)) {
+ continue;
+ }
+ final PsiFile containingFile = file.getContainingFile();
+ myElements.add(containingFile);
+ }
+ suggestAllNames(propertiesFile.getName(), newName);
+ }
+
+ @Override
+ protected String nameToCanonicalName(@NonNls final String name, final PsiNamedElement element) {
+ return PropertiesUtil.getBaseName((PsiFile)element);
+ }
+
+ @Override
+ protected String canonicalNameToName(@NonNls final String canonicalName, final PsiNamedElement element) {
+ final String oldCanonicalName = PropertiesUtil.getBaseName((PsiFile)element);
+ final String oldName = element.getName();
+ assert oldName != null;
+ return canonicalName + oldName.substring(oldCanonicalName.length());
+ }
+
+ @Override
+ public boolean isSelectedByDefault() {
+ return true;
+ }
+
+ @Override
+ public String getDialogTitle() {
+ return PropertiesBundle.message("resource.bundle.renamer");
+ }
+
+ @Override
+ public String getDialogDescription() {
+ return PropertiesBundle.message("resource.bundle.renamer.dialog.description");
+ }
+
+ @Override
+ public String entityName() {
+ return PropertiesBundle.message("resource.bundle.renamer.entity.name");
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java
new file mode 100644
index 000000000000..ec4bd31acbf3
--- /dev/null
+++ b/plugins/properties/src/com/intellij/lang/properties/refactoring/rename/ResourceBundleRenamerFactory.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties.refactoring.rename;
+
+import com.intellij.lang.properties.PropertiesBundle;
+import com.intellij.lang.properties.PropertiesImplUtil;
+import com.intellij.lang.properties.psi.PropertiesFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.rename.naming.AutomaticRenamer;
+import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory;
+import com.intellij.usageView.UsageInfo;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleRenamerFactory implements AutomaticRenamerFactory {
+ @Override
+ public boolean isApplicable(final PsiElement element) {
+ if (!(element instanceof PsiFile)) {
+ return false;
+ }
+ return PropertiesImplUtil.isPropertiesFile((PsiFile)element);
+ }
+
+
+ @Nullable
+ @Override
+ public String getOptionName() {
+ return PropertiesBundle.message("resource.bundle.renamer.option");
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public void setEnabled(final boolean enabled) {
+ }
+
+ @Override
+ public AutomaticRenamer createRenamer(final PsiElement element, final String newName, final Collection<UsageInfo> usages) {
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile)element);
+ assert propertiesFile != null;
+ return new ResourceBundleRenamer(propertiesFile, newName);
+ }
+}
diff --git a/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java b/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java
index b19510be034b..f044a6db681c 100644
--- a/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java
+++ b/plugins/properties/src/com/intellij/lang/properties/references/I18nizeQuickFixDialog.java
@@ -275,7 +275,7 @@ public class I18nizeQuickFixDialog extends DialogWrapper implements I18nizeQuick
private void propertiesFileChanged() {
PropertiesFile propertiesFile = getPropertiesFile();
boolean hasResourceBundle =
- propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles(propertiesFile.getProject()).size() > 1;
+ propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles().size() > 1;
myUseResourceBundle.setEnabled(hasResourceBundle);
}
@@ -497,7 +497,7 @@ public class I18nizeQuickFixDialog extends DialogWrapper implements I18nizeQuick
if (propertiesFile == null) return Collections.emptySet();
Collection<PropertiesFile> propertiesFiles;
if (isUseResourceBundle()) {
- propertiesFiles = propertiesFile.getResourceBundle().getPropertiesFiles(myProject);
+ propertiesFiles = propertiesFile.getResourceBundle().getPropertiesFiles();
}
else {
propertiesFiles = Collections.singleton(propertiesFile);
diff --git a/plugins/properties/src/com/intellij/lang/properties/references/PropertiesCompletionContributor.java b/plugins/properties/src/com/intellij/lang/properties/references/PropertiesCompletionContributor.java
index e356771d5812..5502ec336566 100644
--- a/plugins/properties/src/com/intellij/lang/properties/references/PropertiesCompletionContributor.java
+++ b/plugins/properties/src/com/intellij/lang/properties/references/PropertiesCompletionContributor.java
@@ -30,9 +30,11 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
-import com.intellij.util.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.FilteringIterator;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
@@ -55,12 +57,11 @@ public class PropertiesCompletionContributor extends CompletionContributor {
});
}
- private static final Condition<PsiReference> PROPERTY_REFERENCE = FilteringIterator.instanceOf(PropertyReference.class);
- private void doAdd(CompletionParameters parameters, final CompletionResultSet result) {
+ private static void doAdd(CompletionParameters parameters, final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
PsiReference[] references = ArrayUtil.mergeArrays(position.getReferences(), position.getParent().getReferences());
- PropertyReference propertyReference = (PropertyReference)ContainerUtil.find(references, PROPERTY_REFERENCE);
- if (propertyReference != null) {
+ PropertyReference propertyReference = ContainerUtil.findInstance(references, PropertyReference.class);
+ if (propertyReference != null && !hasMoreImportantReference(references, propertyReference)) {
final int startOffset = parameters.getOffset();
PsiElement element = propertyReference.getElement();
final int offsetInElement = startOffset - element.getTextRange().getStartOffset();
@@ -69,17 +70,16 @@ public class PropertiesCompletionContributor extends CompletionContributor {
LookupElement[] variants = getVariants(propertyReference);
result.withPrefixMatcher(prefix).addAllElements(Arrays.asList(variants));
- if (variants.length != 0) {
- result.stopHere();
- }
}
- //if (parameters.isExtendedCompletion()) {
- // CompletionService.getCompletionService().getVariantsFromContributors(parameters.delegateToClassName(), null, new Consumer<CompletionResult>() {
- // public void consume(final CompletionResult completionResult) {
- // result.passResult(completionResult);
- // }
- // });
- //}
+ }
+
+ private static boolean hasMoreImportantReference(PsiReference[] references, PropertyReference propertyReference) {
+ return propertyReference.isSoft() && ContainerUtil.or(references, new Condition<PsiReference>() {
+ @Override
+ public boolean value(PsiReference reference) {
+ return !reference.isSoft();
+ }
+ });
}
public static final LookupElementRenderer<LookupElement> LOOKUP_ELEMENT_RENDERER = new LookupElementRenderer<LookupElement>() {
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeys/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateKeys/expected.xml
new file mode 100644
index 000000000000..be6d81f7d5f5
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeys/expected.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test2.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test1.properties b/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test1.properties
new file mode 100644
index 000000000000..b429b975e786
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test1.properties
@@ -0,0 +1,2 @@
+key1=value1
+key12=value2
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test2.properties b/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test2.properties
new file mode 100644
index 000000000000..3d6fbfa12610
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeys/src/Test2.properties
@@ -0,0 +1,2 @@
+key1=value1
+key22=value2 \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/expected.xml
new file mode 100644
index 000000000000..7f59ffeee20e
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/expected.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test2.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test2.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test1.properties b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test1.properties
new file mode 100644
index 000000000000..b429b975e786
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test1.properties
@@ -0,0 +1,2 @@
+key1=value1
+key12=value2
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test2.properties b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test2.properties
new file mode 100644
index 000000000000..54dcfaf7230d
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithAndWithoutDifferent/src/Test2.properties
@@ -0,0 +1,2 @@
+key1=value2
+key22=value2 \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/expected.xml
new file mode 100644
index 000000000000..be6d81f7d5f5
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/expected.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test2.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test1.properties b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test1.properties
new file mode 100644
index 000000000000..e3478cbf3733
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test1.properties
@@ -0,0 +1,3 @@
+key1=value11
+key12=value12
+key13=value13 \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test2.properties b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test2.properties
new file mode 100644
index 000000000000..fad421ff11ea
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateKeysWithDifferentValues/src/Test2.properties
@@ -0,0 +1,3 @@
+key1=value12
+key22=value22
+key23=value23
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValues/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateValues/expected.xml
new file mode 100644
index 000000000000..e08ffe362159
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValues/expected.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems>
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValues/src/Test.properties b/plugins/properties/testData/duplicateProperty/duplicateValues/src/Test.properties
new file mode 100644
index 000000000000..6ed8838e3d70
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValues/src/Test.properties
@@ -0,0 +1,3 @@
+key1=value
+key2=value2
+key3=value \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/expected.xml
new file mode 100644
index 000000000000..163ab844d9a1
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/expected.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test1.properties b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test1.properties
new file mode 100644
index 000000000000..ba3a7e2f1192
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test1.properties
@@ -0,0 +1,3 @@
+key11=value
+key12=value12
+key13=value \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test2.properties b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test2.properties
new file mode 100644
index 000000000000..42e8a6631cb8
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesCurrentFileAnalysis/src/Test2.properties
@@ -0,0 +1,3 @@
+key21=value
+key22=value22
+key23=value23
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/expected.xml b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/expected.xml
new file mode 100644
index 000000000000..0333b5edb5c6
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/expected.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+ <problem>
+ <file>Test1.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+ <problem>
+ <file>Test2.properties</file>
+ <line>1</line>
+ <description>Duplicate</description>
+ </problem>
+</problems> \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test1.properties b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test1.properties
new file mode 100644
index 000000000000..ba3a7e2f1192
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test1.properties
@@ -0,0 +1,3 @@
+key11=value
+key12=value12
+key13=value \ No newline at end of file
diff --git a/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test2.properties b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test2.properties
new file mode 100644
index 000000000000..42e8a6631cb8
--- /dev/null
+++ b/plugins/properties/testData/duplicateProperty/duplicateValuesInDifferentFiles/src/Test2.properties
@@ -0,0 +1,3 @@
+key21=value
+key22=value22
+key23=value23
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/DuplicatePropertyInspectionTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/DuplicatePropertyInspectionTest.java
new file mode 100644
index 000000000000..b33a69cc86ca
--- /dev/null
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/DuplicatePropertyInspectionTest.java
@@ -0,0 +1,72 @@
+package com.intellij.lang.properties;
+
+import com.intellij.codeInspection.duplicatePropertyInspection.DuplicatePropertyInspection;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.testFramework.InspectionTestCase;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ * Date: 05-Sep-2005
+ */
+public class DuplicatePropertyInspectionTest extends InspectionTestCase {
+ //ProblemDescriptor.getLineNumber()==1 for this inspection (there is no RefPropertyElement thus PsiElement -> PsiFile)
+ private DuplicatePropertyInspection myTool;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myTool = new DuplicatePropertyInspection();
+ }
+
+ private void doTest() throws Exception {
+ doTest("duplicateProperty/" + getTestName(true), myTool);
+ }
+
+ public void testDuplicateValues() throws Exception{
+ doTest();
+ }
+
+ public void testDuplicateValuesCurrentFileAnalysis() throws Exception{
+ doTest();
+ }
+
+ public void testDuplicateValuesInDifferentFiles() throws Exception{
+ myTool.CURRENT_FILE = false;
+ myTool.MODULE_WITH_DEPENDENCIES = true;
+ doTest();
+ }
+
+ public void testDuplicateKeysWithDifferentValues() throws Exception{
+ myTool.CURRENT_FILE = false;
+ myTool.MODULE_WITH_DEPENDENCIES = true;
+ myTool.CHECK_DUPLICATE_KEYS = false;
+ myTool.CHECK_DUPLICATE_VALUES = false;
+ myTool.CHECK_DUPLICATE_KEYS_WITH_DIFFERENT_VALUES = true;
+ doTest();
+ }
+
+ public void testDuplicateKeys() throws Exception{
+ myTool.CURRENT_FILE = false;
+ myTool.MODULE_WITH_DEPENDENCIES = true;
+ myTool.CHECK_DUPLICATE_KEYS = true;
+ myTool.CHECK_DUPLICATE_VALUES = false;
+ myTool.CHECK_DUPLICATE_KEYS_WITH_DIFFERENT_VALUES = false;
+ doTest();
+ }
+
+ public void testDuplicateKeysWithAndWithoutDifferent() throws Exception{
+ myTool.CURRENT_FILE = false;
+ myTool.MODULE_WITH_DEPENDENCIES = true;
+ myTool.CHECK_DUPLICATE_KEYS = true;
+ myTool.CHECK_DUPLICATE_VALUES = false;
+ myTool.CHECK_DUPLICATE_KEYS_WITH_DIFFERENT_VALUES = true;
+ doTest();
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("properties") + "/testData";
+ }
+}
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
index 5ebf25d4258f..20c44e9f47e0 100644
--- a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesUtilTest.java
@@ -16,13 +16,16 @@
package com.intellij.lang.properties;
import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.FakePsiElement;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Batkovich
*/
-public class PropertiesUtilTest extends TestCase {
+public class PropertiesUtilTest extends LightPlatformCodeInsightFixtureTestCase {
public void testBaseNameWithoutLocale() {
assertBaseNameEquals("property-file.properties", "property-file");
@@ -40,6 +43,10 @@ public class PropertiesUtilTest extends TestCase {
assertBaseNameEquals("property-file_fr.file_en.utf8.properties", "property-file_fr.file.utf8");
}
+ public void testBaseNameWithLongLocale() {
+ assertBaseNameEquals("property_latin.properties", "property");
+ }
+
public void testBaseNameWithCountryAndVariant() {
assertBaseNameEquals("property-file_fr.file_en_GB_UNIX.utf8.properties", "property-file_fr.file.utf8");
}
@@ -52,24 +59,18 @@ public class PropertiesUtilTest extends TestCase {
assertBaseNameEquals("Base_Properties.utf8.properties", "Base_Properties.utf8");
}
- public void test1() {
+ public void _test1() {
assertBaseNameEquals("Base_Page_fr.utf8.properties", "Base_Page.utf8");
}
- public void test2() {
+ public void _test2() {
assertBaseNameEquals("Base_Page_en.utf8.properties", "Base_Page.utf8");
}
- public void test3() {
+ public void _test3() {
assertBaseNameEquals("Base_Page.utf8.properties", "Base_Page.utf8");
}
- private static void assertBaseNameEquals(final String propertyFileName, final String expectedBaseName) {
- final String actualBaseName = PropertiesUtil.getBaseName(new StubVirtualFile() {
- @NotNull
- @Override
- public String getName() {
- return propertyFileName;
- }
- });
+ private void assertBaseNameEquals(final String propertyFileName, final String expectedBaseName) {
+ final String actualBaseName = PropertiesUtil.getBaseName(myFixture.configureByText(propertyFileName, ""));
assertEquals(expectedBaseName, actualBaseName);
}
}
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java
new file mode 100644
index 000000000000..f8c435817ea4
--- /dev/null
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/ResourceBundleRenameTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.properties;
+
+import com.intellij.lang.properties.refactoring.rename.ResourceBundleRenamerFactory;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.rename.RenameProcessor;
+import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ResourceBundleRenameTest extends LightPlatformCodeInsightFixtureTestCase {
+
+ public void testRenameResourceBundleEntryFile() {
+ final PsiFile toRenameFile = myFixture.addFileToProject("old_p.properties", "");
+ final PsiFile toCheck = myFixture.addFileToProject("old_p_en.properties", "");
+
+ final RenameProcessor processor = new RenameProcessor(getProject(), toRenameFile, "new_p.properties", true, true);
+ for (AutomaticRenamerFactory factory : Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) {
+ if (factory instanceof ResourceBundleRenamerFactory) {
+ processor.addRenamerFactory(factory);
+ }
+ }
+ processor.run();
+
+ assertEquals("new_p_en.properties", toCheck.getName());
+ }
+
+ public void testRenamePropertyKey() {
+ final PsiFile toCheckFile = myFixture.addFileToProject("p.properties", "key=value");
+ myFixture.configureByText("p_en.properties", "ke<caret>y=en_value");
+ myFixture.renameElementAtCaret("new_key");
+ assertEquals(toCheckFile.getText(), "new_key=value");
+ }
+}
diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/xml/XmlPropertiesTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/xml/XmlPropertiesTest.java
index 66bb380d992c..9e1235399b03 100644
--- a/plugins/properties/testSrc/com/intellij/lang/properties/xml/XmlPropertiesTest.java
+++ b/plugins/properties/testSrc/com/intellij/lang/properties/xml/XmlPropertiesTest.java
@@ -5,6 +5,7 @@ import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.PropertiesReferenceManager;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
@@ -38,6 +39,22 @@ public class XmlPropertiesTest extends LightPlatformCodeInsightFixtureTestCase {
myFixture.testHighlighting("foo.xml");
}
+ public void testAddProperty() {
+ final PsiFile psiFile = myFixture.configureByFile("foo.xml");
+ final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(psiFile);
+ assertNotNull(propertiesFile);
+
+ WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {
+ public void run() {
+ propertiesFile.addProperty("kkk", "vvv");
+ }
+ });
+
+ final IProperty property = propertiesFile.findPropertyByKey("kkk");
+ assertNotNull(property);
+ assertEquals("vvv", property.getValue());
+ }
+
@Override
protected String getTestDataPath() {
return PluginPathManager.getPluginHomePath("properties") + "/testData/xml/";
diff --git a/plugins/structuralsearch/build.xml b/plugins/structuralsearch/build.xml
new file mode 100644
index 000000000000..942281dbfbb1
--- /dev/null
+++ b/plugins/structuralsearch/build.xml
@@ -0,0 +1,53 @@
+<project name="StructuralSearchPlugin" default="jar_plugin" basedir=".">
+ <property name="plugname" value="StructuralSearchPlugin"/>
+ <property name="releasePlugname" value="SS"/>
+ <property name="build.path" value="${project.path}/build_out"/>
+ <property name="version" value="0.7.0.1"/>
+ <property name="description" value="This is experimental yet useful plugin for searching source code
+ in terms of java syntax (query code by example :-). It is intended to be used for:
+ &amp;lt;LI&amp;gt;understanding new libraries, finding highlevel code patterns (singletons, serialization implementation,
+ Struts actions, ejbs, servlets, filters, source metadata, etc), analyzing
+ opportunities for aspect refactoring (finding exception handling, methods with
+ specific signatures and structure, etc). For instance, for exploring source code of JDK 1.5 with Aurora
+ one could use search to find added entities (classes, methods, etc), generic classes, methods and declarations or just
+ parameterized symbols. Note, that the plugin could miss some generic stuff that is not supported by Aurora (e.g. anonymous typed vars).
+ &amp;lt;LI&amp;gt; finding expressions, statements or group of statements regardsless of particular whitespace indentation.
+ This could be useful e.g. after applying extract method refactoring to find the other occurences the such extracted code.
+ &amp;lt;LI&amp;gt;Find code fragments (symbols, references, constants) like given pattern.
+ &amp;lt;BR&amp;gt;Warning, the plugin is PSI dependent, works with 1156 and 706" />
+ <target name="clean">
+ <delete includeEmptyDirs="true" failonerror="false">
+ <fileset dir="${build.path}" includes="**/*.class,**/*.html,META-INF/*.xml,META-INF/*.txt"/>
+ </delete>
+ <mkdir dir="${build.path}"/>
+ </target>
+ <target name="copy_files">
+ <copy todir="${build.path}/META-INF" >
+ <fileset dir="${project.path}/META-INF" includes="plugin.xml,version.txt"/>
+ </copy>
+ <copy todir="${build.path}/resources">
+ <fileset dir="${project.path}/resources"/>
+ </copy>
+ <copy todir="${build.path}">
+ <fileset dir="${project.path}/classes" includes="**/*.class">
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="version" depends="copy_files">
+ <replace dir="${build.path}" includes="**/*.xml **/*.html **/*.txt">
+ <replacefilter token="@PLUGIN.VERSION@" value="${version}"/>
+ <replacefilter token="@PLUGIN.DESCRIPTION@" value="${description}"/>
+ </replace>
+ </target>
+ <target name="jar_plugin" depends="clean,copy_files,version" >
+
+ <jar jarfile="${build.path}/${plugname}.jar" basedir="${build.path}"
+ excludes="${plugname}.jar"
+ />
+
+ <copy todir="${idea.path}/debug/plugins">
+ <fileset dir="${build.path}" includes="*.jar" />
+ </copy>
+ </target>
+</project>
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/DocumentBasedReplaceHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/DocumentBasedReplaceHandler.java
new file mode 100644
index 000000000000..1f319b8f15e5
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/DocumentBasedReplaceHandler.java
@@ -0,0 +1,55 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementInfoImpl;
+import com.intellij.util.containers.HashMap;
+
+import java.util.Map;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class DocumentBasedReplaceHandler extends StructuralReplaceHandler {
+ private final Project myProject;
+ private final Map<ReplacementInfo, RangeMarker> myRangeMarkers = new HashMap<ReplacementInfo, RangeMarker>();
+
+ DocumentBasedReplaceHandler(Project project) {
+ myProject = project;
+ }
+
+ public void replace(ReplacementInfo info, ReplaceOptions options) {
+ if (info.getMatchesCount() == 0) return;
+ assert info instanceof ReplacementInfoImpl;
+ PsiElement element = info.getMatch(0);
+ if (element == null) return;
+ PsiFile file = element instanceof PsiFile ? (PsiFile)element : element.getContainingFile();
+ assert file != null;
+ RangeMarker rangeMarker = myRangeMarkers.get(info);
+ Document document = rangeMarker.getDocument();
+ document.replaceString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), info.getReplacement());
+ PsiDocumentManager.getInstance(element.getProject()).commitDocument(document);
+ }
+
+ @Override
+ public void prepare(ReplacementInfo info) {
+ assert info instanceof ReplacementInfoImpl;
+ MatchResult result = ((ReplacementInfoImpl)info).getMatchResult();
+ PsiElement element = result.getMatch();
+ PsiFile file = element instanceof PsiFile ? (PsiFile)element : element.getContainingFile();
+ Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
+ TextRange textRange = result.getMatchRef().getElement().getTextRange();
+ assert textRange != null;
+ RangeMarker rangeMarker = document.createRangeMarker(textRange);
+ rangeMarker.setGreedyToLeft(true);
+ rangeMarker.setGreedyToRight(true);
+ myRangeMarkers.put(info, rangeMarker);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MalformedPatternException.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MalformedPatternException.java
new file mode 100644
index 000000000000..e73eddc19550
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MalformedPatternException.java
@@ -0,0 +1,11 @@
+package com.intellij.structuralsearch;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Class to indicate incorrect pattern
+ */
+public class MalformedPatternException extends RuntimeException {
+ public MalformedPatternException() {}
+ public MalformedPatternException(String msg) { super(msg); }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchOptions.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchOptions.java
new file mode 100644
index 000000000000..fb22f39990fa
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchOptions.java
@@ -0,0 +1,334 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.psi.search.SearchScope;
+import org.jdom.Attribute;
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * match options
+ */
+public class MatchOptions implements JDOMExternalizable, Cloneable {
+ @NonNls private static final String TEXT_ATTRIBUTE_NAME = "text";
+
+ private boolean looseMatching;
+ private boolean distinct;
+ private boolean recursiveSearch;
+ private boolean caseSensitiveMatch;
+ private boolean resultIsContextMatch = false;
+ private FileType myFileType = StructuralSearchUtil.getDefaultFileType();
+ private Language myDialect = null;
+ private int maxMatches = Integer.MAX_VALUE;
+
+ private SearchScope scope;
+ private SearchScope downUpMatchScope;
+ private String searchCriteria = "";
+ private Map<String,MatchVariableConstraint> variableConstraints;
+
+ private String myPatternContext;
+
+ @NonNls private static final String DISTINCT_ATTRIBUTE_NAME = "distinct";
+ @NonNls private static final String RECURSIVE_ATTRIBUTE_NAME = "recursive";
+ @NonNls private static final String CASESENSITIVE_ATTRIBUTE_NAME = "caseInsensitive";
+ //private static final String SCOPE_ATTRIBUTE_NAME = "scope";
+ @NonNls private static final String CONSTRAINT_TAG_NAME = "constraint";
+ @NonNls private static final String FILE_TYPE_ATTR_NAME = "type";
+ @NonNls private static final String DIALECT_ATTR_NAME = "dialect";
+ @NonNls public static final String INSTANCE_MODIFIER_NAME = "Instance";
+ @NonNls public static final String MODIFIER_ANNOTATION_NAME = "Modifier";
+
+ //private static final String UNDEFINED_SCOPE = "undefined";
+
+ public void addVariableConstraint(MatchVariableConstraint constraint) {
+ if (variableConstraints==null) {
+ variableConstraints = new LinkedHashMap<String,MatchVariableConstraint>();
+ }
+ variableConstraints.put( constraint.getName(), constraint );
+ }
+
+ public boolean hasVariableConstraints() {
+ return variableConstraints!=null;
+ }
+
+ public void clearVariableConstraints() {
+ variableConstraints=null;
+ }
+
+ public MatchVariableConstraint getVariableConstraint(String name) {
+ if (variableConstraints!=null) {
+ return variableConstraints.get(name);
+ }
+ return null;
+ }
+
+ public Iterator<String> getVariableConstraintNames() {
+ if (variableConstraints==null) return null;
+ return variableConstraints.keySet().iterator();
+ }
+
+ public void setCaseSensitiveMatch(boolean caseSensitiveMatch) {
+ this.caseSensitiveMatch = caseSensitiveMatch;
+ }
+
+ public boolean isCaseSensitiveMatch() {
+ return caseSensitiveMatch;
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ public String toString() {
+ StringBuffer result = new StringBuffer();
+
+ result.append("match options:\n");
+ result.append("search pattern:\n");
+ result.append(searchCriteria);
+ result.append("\nsearch scope:\n");
+
+ // @TODO print scope
+ //result.append((scopeHandler!=null)?scopeHandler.toString():"undefined scope");
+
+ result.append("\nrecursive:");
+ result.append(recursiveSearch);
+
+ result.append("\ndistinct:");
+ result.append(distinct);
+
+ result.append("\ncasesensitive:");
+ result.append(caseSensitiveMatch);
+
+ return result.toString();
+ }
+
+ public boolean isDistinct() {
+ return distinct;
+ }
+
+ public void setDistinct(boolean distinct) {
+ this.distinct = distinct;
+ }
+
+ public boolean isRecursiveSearch() {
+ return recursiveSearch;
+ }
+
+ public void setRecursiveSearch(boolean recursiveSearch) {
+ this.recursiveSearch = recursiveSearch;
+ }
+
+ public boolean isLooseMatching() {
+ return looseMatching;
+ }
+
+ public void setLooseMatching(boolean looseMatching) {
+ this.looseMatching = looseMatching;
+ }
+
+ public void setSearchPattern(String text) {
+ searchCriteria = text;
+ }
+
+ public String getSearchPattern() {
+ return searchCriteria;
+ }
+
+ public int getMaxMatchesCount() {
+ return maxMatches;
+ }
+
+ public boolean isResultIsContextMatch() {
+ return resultIsContextMatch;
+ }
+
+ public void setResultIsContextMatch(boolean resultIsContextMatch) {
+ this.resultIsContextMatch = resultIsContextMatch;
+ }
+
+ public SearchScope getScope() {
+ return scope;
+ }
+
+ public void setScope(SearchScope scope) {
+ this.scope = scope;
+ }
+
+ public SearchScope getDownUpMatchScope() {
+ return downUpMatchScope;
+ }
+
+ public void setDownUpMatchScope(final SearchScope downUpMatchScope) {
+ this.downUpMatchScope = downUpMatchScope;
+ }
+
+ public void writeExternal(Element element) {
+ element.setAttribute(TEXT_ATTRIBUTE_NAME,getSearchPattern());
+ element.setAttribute(RECURSIVE_ATTRIBUTE_NAME,String.valueOf(recursiveSearch));
+ if (distinct) element.setAttribute(DISTINCT_ATTRIBUTE_NAME,String.valueOf(distinct));
+ element.setAttribute(CASESENSITIVE_ATTRIBUTE_NAME,String.valueOf(caseSensitiveMatch));
+
+ //@TODO serialize scope!
+
+ //if (myFileType != StdFileTypes.JAVA) {
+ element.setAttribute(FILE_TYPE_ATTR_NAME, myFileType.getName());
+ //}
+
+ if (myDialect != null) {
+ element.setAttribute(DIALECT_ATTR_NAME, myDialect.getID());
+ }
+
+ if (variableConstraints!=null) {
+ for (final MatchVariableConstraint matchVariableConstraint : variableConstraints.values()) {
+ if (matchVariableConstraint.isArtificial()) continue;
+ final Element infoElement = new Element(CONSTRAINT_TAG_NAME);
+ element.addContent(infoElement);
+ matchVariableConstraint.writeExternal(infoElement);
+ }
+ }
+ }
+
+ public void readExternal(Element element) {
+ setSearchPattern(element.getAttribute(TEXT_ATTRIBUTE_NAME).getValue());
+
+ Attribute attr = element.getAttribute(RECURSIVE_ATTRIBUTE_NAME);
+ if (attr!=null) {
+ try {
+ recursiveSearch = attr.getBooleanValue();
+ } catch(DataConversionException ignored) {}
+ }
+
+ attr = element.getAttribute(DISTINCT_ATTRIBUTE_NAME);
+ if (attr!=null) {
+ try {
+ distinct = attr.getBooleanValue();
+ } catch(DataConversionException ignored) {}
+ }
+
+ attr = element.getAttribute(CASESENSITIVE_ATTRIBUTE_NAME);
+ if (attr!=null) {
+ try {
+ caseSensitiveMatch = attr.getBooleanValue();
+ } catch(DataConversionException ignored) {}
+ }
+
+ attr = element.getAttribute(FILE_TYPE_ATTR_NAME);
+ if (attr!=null) {
+ String value = attr.getValue();
+ myFileType = getFileTypeByName(value);
+ }
+
+ attr = element.getAttribute(DIALECT_ATTR_NAME);
+ if (attr != null) {
+ myDialect = Language.findLanguageByID(attr.getValue());
+ }
+
+ // @TODO deserialize scope
+
+ List<Element> elements = element.getChildren(CONSTRAINT_TAG_NAME);
+ if (elements!=null && !elements.isEmpty()) {
+ for (final Element element1 : elements) {
+ final MatchVariableConstraint constraint = new MatchVariableConstraint();
+ constraint.readExternal(element1);
+ addVariableConstraint(constraint);
+ }
+ }
+ }
+
+ private static FileType getFileTypeByName(String value) {
+ if (value != null) {
+ for (FileType type : StructuralSearchUtil.getSuitableFileTypes()) {
+ if (value.equals(type.getName())) {
+ return type;
+ }
+ }
+ }
+
+ return StructuralSearchUtil.getDefaultFileType();
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof MatchOptions)) return false;
+
+ final MatchOptions matchOptions = (MatchOptions)o;
+
+ if (caseSensitiveMatch != matchOptions.caseSensitiveMatch) return false;
+ if (distinct != matchOptions.distinct) return false;
+ //if (enableAutoIdentifySearchTarget != matchOptions.enableAutoIdentifySearchTarget) return false;
+ if (looseMatching != matchOptions.looseMatching) return false;
+ if (recursiveSearch != matchOptions.recursiveSearch) return false;
+ // @TODO support scope
+
+ if (searchCriteria != null ? !searchCriteria.equals(matchOptions.searchCriteria) : matchOptions.searchCriteria != null) return false;
+ if (variableConstraints != null ? !variableConstraints.equals(matchOptions.variableConstraints) : matchOptions.variableConstraints !=
+ null) {
+ return false;
+ }
+ if (myFileType != matchOptions.myFileType) {
+ return false;
+ }
+
+ if (myDialect != null ? !myDialect.equals(matchOptions.myDialect) : matchOptions.myDialect != null) {
+ return false;
+ }
+
+ if (myPatternContext != null ? !myPatternContext.equals(matchOptions.myPatternContext) : matchOptions.myPatternContext != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (looseMatching ? 1 : 0);
+ result = 29 * result + (distinct ? 1 : 0);
+ result = 29 * result + (recursiveSearch ? 1 : 0);
+ result = 29 * result + (caseSensitiveMatch ? 1 : 0);
+ // @TODO support scope
+ result = 29 * result + (searchCriteria != null ? searchCriteria.hashCode() : 0);
+ result = 29 * result + (variableConstraints != null ? variableConstraints.hashCode() : 0);
+ if (myFileType != null) result = 29 * result + myFileType.hashCode();
+ if (myDialect != null) result = 29 * result + myDialect.hashCode();
+ return result;
+ }
+
+ public void setFileType(FileType fileType) {
+ myFileType = fileType;
+ }
+
+ public FileType getFileType() {
+ return myFileType;
+ }
+
+ public Language getDialect() {
+ return myDialect;
+ }
+
+ public void setDialect(Language dialect) {
+ myDialect = dialect;
+ }
+
+ public String getPatternContext() {
+ return myPatternContext;
+ }
+
+ public void setPatternContext(String patternContext) {
+ myPatternContext = patternContext;
+ }
+
+ public MatchOptions clone() {
+ try {
+ return (MatchOptions) super.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResult.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResult.java
new file mode 100644
index 000000000000..c5196e67178d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResult.java
@@ -0,0 +1,29 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.List;
+
+/**
+ * Class describing the match result
+ */
+public abstract class MatchResult {
+ @NonNls public static final String LINE_MATCH = "line";
+ @NonNls public static final String MULTI_LINE_MATCH = "context";
+
+ public abstract String getMatchImage();
+
+ public abstract SmartPsiPointer getMatchRef();
+ public abstract PsiElement getMatch();
+ public abstract int getStart();
+ public abstract int getEnd();
+
+ public abstract String getName();
+
+ public abstract List<MatchResult> getAllSons();
+ public abstract boolean hasSons();
+ public abstract boolean isScopeMatch();
+ public abstract boolean isMultipleMatch();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResultSink.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResultSink.java
new file mode 100644
index 000000000000..8a4fdf968a8c
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchResultSink.java
@@ -0,0 +1,35 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.psi.PsiFile;
+import com.intellij.structuralsearch.MatchingProcess;
+import com.intellij.openapi.progress.ProgressIndicator;
+
+/**
+ * Interface for consumers of match results
+ */
+public interface MatchResultSink {
+ /**
+ * Notifies sink about new match
+ * @param result
+ */
+ void newMatch(MatchResult result);
+
+ /**
+ * Notifies sink about starting the matching for given element
+ * @param element the current file
+ */
+ void processFile(PsiFile element);
+
+ /**
+ * Sets the reference to the matching process
+ * @param matchingProcess the matching process reference
+ */
+ void setMatchingProcess(MatchingProcess matchingProcess);
+
+ /**
+ * Notifies sink about end of matching.
+ */
+ void matchingFinished();
+
+ ProgressIndicator getProgressIndicator();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchVariableConstraint.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchVariableConstraint.java
new file mode 100644
index 000000000000..db2aaa901c54
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchVariableConstraint.java
@@ -0,0 +1,558 @@
+package com.intellij.structuralsearch;
+
+import org.jdom.Element;
+import org.jdom.Attribute;
+import org.jdom.DataConversionException;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Mar 19, 2004
+ * Time: 5:36:32 PM
+ */
+public class MatchVariableConstraint extends NamedScriptableDefinition {
+ private String regExp = "";
+ private boolean invertRegExp;
+ private boolean withinHierarchy;
+ private boolean strictlyWithinHierarchy;
+ private boolean wholeWordsOnly;
+ private int minCount = 1;
+ private int maxCount = 1;
+ private boolean readAccess;
+ private boolean invertReadAccess;
+ private boolean writeAccess;
+ private boolean invertWriteAccess;
+ private boolean greedy = true;
+ private boolean reference;
+ private boolean invertReference;
+ private String nameOfReferenceVar = "";
+ private boolean partOfSearchResults;
+ private String nameOfExprType = "";
+ private boolean invertExprType;
+ private boolean exprTypeWithinHierarchy;
+
+ private String nameOfFormalArgType = "";
+ private boolean invertFormalType;
+ private boolean formalArgTypeWithinHierarchy;
+
+ private String withinConstraint = "";
+ private String containsConstraint = "";
+ private boolean invertContainsConstraint;
+ private boolean invertWithinConstraint;
+ private final boolean artificial;
+
+ @NonNls private static final String NAME_OF_REFEENCE_VAR = "nameOfReferenceVar";
+ @NonNls private static final String NAME_OF_EXPRTYPE = "nameOfExprType";
+ @NonNls private static final String NAME_OF_FORMALTYPE = "nameOfFormalType";
+ @NonNls private static final String REGEXP = "regexp";
+ @NonNls private static final String EXPRTYPE_WITHIN_HIERARCHY = "exprTypeWithinHierarchy";
+ @NonNls private static final String FORMALTYPE_WITHIN_HIERARCHY = "formalTypeWithinHierarchy";
+
+ @NonNls private static final String WITHIN_HIERARCHY = "withinHierarchy";
+ @NonNls private static final String MAX_OCCURS = "maxCount";
+ @NonNls private static final String MIN_OCCURS = "minCount";
+
+ @NonNls private static final String NEGATE_NAME_CONDITION = "negateName";
+ @NonNls private static final String NEGATE_EXPRTYPE_CONDITION = "negateExprType";
+ @NonNls private static final String NEGATE_FORMALTYPE_CONDITION = "negateFormalType";
+ @NonNls private static final String NEGATE_READ_CONDITION = "negateRead";
+ @NonNls private static final String NEGATE_WRITE_CONDITION = "negateWrite";
+ @NonNls private static final String NEGATE_CONTAINS_CONDITION = "negateContains";
+ @NonNls private static final String NEGATE_WITHIN_CONDITION = "negateWithin";
+ @NonNls private static final String WITHIN_CONDITION = "within";
+ @NonNls private static final String CONTAINS_CONDITION = "contains";
+ @NonNls private static final String READ = "readAccess";
+ @NonNls private static final String WRITE = "writeAccess";
+ @NonNls private static final String TARGET = "target";
+
+ @NonNls private static final String WHOLE_WORDS_ONLY = "wholeWordsOnly";
+ @NonNls private static final String TRUE = Boolean.TRUE.toString();
+
+ public MatchVariableConstraint() { this(false); }
+ public MatchVariableConstraint(boolean _artificial) { artificial = _artificial; }
+
+ public boolean isGreedy() {
+ return greedy;
+ }
+
+ public void setGreedy(boolean greedy) {
+ this.greedy = greedy;
+ }
+
+ public String getRegExp() {
+ return regExp;
+ }
+
+ public void setRegExp(String regExp) {
+ this.regExp = regExp;
+ }
+
+ public boolean isInvertRegExp() {
+ return invertRegExp;
+ }
+
+ public void setInvertRegExp(boolean invertRegExp) {
+ this.invertRegExp = invertRegExp;
+ }
+
+ public boolean isWithinHierarchy() {
+ return withinHierarchy;
+ }
+
+ public void setWithinHierarchy(boolean withinHierarchy) {
+ this.withinHierarchy = withinHierarchy;
+ }
+
+ public int getMinCount() {
+ return minCount;
+ }
+
+ public void setMinCount(int minCount) {
+ this.minCount = minCount;
+ }
+
+ public int getMaxCount() {
+ return maxCount;
+ }
+
+ public void setMaxCount(int maxCount) {
+ this.maxCount = maxCount;
+ }
+
+ public boolean isReadAccess() {
+ return readAccess;
+ }
+
+ public void setReadAccess(boolean readAccess) {
+ this.readAccess = readAccess;
+ }
+
+ public boolean isInvertReadAccess() {
+ return invertReadAccess;
+ }
+
+ public void setInvertReadAccess(boolean invertReadAccess) {
+ this.invertReadAccess = invertReadAccess;
+ }
+
+ public boolean isWriteAccess() {
+ return writeAccess;
+ }
+
+ public void setWriteAccess(boolean writeAccess) {
+ this.writeAccess = writeAccess;
+ }
+
+ public boolean isInvertWriteAccess() {
+ return invertWriteAccess;
+ }
+
+ public void setInvertWriteAccess(boolean invertWriteAccess) {
+ this.invertWriteAccess = invertWriteAccess;
+ }
+
+ public boolean isPartOfSearchResults() {
+ return partOfSearchResults;
+ }
+
+ public void setPartOfSearchResults(boolean partOfSearchResults) {
+ this.partOfSearchResults = partOfSearchResults;
+ }
+
+ public boolean isReference() {
+ return reference;
+ }
+
+ public void setReference(boolean reference) {
+ this.reference = reference;
+ }
+
+ public boolean isInvertReference() {
+ return invertReference;
+ }
+
+ public void setInvertReference(boolean invertReference) {
+ this.invertReference = invertReference;
+ }
+
+ public String getNameOfReferenceVar() {
+ return nameOfReferenceVar;
+ }
+
+ public void setNameOfReferenceVar(String nameOfReferenceVar) {
+ this.nameOfReferenceVar = nameOfReferenceVar;
+ }
+
+ public boolean isStrictlyWithinHierarchy() {
+ return strictlyWithinHierarchy;
+ }
+
+ public void setStrictlyWithinHierarchy(boolean strictlyWithinHierarchy) {
+ this.strictlyWithinHierarchy = strictlyWithinHierarchy;
+ }
+
+ public String getNameOfExprType() {
+ return nameOfExprType;
+ }
+
+ public void setNameOfExprType(String nameOfExprType) {
+ this.nameOfExprType = nameOfExprType;
+ }
+
+ public boolean isInvertExprType() {
+ return invertExprType;
+ }
+
+ public void setInvertExprType(boolean invertExprType) {
+ this.invertExprType = invertExprType;
+ }
+
+ public boolean isExprTypeWithinHierarchy() {
+ return exprTypeWithinHierarchy;
+ }
+
+ public void setExprTypeWithinHierarchy(boolean exprTypeWithinHierarchy) {
+ this.exprTypeWithinHierarchy = exprTypeWithinHierarchy;
+ }
+
+ public boolean isWholeWordsOnly() {
+ return wholeWordsOnly;
+ }
+
+ public void setWholeWordsOnly(boolean wholeWordsOnly) {
+ this.wholeWordsOnly = wholeWordsOnly;
+ }
+
+ public String getNameOfFormalArgType() {
+ return nameOfFormalArgType;
+ }
+
+ public void setNameOfFormalArgType(String nameOfFormalArgType) {
+ this.nameOfFormalArgType = nameOfFormalArgType;
+ }
+
+ public boolean isInvertFormalType() {
+ return invertFormalType;
+ }
+
+ public void setInvertFormalType(boolean invertFormalType) {
+ this.invertFormalType = invertFormalType;
+ }
+
+ public boolean isFormalArgTypeWithinHierarchy() {
+ return formalArgTypeWithinHierarchy;
+ }
+
+ public void setFormalArgTypeWithinHierarchy(boolean formalArgTypeWithinHierarchy) {
+ this.formalArgTypeWithinHierarchy = formalArgTypeWithinHierarchy;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof MatchVariableConstraint)) return false;
+ if (!(super.equals(o))) return false;
+
+ final MatchVariableConstraint matchVariableConstraint = (MatchVariableConstraint)o;
+
+ if (exprTypeWithinHierarchy != matchVariableConstraint.exprTypeWithinHierarchy) return false;
+ if (formalArgTypeWithinHierarchy != matchVariableConstraint.formalArgTypeWithinHierarchy) return false;
+ if (greedy != matchVariableConstraint.greedy) return false;
+ if (invertExprType != matchVariableConstraint.invertExprType) return false;
+ if (invertFormalType != matchVariableConstraint.invertFormalType) return false;
+ if (invertReadAccess != matchVariableConstraint.invertReadAccess) return false;
+ if (invertReference != matchVariableConstraint.invertReference) return false;
+ if (invertRegExp != matchVariableConstraint.invertRegExp) return false;
+ if (invertWriteAccess != matchVariableConstraint.invertWriteAccess) return false;
+ if (maxCount != matchVariableConstraint.maxCount) return false;
+ if (minCount != matchVariableConstraint.minCount) return false;
+ if (partOfSearchResults != matchVariableConstraint.partOfSearchResults) return false;
+ if (readAccess != matchVariableConstraint.readAccess) return false;
+ if (reference != matchVariableConstraint.reference) return false;
+ if (strictlyWithinHierarchy != matchVariableConstraint.strictlyWithinHierarchy) return false;
+ if (wholeWordsOnly != matchVariableConstraint.wholeWordsOnly) return false;
+ if (withinHierarchy != matchVariableConstraint.withinHierarchy) return false;
+ if (writeAccess != matchVariableConstraint.writeAccess) return false;
+ if (!nameOfExprType.equals(matchVariableConstraint.nameOfExprType)) return false;
+ if (!nameOfFormalArgType.equals(matchVariableConstraint.nameOfFormalArgType)) return false;
+ if (!nameOfReferenceVar.equals(matchVariableConstraint.nameOfReferenceVar)) return false;
+ if (!regExp.equals(matchVariableConstraint.regExp)) return false;
+ if (!withinConstraint.equals(matchVariableConstraint.withinConstraint)) return false;
+ if (!containsConstraint.equals(matchVariableConstraint.containsConstraint)) return false;
+ if (invertWithinConstraint != matchVariableConstraint.invertWithinConstraint) return false;
+ if (invertContainsConstraint != matchVariableConstraint.invertContainsConstraint) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = super.hashCode();
+ result = 29 * result + regExp.hashCode();
+ result = 29 * result + (invertRegExp ? 1 : 0);
+ result = 29 * result + (withinHierarchy ? 1 : 0);
+ result = 29 * result + (strictlyWithinHierarchy ? 1 : 0);
+ result = 29 * result + (wholeWordsOnly ? 1 : 0);
+ result = 29 * result + minCount;
+ result = 29 * result + maxCount;
+ result = 29 * result + (readAccess ? 1 : 0);
+ result = 29 * result + (invertReadAccess ? 1 : 0);
+ result = 29 * result + (writeAccess ? 1 : 0);
+ result = 29 * result + (invertWriteAccess ? 1 : 0);
+ result = 29 * result + (greedy ? 1 : 0);
+ result = 29 * result + (reference ? 1 : 0);
+ result = 29 * result + (invertReference ? 1 : 0);
+ result = 29 * result + nameOfReferenceVar.hashCode();
+ result = 29 * result + (partOfSearchResults ? 1 : 0);
+ result = 29 * result + nameOfExprType.hashCode();
+ result = 29 * result + (invertExprType ? 1 : 0);
+ result = 29 * result + (exprTypeWithinHierarchy ? 1 : 0);
+ result = 29 * result + nameOfFormalArgType.hashCode();
+ result = 29 * result + (invertFormalType ? 1 : 0);
+ result = 29 * result + (formalArgTypeWithinHierarchy ? 1 : 0);
+ result = 29 * result + withinConstraint.hashCode();
+ result = 29 * result + containsConstraint.hashCode();
+
+ if (invertContainsConstraint) result = 29 * result + 1;
+ if (invertWithinConstraint) result = 29 * result + 1;
+ return result;
+ }
+
+ public void readExternal(Element element) {
+ super.readExternal(element);
+ Attribute attribute;
+
+ attribute = element.getAttribute(REGEXP);
+ if (attribute != null) {
+ regExp = attribute.getValue();
+ }
+
+ attribute = element.getAttribute(NAME_OF_EXPRTYPE);
+ if (attribute != null) {
+ nameOfExprType = attribute.getValue();
+ }
+
+ attribute = element.getAttribute(NAME_OF_FORMALTYPE);
+ if (attribute != null) {
+ nameOfFormalArgType = attribute.getValue();
+ }
+
+ attribute = element.getAttribute(NAME_OF_REFEENCE_VAR);
+ if (attribute != null) {
+ nameOfReferenceVar = attribute.getValue();
+ }
+
+ attribute = element.getAttribute(WITHIN_HIERARCHY);
+ if (attribute != null) {
+ try {
+ withinHierarchy = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(EXPRTYPE_WITHIN_HIERARCHY);
+ if (attribute != null) {
+ try {
+ exprTypeWithinHierarchy = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(FORMALTYPE_WITHIN_HIERARCHY);
+ if (attribute != null) {
+ try {
+ formalArgTypeWithinHierarchy = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_NAME_CONDITION);
+ if (attribute != null) {
+ try {
+ invertRegExp = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_EXPRTYPE_CONDITION);
+ if (attribute != null) {
+ try {
+ invertExprType = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_FORMALTYPE_CONDITION);
+ if (attribute != null) {
+ try {
+ invertFormalType = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_READ_CONDITION);
+ if (attribute != null) {
+ try {
+ invertReadAccess = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_WRITE_CONDITION);
+ if (attribute != null) {
+ try {
+ invertWriteAccess = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(READ);
+ if (attribute != null) {
+ try {
+ readAccess = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(WRITE);
+ if (attribute != null) {
+ try {
+ writeAccess = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(TARGET);
+ if (attribute != null) {
+ try {
+ partOfSearchResults = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(MIN_OCCURS);
+ if (attribute != null) {
+ try {
+ minCount = attribute.getIntValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(MAX_OCCURS);
+ if (attribute != null) {
+ try {
+ maxCount = attribute.getIntValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(WHOLE_WORDS_ONLY);
+ if (attribute != null) {
+ try {
+ wholeWordsOnly = attribute.getBooleanValue();
+ }
+ catch (DataConversionException ex) {
+ }
+ }
+
+ attribute = element.getAttribute(NEGATE_WITHIN_CONDITION);
+ if (attribute != null) {
+ try {
+ invertWithinConstraint = attribute.getBooleanValue();
+ } catch (DataConversionException ex) {}
+ }
+
+ attribute = element.getAttribute(NEGATE_CONTAINS_CONDITION);
+ if (attribute != null) {
+ try {
+ invertContainsConstraint = attribute.getBooleanValue();
+ } catch (DataConversionException ex) {}
+ }
+
+ attribute = element.getAttribute(CONTAINS_CONDITION);
+ if(attribute != null) containsConstraint = attribute.getValue();
+
+ attribute = element.getAttribute(WITHIN_CONDITION);
+ if(attribute != null) withinConstraint = attribute.getValue();
+ }
+
+ public void writeExternal(Element element) {
+ super.writeExternal(element);
+
+ if (regExp.length() > 0) element.setAttribute(REGEXP,regExp);
+ if (nameOfExprType.length() > 0) element.setAttribute(NAME_OF_EXPRTYPE,nameOfExprType);
+ if (nameOfReferenceVar.length() > 0) element.setAttribute(NAME_OF_REFEENCE_VAR,nameOfReferenceVar);
+ if (nameOfFormalArgType.length() > 0) element.setAttribute(NAME_OF_FORMALTYPE,nameOfFormalArgType);
+
+
+ if (withinHierarchy) element.setAttribute(WITHIN_HIERARCHY,TRUE);
+ if (exprTypeWithinHierarchy) element.setAttribute(EXPRTYPE_WITHIN_HIERARCHY,TRUE);
+ if (formalArgTypeWithinHierarchy) element.setAttribute(FORMALTYPE_WITHIN_HIERARCHY,TRUE);
+
+ if (minCount!=1) element.setAttribute(MIN_OCCURS,String.valueOf(minCount));
+ if (maxCount!=1) element.setAttribute(MAX_OCCURS,String.valueOf(maxCount));
+ if (partOfSearchResults) element.setAttribute(TARGET,TRUE);
+ if (readAccess) element.setAttribute(READ,TRUE);
+ if (writeAccess) element.setAttribute(WRITE,TRUE);
+
+ if (invertRegExp) element.setAttribute(NEGATE_NAME_CONDITION,TRUE);
+ if (invertExprType) element.setAttribute(NEGATE_EXPRTYPE_CONDITION,TRUE);
+ if (invertFormalType) element.setAttribute(NEGATE_FORMALTYPE_CONDITION,TRUE);
+ if (invertReadAccess) element.setAttribute(NEGATE_READ_CONDITION,TRUE);
+ if (invertWriteAccess) element.setAttribute(NEGATE_WRITE_CONDITION,TRUE);
+
+ if (wholeWordsOnly) element.setAttribute(WHOLE_WORDS_ONLY,TRUE);
+ if (invertContainsConstraint) element.setAttribute(NEGATE_CONTAINS_CONDITION,TRUE);
+ if (invertWithinConstraint) element.setAttribute(NEGATE_WITHIN_CONDITION,TRUE);
+ element.setAttribute(WITHIN_CONDITION, withinConstraint);
+ element.setAttribute(CONTAINS_CONDITION, containsConstraint);
+ }
+
+ public String getWithinConstraint() {
+ return withinConstraint;
+ }
+
+ public void setWithinConstraint(final String withinConstraint) {
+ this.withinConstraint = withinConstraint;
+ }
+
+ public String getContainsConstraint() {
+ return containsConstraint;
+ }
+
+ public void setContainsConstraint(final String containsConstraint) {
+ this.containsConstraint = containsConstraint;
+ }
+
+ public boolean isInvertContainsConstraint() {
+ return invertContainsConstraint;
+ }
+
+ public void setInvertContainsConstraint(final boolean invertContainsConstraint) {
+ this.invertContainsConstraint = invertContainsConstraint;
+ }
+
+ public boolean isInvertWithinConstraint() {
+ return invertWithinConstraint;
+ }
+
+ public void setInvertWithinConstraint(final boolean invertWithinConstraint) {
+ this.invertWithinConstraint = invertWithinConstraint;
+ }
+
+ public boolean isArtificial() {
+ return artificial;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/Matcher.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/Matcher.java
new file mode 100644
index 000000000000..594686e14d49
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/Matcher.java
@@ -0,0 +1,84 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * This class makes program structure tree matching:
+ */
+public class Matcher extends MatcherImpl {
+
+ public Matcher(Project project) {
+ super(project);
+ }
+
+ public Matcher(final Project project, final MatchOptions matchOptions) {
+ super(project, matchOptions);
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ public void findMatches(MatchResultSink sink,MatchOptions options) throws
+ MalformedPatternException, UnsupportedPatternException
+ {
+ super.findMatches(sink,options);
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @param source string for search
+ * @param pattern to be searched
+ * @return list of matches found
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ public List<MatchResult> testFindMatches(String source,
+ String pattern,
+ MatchOptions options,
+ boolean filePattern,
+ FileType sourceFileType,
+ String sourceExtension,
+ boolean physicalSourceFile)
+ throws MalformedPatternException, UnsupportedPatternException {
+ return super.testFindMatches(source, pattern, options, filePattern, sourceFileType, sourceExtension, physicalSourceFile);
+ }
+
+ public List<MatchResult> testFindMatches(String source, String pattern, MatchOptions options, boolean filePattern)
+ throws MalformedPatternException, UnsupportedPatternException {
+ return super.testFindMatches(source, pattern, options, filePattern);
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @param sink
+ * @param options
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ public void testFindMatches(MatchResultSink sink,MatchOptions options)
+ throws MalformedPatternException, UnsupportedPatternException {
+
+ super.testFindMatches(sink,options);
+ }
+
+ /**
+ * Tests if given element is matched by given pattern starting from target variable. If matching succeeds
+ * then not null match result is returned.
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ @Nullable
+ public MatchResult isMatchedByDownUp(PsiElement element,MatchOptions options) throws
+ MalformedPatternException, UnsupportedPatternException
+ {
+ return super.isMatchedByDownUp(element, options);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchingProcess.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchingProcess.java
new file mode 100644
index 000000000000..6ecb42d800c3
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/MatchingProcess.java
@@ -0,0 +1,13 @@
+package com.intellij.structuralsearch;
+
+/**
+ * Interface of running matching process
+ */
+public interface MatchingProcess {
+ void stop();
+ void pause();
+ void resume();
+
+ boolean isSuspended();
+ boolean isEnded();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/NamedScriptableDefinition.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/NamedScriptableDefinition.java
new file mode 100644
index 000000000000..8c954ab5a0ef
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/NamedScriptableDefinition.java
@@ -0,0 +1,81 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import org.jdom.Element;
+import org.jdom.Attribute;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: 11.06.2009
+ * Time: 12:55:39
+ */
+public class NamedScriptableDefinition implements JDOMExternalizable, Cloneable {
+ @NonNls private static final String NAME = "name";
+ @NonNls private static final String SCRIPT = "script";
+ private String name;
+ private String scriptCodeConstraint = "";
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getScriptCodeConstraint() {
+ return scriptCodeConstraint;
+ }
+
+ public void setScriptCodeConstraint(String scriptCodeConstraint) {
+ this.scriptCodeConstraint = scriptCodeConstraint;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch(CloneNotSupportedException ex) {
+ return null;
+ }
+ }
+
+ public void readExternal(Element element) {
+ Attribute attribute = element.getAttribute(NAME);
+ if (attribute != null) {
+ name = attribute.getValue();
+ }
+
+ String s = element.getAttributeValue(SCRIPT);
+ if (s != null) {
+ setScriptCodeConstraint(s);
+ }
+ }
+
+ public void writeExternal(Element element) {
+ element.setAttribute(NAME,name);
+ if (scriptCodeConstraint.length() > 0) element.setAttribute(SCRIPT,scriptCodeConstraint);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof NamedScriptableDefinition)) return false;
+
+ NamedScriptableDefinition that = (NamedScriptableDefinition)o;
+
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+ if (scriptCodeConstraint != null ? !scriptCodeConstraint.equals(that.scriptCodeConstraint) : that.scriptCodeConstraint != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (scriptCodeConstraint != null ? scriptCodeConstraint.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/PredefinedConfigurationUtil.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/PredefinedConfigurationUtil.java
new file mode 100644
index 000000000000..6e14ce437025
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/PredefinedConfigurationUtil.java
@@ -0,0 +1,34 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchConfiguration;
+import org.jetbrains.annotations.NonNls;
+
+public class PredefinedConfigurationUtil {
+
+ public static Configuration createSearchTemplateInfo(String name, @NonNls String criteria, String category) {
+ return createSearchTemplateInfo(name, criteria, category, StdFileTypes.JAVA);
+ }
+
+ public static Configuration createSearchTemplateInfo(String name, @NonNls String criteria, String category, FileType fileType) {
+ final SearchConfiguration config = new SearchConfiguration();
+ config.setPredefined(true);
+ config.setName(name);
+ config.setCategory(category);
+ config.getMatchOptions().setSearchPattern(criteria);
+ config.getMatchOptions().setFileType(fileType);
+ MatcherImplUtil.transform( config.getMatchOptions() );
+
+ return config;
+ }
+
+ public static Configuration createSearchTemplateInfoSimple(String name, @NonNls String criteria, String category) {
+ final Configuration info = createSearchTemplateInfo(name,criteria,category);
+ info.getMatchOptions().setRecursiveSearch(false);
+
+ return info;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/ReplacementVariableDefinition.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/ReplacementVariableDefinition.java
new file mode 100644
index 000000000000..1010db48c1f8
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/ReplacementVariableDefinition.java
@@ -0,0 +1,14 @@
+package com.intellij.structuralsearch;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Mar 19, 2004
+ * Time: 5:36:32 PM
+ */
+public class ReplacementVariableDefinition extends NamedScriptableDefinition {
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ReplacementVariableDefinition)) return false;
+ return super.equals(o);
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/SSRBundle.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/SSRBundle.java
new file mode 100644
index 000000000000..8ef278154b24
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/SSRBundle.java
@@ -0,0 +1,32 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.CommonBundle;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+public class SSRBundle {
+
+ public static String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, @NotNull Object... params) {
+ return CommonBundle.message(getBundle(), key, params);
+ }
+
+ private static Reference<ResourceBundle> ourBundle;
+ @NonNls private static final String BUNDLE = "messages.SSRBundle";
+
+ private SSRBundle() {
+ }
+
+ private static ResourceBundle getBundle() {
+ ResourceBundle bundle = com.intellij.reference.SoftReference.dereference(ourBundle);
+ if (bundle == null) {
+ bundle = ResourceBundle.getBundle(BUNDLE);
+ ourBundle = new SoftReference<ResourceBundle>(bundle);
+ }
+ return bundle;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralReplaceHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralReplaceHandler.java
new file mode 100644
index 000000000000..063f272cf4c4
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralReplaceHandler.java
@@ -0,0 +1,15 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class StructuralReplaceHandler {
+ public abstract void replace(final ReplacementInfo info, ReplaceOptions options);
+
+ public void prepare
+ (ReplacementInfo info) {
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchException.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchException.java
new file mode 100644
index 000000000000..f925285054f0
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchException.java
@@ -0,0 +1,13 @@
+
+package com.intellij.structuralsearch;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class StructuralSearchException extends RuntimeException {
+ public StructuralSearchException() {}
+
+ public StructuralSearchException(String message) {
+ super(message);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java
new file mode 100644
index 000000000000..ff7b379a161f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java
@@ -0,0 +1,281 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.lang.Language;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.ParameterInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementBuilder;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+import com.intellij.structuralsearch.plugin.ui.UIUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.LocalTimeCounter;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class StructuralSearchProfile {
+ public static final ExtensionPointName<StructuralSearchProfile> EP_NAME =
+ ExtensionPointName.create("com.intellij.structuralsearch.profile");
+
+ public abstract void compile(PsiElement[] elements, @NotNull GlobalCompilingVisitor globalVisitor);
+
+ @NotNull
+ public abstract PsiElementVisitor createMatchingVisitor(@NotNull GlobalMatchingVisitor globalVisitor);
+
+ @NotNull
+ public abstract PsiElementVisitor getLexicalNodesFilter(@NotNull LexicalNodesFilter filter);
+
+ @NotNull
+ public abstract CompiledPattern createCompiledPattern();
+
+ public static String getTypeName(FileType fileType) {
+ return fileType.getName().toLowerCase();
+ }
+
+ public abstract boolean canProcess(@NotNull FileType fileType);
+
+ public abstract boolean isMyLanguage(@NotNull Language language);
+
+ public boolean isMyFile(PsiFile file, @NotNull Language language, Language... patternLanguages) {
+ if (isMyLanguage(language) && ArrayUtil.find(patternLanguages, language) >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @NotNull
+ public PsiElement[] createPatternTree(@NotNull String text,
+ @NotNull PatternTreeContext context,
+ @NotNull FileType fileType,
+ @Nullable Language language,
+ @Nullable String contextName,
+ @Nullable String extension,
+ @NotNull Project project,
+ boolean physical) {
+ final String ext = extension != null ? extension : fileType.getDefaultExtension();
+ final String name = "__dummy." + ext;
+ final PsiFileFactory factory = PsiFileFactory.getInstance(project);
+
+ final PsiFile file = language == null
+ ? factory.createFileFromText(name, fileType, text, LocalTimeCounter.currentTime(), physical, true)
+ : factory.createFileFromText(name, language, text, physical, true);
+
+ return file != null ? file.getChildren() : PsiElement.EMPTY_ARRAY;
+ }
+
+ @NotNull
+ public PsiElement[] createPatternTree(@NotNull String text,
+ @NotNull PatternTreeContext context,
+ @NotNull FileType fileType,
+ @NotNull Project project,
+ boolean physical) {
+ return createPatternTree(text, context, fileType, null, null, null, project, physical);
+ }
+
+ @NotNull
+ public Editor createEditor(@NotNull SearchContext searchContext,
+ @NotNull FileType fileType,
+ Language dialect,
+ String text,
+ boolean useLastConfiguration) {
+ PsiFile codeFragment = createCodeFragment(searchContext.getProject(), text, null);
+ if (codeFragment == null) {
+ codeFragment = createFileFragment(searchContext, fileType, dialect, text);
+ }
+
+ if (codeFragment != null) {
+ final Document doc = PsiDocumentManager.getInstance(searchContext.getProject()).getDocument(codeFragment);
+ assert doc != null : "code fragment element should be physical";
+ DaemonCodeAnalyzer.getInstance(searchContext.getProject()).setHighlightingEnabled(codeFragment, false);
+ return UIUtil.createEditor(doc, searchContext.getProject(), true, true, getTemplateContextType());
+ }
+
+ final EditorFactory factory = EditorFactory.getInstance();
+ final Document document = factory.createDocument(text);
+ final EditorEx editor = (EditorEx)factory.createEditor(document, searchContext.getProject());
+ editor.getSettings().setFoldingOutlineShown(false);
+ return editor;
+ }
+
+ private static PsiFile createFileFragment(SearchContext searchContext, FileType fileType, Language dialect, String text) {
+ final String name = "__dummy." + fileType.getDefaultExtension();
+ final PsiFileFactory factory = PsiFileFactory.getInstance(searchContext.getProject());
+
+ return dialect == null ?
+ factory.createFileFromText(name, fileType, text, LocalTimeCounter.currentTime(), true, true) :
+ factory.createFileFromText(name, dialect, text, true, true);
+ }
+
+ @Nullable
+ public PsiCodeFragment createCodeFragment(Project project, String text, @Nullable PsiElement context) {
+ return null;
+ }
+
+ @Nullable
+ public Class<? extends TemplateContextType> getTemplateContextTypeClass() {
+ return null;
+ }
+
+ public final TemplateContextType getTemplateContextType() {
+ final Class<? extends TemplateContextType> clazz = getTemplateContextTypeClass();
+ return clazz != null ? ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), clazz) : null;
+ }
+
+ @Nullable
+ public FileType detectFileType(@NotNull PsiElement context) {
+ return null;
+ }
+
+ @Nullable
+ public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
+ return null;
+ }
+
+ public void checkSearchPattern(Project project, MatchOptions options) {
+ }
+
+ public void checkReplacementPattern(Project project, ReplaceOptions options) {
+ String fileType = getTypeName(options.getMatchOptions().getFileType());
+ throw new UnsupportedPatternException(SSRBundle.message("replacement.not.supported.for.filetype", fileType));
+ }
+
+ @NotNull
+ public Language getLanguage(PsiElement element) {
+ return element.getLanguage();
+ }
+
+ // only for nodes not filtered by lexical-nodes filter; they can be by default
+ public boolean canBeVarDelimeter(@NotNull PsiElement element) {
+ return false;
+ }
+
+ public String getText(PsiElement match, int start, int end) {
+ final String matchText = match.getText();
+ if (start==0 && end==-1) return matchText;
+ return matchText.substring(start, end == -1 ? matchText.length() : end);
+ }
+
+ public Class getElementContextByPsi(PsiElement element) {
+ return element.getClass();
+ }
+
+ public String getTypedVarString(PsiElement element) {
+ if (element instanceof PsiNamedElement) {
+ return ((PsiNamedElement)element).getName();
+ }
+ return element.getText();
+ }
+
+ public String getMeaningfulText(PsiElement element) {
+ return getTypedVarString(element);
+ }
+
+ public PsiElement updateCurrentNode(PsiElement node) {
+ return node;
+ }
+
+ public PsiElement extendMatchedByDownUp(PsiElement node) {
+ return node;
+ }
+
+ public PsiElement extendMatchOnePsiFile(PsiElement file) {
+ return file;
+ }
+
+ public LanguageFileType getDefaultFileType(@Nullable LanguageFileType fileType) {
+ return fileType;
+ }
+
+ Configuration[] getPredefinedTemplates() {
+ return Configuration.EMPTY_ARRAY;
+ }
+
+ public void provideAdditionalReplaceOptions(@NotNull PsiElement node, ReplaceOptions options, ReplacementBuilder builder) {}
+
+ public int handleSubstitution(final ParameterInfo info,
+ MatchResult match,
+ StringBuilder result,
+ int offset,
+ HashMap<String, MatchResult> matchMap) {
+ return defaultHandleSubstitution(info, match, result, offset);
+ }
+
+ public static int defaultHandleSubstitution(ParameterInfo info, MatchResult match, StringBuilder result, int offset) {
+ if (info.getName().equals(match.getName())) {
+ String replacementString = match.getMatchImage();
+ boolean forceAddingNewLine = false;
+ if (match.getAllSons().size() > 0 && !match.isScopeMatch()) {
+ // compound matches
+ StringBuilder buf = new StringBuilder();
+
+ for (final MatchResult matchResult : match.getAllSons()) {
+ final PsiElement currentElement = matchResult.getMatch();
+
+ if (buf.length() > 0) {
+ if (info.isParameterContext()) {
+ buf.append(',');
+ } else {
+ buf.append(' ');
+ }
+ }
+
+ buf.append(matchResult.getMatchImage());
+ forceAddingNewLine = currentElement instanceof PsiComment;
+ }
+ replacementString = buf.toString();
+ } else {
+ if (info.isStatementContext()) {
+ forceAddingNewLine = match.getMatch() instanceof PsiComment;
+ }
+ }
+
+ offset = Replacer.insertSubstitution(result, offset, info, replacementString);
+ if (forceAddingNewLine && info.isStatementContext()) {
+ result.insert(info.getStartIndex() + offset + 1, '\n');
+ offset ++;
+ }
+ }
+ return offset;
+ }
+
+ public int processAdditionalOptions(ParameterInfo info, int offset, StringBuilder result, MatchResult r) {
+ return offset;
+ }
+
+ public boolean isIdentifier(PsiElement element) {
+ return false;
+ }
+
+ public Collection<String> getReservedWords() {
+ return Collections.emptySet();
+ }
+
+ public boolean isDocCommentOwner(PsiElement match) {
+ return false;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfileBase.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfileBase.java
new file mode 100644
index 000000000000..9e9496115809
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfileBase.java
@@ -0,0 +1,674 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.dupLocator.PsiElementRole;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptorProvider;
+import com.intellij.dupLocator.equivalence.MultiChildDescriptor;
+import com.intellij.dupLocator.equivalence.SingleChildDescriptor;
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageParserDefinitions;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.structuralsearch.impl.matcher.*;
+import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.*;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.LocalTimeCounter;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class StructuralSearchProfileBase extends StructuralSearchProfile {
+ private static final String DELIMETER_CHARS = ",;.[]{}():";
+ protected static final String PATTERN_PLACEHOLDER = "$$PATTERN_PLACEHOLDER$$";
+ private PsiElementVisitor myLexicalNodesFilter;
+
+ @Override
+ public void compile(PsiElement[] elements, @NotNull final GlobalCompilingVisitor globalVisitor) {
+ final PsiElement topElement = elements[0].getParent();
+ final PsiElement element = elements.length > 1 ? topElement : elements[0];
+
+ element.accept(new MyCompilingVisitor(globalVisitor, topElement));
+
+ element.accept(new PsiRecursiveElementVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+ if (DuplocatorUtil.isIgnoredNode(element)) {
+ return;
+ }
+ CompiledPattern pattern = globalVisitor.getContext().getPattern();
+ MatchingHandler handler = pattern.getHandler(element);
+
+ if (!(handler instanceof SubstitutionHandler) &&
+ !(handler instanceof TopLevelMatchingHandler) &&
+ !(handler instanceof LightTopLevelMatchingHandler)) {
+ pattern.setHandler(element, new SkippingHandler(handler));
+ }
+
+ // todo: simplify logic
+
+ /*
+ place skipping handler under top-level handler, because when we skip top-level node we can get non top-level handler, so
+ depth matching won't be done!;
+ */
+ if (handler instanceof LightTopLevelMatchingHandler) {
+ MatchingHandler delegate = ((LightTopLevelMatchingHandler)handler).getDelegate();
+ if (!(delegate instanceof SubstitutionHandler)) {
+ pattern.setHandler(element, new LightTopLevelMatchingHandler(new SkippingHandler(delegate)));
+ }
+ }
+ }
+ });
+
+
+ final Language baseLanguage = element.getContainingFile().getLanguage();
+
+ // todo: try to optimize it: too heavy strategy!
+ globalVisitor.getContext().getPattern().setStrategy(new MatchingStrategy() {
+ @Override
+ public boolean continueMatching(PsiElement start) {
+ Language language = start.getLanguage();
+
+ PsiFile file = start.getContainingFile();
+ if (file != null) {
+ Language fileLanguage = file.getLanguage();
+ if (fileLanguage.isKindOf(language)) {
+ // dialect
+ language = fileLanguage;
+ }
+ }
+
+ return language == baseLanguage;
+ }
+
+ @Override
+ public boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
+ return DuplocatorUtil.shouldSkip(element, elementToMatchWith);
+ }
+ });
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor createMatchingVisitor(@NotNull GlobalMatchingVisitor globalVisitor) {
+ return new MyMatchingVisitor(globalVisitor);
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor getLexicalNodesFilter(@NotNull final LexicalNodesFilter filter) {
+ if (myLexicalNodesFilter == null) {
+ myLexicalNodesFilter = new PsiElementVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+ if (DuplocatorUtil.isIgnoredNode(element)) {
+ filter.setResult(true);
+ }
+ }
+ };
+ }
+ return myLexicalNodesFilter;
+ }
+
+ public static boolean containsOnlyDelimeters(String s) {
+ for (int i = 0, n = s.length(); i < n; i++) {
+ if (DELIMETER_CHARS.indexOf(s.charAt(i)) < 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @NotNull
+ protected abstract String[] getVarPrefixes();
+
+ @NotNull
+ @Override
+ public CompiledPattern createCompiledPattern() {
+ return new CompiledPattern() {
+
+ @Override
+ protected SubstitutionHandler doCreateSubstitutionHandler(String name, boolean target, int minOccurs, int maxOccurs, boolean greedy) {
+ return new MySubstitutionHandler(name, target, minOccurs, maxOccurs, greedy);
+ }
+
+ @Override
+ public String[] getTypedVarPrefixes() {
+ return getVarPrefixes();
+ }
+
+ @Override
+ public boolean isTypedVar(String str) {
+ for (String prefix : getVarPrefixes()) {
+ if (str.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getTypedVarString(PsiElement element) {
+ final PsiElement initialElement = element;
+ PsiElement child = SkippingHandler.getOnlyNonWhitespaceChild(element);
+
+ while (child != element && child != null && !(child instanceof LeafElement)) {
+ element = child;
+ child = SkippingHandler.getOnlyNonWhitespaceChild(element);
+ }
+ return child instanceof LeafElement ? element.getText() : initialElement.getText();
+ }
+ };
+ }
+
+ @Override
+ public boolean canProcess(@NotNull FileType fileType) {
+ return fileType instanceof LanguageFileType &&
+ isMyLanguage(((LanguageFileType)fileType).getLanguage());
+ }
+
+ @Override
+ public boolean isMyLanguage(@NotNull Language language) {
+ return language.isKindOf(getFileType().getLanguage());
+ }
+
+ @NotNull
+ protected abstract LanguageFileType getFileType();
+
+ @NotNull
+ @Override
+ public PsiElement[] createPatternTree(@NotNull String text,
+ @NotNull PatternTreeContext context,
+ @NotNull FileType fileType,
+ @Nullable Language language,
+ @Nullable String contextName,
+ @Nullable String extension,
+ @NotNull Project project,
+ boolean physical) {
+ if (context == PatternTreeContext.Block) {
+ final String strContext = getContext(text, language, contextName);
+ return strContext != null ?
+ parsePattern(project, strContext, text, fileType, language, extension, physical) :
+ PsiElement.EMPTY_ARRAY;
+ }
+ return super.createPatternTree(text, context, fileType, language, contextName, extension, project, physical);
+ }
+
+ @Override
+ public void checkReplacementPattern(Project project, ReplaceOptions options) {
+ final CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, options.getMatchOptions());
+ if (compiledPattern == null) {
+ return;
+ }
+
+ final NodeIterator it = compiledPattern.getNodes();
+ if (!it.hasNext()) {
+ return;
+ }
+
+ final PsiElement root = it.current().getParent();
+
+ if (!checkOptionalChildren(root) ||
+ !checkErrorElements(root)) {
+ throw new UnsupportedPatternException(": Partial and expression patterns are not supported");
+ }
+ }
+
+ private static boolean checkErrorElements(PsiElement element) {
+ final boolean[] result = {true};
+ final int endOffset = element.getTextRange().getEndOffset();
+
+ element.accept(new PsiRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+
+ if (element instanceof PsiErrorElement && element.getTextRange().getEndOffset() == endOffset) {
+ result[0] = false;
+ }
+ }
+ });
+
+ return result[0];
+ }
+
+ private static boolean checkOptionalChildren(PsiElement root) {
+ final boolean[] result = {true};
+
+ root.accept(new PsiRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+
+ if (element instanceof LeafElement) {
+ return;
+ }
+
+ final EquivalenceDescriptorProvider provider = EquivalenceDescriptorProvider.getInstance(element);
+ if (provider == null) {
+ return;
+ }
+
+ final EquivalenceDescriptor descriptor = provider.buildDescriptor(element);
+ if (descriptor == null) {
+ return;
+ }
+
+ for (SingleChildDescriptor childDescriptor : descriptor.getSingleChildDescriptors()) {
+ if (childDescriptor.getType() == SingleChildDescriptor.MyType.OPTIONALLY_IN_PATTERN &&
+ childDescriptor.getElement() == null) {
+ result[0] = false;
+ }
+ }
+
+ for (MultiChildDescriptor childDescriptor : descriptor.getMultiChildDescriptors()) {
+ if (childDescriptor.getType() == MultiChildDescriptor.MyType.OPTIONALLY_IN_PATTERN) {
+ PsiElement[] elements = childDescriptor.getElements();
+ if (elements == null || elements.length == 0) {
+ result[0] = false;
+ }
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ @Override
+ public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
+ return new DocumentBasedReplaceHandler(context.getProject());
+ }
+
+ @NotNull
+ public String[] getContextNames() {
+ return ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
+ @Nullable
+ protected String getContext(@NotNull String pattern, @Nullable Language language, @Nullable String contextName) {
+ return PATTERN_PLACEHOLDER;
+ }
+
+ private static boolean canBePatternVariable(PsiElement element) {
+ // can be leaf element! (ex. var a = 1 <-> var $a$ = 1)
+ if (element instanceof LeafElement) {
+ return true;
+ }
+
+ while (!(element instanceof LeafElement) && element != null) {
+ element = SkippingHandler.getOnlyNonWhitespaceChild(element);
+ }
+ return element != null;
+ }
+
+ private static boolean isLiteral(PsiElement element) {
+ if (element == null) return false;
+ final ASTNode astNode = element.getNode();
+ if (astNode == null) {
+ return false;
+ }
+ final IElementType elementType = astNode.getElementType();
+ final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage());
+ if (parserDefinition != null) {
+ final TokenSet literals = parserDefinition.getStringLiteralElements();
+ return literals.contains(elementType);
+ }
+ return false;
+ }
+
+ private static boolean canBePatternVariableValue(PsiElement element) {
+ // can be leaf element! (ex. var a = 1 <-> var $a$ = 1)
+ return !containsOnlyDelimeters(element.getText());
+ }
+
+ @Override
+ public boolean canBeVarDelimeter(@NotNull PsiElement element) {
+ final ASTNode node = element.getNode();
+ return node != null && getVariableDelimiters().contains(node.getElementType());
+ }
+
+ protected TokenSet getVariableDelimiters() {
+ return TokenSet.EMPTY;
+ }
+
+ public static PsiElement[] parsePattern(Project project,
+ String context,
+ String pattern,
+ FileType fileType,
+ Language language,
+ String extension,
+ boolean physical) {
+ int offset = context.indexOf(PATTERN_PLACEHOLDER);
+
+ final int patternLength = pattern.length();
+ final String patternInContext = context.replace(PATTERN_PLACEHOLDER, pattern);
+
+ final String ext = extension != null ? extension : fileType.getDefaultExtension();
+ final String name = "__dummy." + ext;
+ final PsiFileFactory factory = PsiFileFactory.getInstance(project);
+
+ final PsiFile file = language == null
+ ? factory.createFileFromText(name, fileType, patternInContext, LocalTimeCounter.currentTime(), physical, true)
+ : factory.createFileFromText(name, language, patternInContext, physical, true);
+ if (file == null) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ final List<PsiElement> result = new ArrayList<PsiElement>();
+
+ PsiElement element = file.findElementAt(offset);
+ if (element == null) {
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ PsiElement topElement = element;
+ element = element.getParent();
+
+ while (element != null) {
+ if (element.getTextRange().getStartOffset() == offset && element.getTextLength() <= patternLength) {
+ topElement = element;
+ }
+ element = element.getParent();
+ }
+
+ if (topElement instanceof PsiFile) {
+ return topElement.getChildren();
+ }
+
+ final int endOffset = offset + patternLength;
+ result.add(topElement);
+ topElement = topElement.getNextSibling();
+
+ while (topElement != null && topElement.getTextRange().getEndOffset() <= endOffset) {
+ result.add(topElement);
+ topElement = topElement.getNextSibling();
+ }
+
+ return result.toArray(new PsiElement[result.size()]);
+ }
+
+ // todo: support expression patterns
+ // todo: support {statement;} = statement; (node has only non-lexical child)
+
+ private static class MyCompilingVisitor extends PsiRecursiveElementVisitor {
+ private final GlobalCompilingVisitor myGlobalVisitor;
+ private final PsiElement myTopElement;
+
+ private Pattern[] mySubstitutionPatterns;
+
+ private MyCompilingVisitor(GlobalCompilingVisitor globalVisitor, PsiElement topElement) {
+ myGlobalVisitor = globalVisitor;
+ myTopElement = topElement;
+ }
+
+ @Override
+ public void visitElement(PsiElement element) {
+ doVisitElement(element);
+
+ if (isLiteral(element)) {
+ visitLiteral(element);
+ }
+ }
+
+ private void doVisitElement(PsiElement element) {
+ CompiledPattern pattern = myGlobalVisitor.getContext().getPattern();
+
+ if (myGlobalVisitor.getCodeBlockLevel() == 0) {
+ initTopLevelElement(element);
+ return;
+ }
+
+ if (canBePatternVariable(element) && pattern.isRealTypedVar(element)) {
+ myGlobalVisitor.handle(element);
+ final MatchingHandler handler = pattern.getHandler(element);
+ handler.setFilter(new NodeFilter() {
+ public boolean accepts(PsiElement other) {
+ return canBePatternVariableValue(other);
+ }
+ });
+
+ super.visitElement(element);
+
+ return;
+ }
+
+ super.visitElement(element);
+
+ if (myGlobalVisitor.getContext().getSearchHelper().doOptimizing() && element instanceof LeafElement) {
+ ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage());
+ if (parserDefinition != null) {
+ String text = element.getText();
+
+ // todo: support variables inside comments
+ boolean flag = true;
+ if (StringUtil.isJavaIdentifier(text) && flag) {
+ myGlobalVisitor.processTokenizedName(text, true, GlobalCompilingVisitor.OccurenceKind.CODE);
+ }
+ }
+ }
+ }
+
+ private void visitLiteral(PsiElement literal) {
+ String value = literal.getText();
+
+ if (value.length() > 2 &&
+ (value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') ||
+ (value.charAt(0) == '\'' && value.charAt(value.length() - 1) == '\'')) {
+
+ if (mySubstitutionPatterns == null) {
+ final String[] prefixes = myGlobalVisitor.getContext().getPattern().getTypedVarPrefixes();
+ mySubstitutionPatterns = createPatterns(prefixes);
+ }
+
+ for (Pattern substitutionPattern : mySubstitutionPatterns) {
+ @Nullable MatchingHandler handler =
+ myGlobalVisitor.processPatternStringWithFragments(value, GlobalCompilingVisitor.OccurenceKind.LITERAL, substitutionPattern);
+
+ if (handler != null) {
+ literal.putUserData(CompiledPattern.HANDLER_KEY, handler);
+ break;
+ }
+ }
+ }
+ }
+
+ private static Pattern[] createPatterns(String[] prefixes) {
+ final Pattern[] patterns = new Pattern[prefixes.length];
+
+ for (int i = 0; i < prefixes.length; i++) {
+ final String s = StructuralSearchUtil.shieldSpecialChars(prefixes[0]);
+ patterns[i] = Pattern.compile("\\b(" + s + "\\w+)\\b");
+ }
+ return patterns;
+ }
+
+ private void initTopLevelElement(PsiElement element) {
+ CompiledPattern pattern = myGlobalVisitor.getContext().getPattern();
+
+ PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(element);
+
+ if (element != newElement && newElement != null) {
+ // way to support partial matching (ex. if ($condition$) )
+ newElement.accept(this);
+ pattern.setHandler(element, new LightTopLevelMatchingHandler(pattern.getHandler(element)));
+ }
+ else {
+ myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() + 1);
+
+ for (PsiElement el = element.getFirstChild(); el != null; el = el.getNextSibling()) {
+ if (GlobalCompilingVisitor.getFilter().accepts(el)) {
+ if (el instanceof PsiWhiteSpace) {
+ myGlobalVisitor.addLexicalNode(el);
+ }
+ }
+ else {
+ el.accept(this);
+
+ MatchingHandler matchingHandler = pattern.getHandler(el);
+ pattern.setHandler(el, element == myTopElement ? new TopLevelMatchingHandler(matchingHandler) :
+ new LightTopLevelMatchingHandler(matchingHandler));
+
+ /*
+ do not assign light-top-level handlers through skipping, because it is incorrect;
+ src: if (...) { st1; st2; }
+ pattern: if (...) {$a$;}
+
+ $a$ will have top-level handler, so matching will be considered as correct, although "st2;" is left!
+ */
+ }
+ }
+
+ myGlobalVisitor.setCodeBlockLevel(myGlobalVisitor.getCodeBlockLevel() - 1);
+ pattern.setHandler(element, new TopLevelMatchingHandler(pattern.getHandler(element)));
+ }
+ }
+ }
+
+ private static class MyMatchingVisitor extends PsiElementVisitor {
+ private final GlobalMatchingVisitor myGlobalVisitor;
+
+ private MyMatchingVisitor(GlobalMatchingVisitor globalVisitor) {
+ myGlobalVisitor = globalVisitor;
+ }
+
+ private boolean shouldIgnoreVarNode(PsiElement element) {
+ MatchingHandler handler = myGlobalVisitor.getMatchContext().getPattern().getHandlerSimple(element);
+ if (handler instanceof DelegatingHandler) {
+ handler = ((DelegatingHandler)handler).getDelegate();
+ }
+ return handler instanceof MySubstitutionHandler && ((MySubstitutionHandler)handler).myExceptedNodes.contains(element);
+ }
+
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+
+ final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element);
+
+ if (descriptorProvider != null) {
+ final EquivalenceDescriptor descriptor1 = descriptorProvider.buildDescriptor(element);
+ final EquivalenceDescriptor descriptor2 = descriptorProvider.buildDescriptor(myGlobalVisitor.getElement());
+
+ if (descriptor1 != null && descriptor2 != null) {
+ final boolean result = DuplocatorUtil
+ .match(descriptor1, descriptor2, myGlobalVisitor, Collections.<PsiElementRole>emptySet(), null);
+ myGlobalVisitor.setResult(result);
+ return;
+ }
+ }
+
+ if (isLiteral(element)) {
+ visitLiteral(element);
+ return;
+ }
+
+ if (canBePatternVariable(element) &&
+ myGlobalVisitor.getMatchContext().getPattern().isRealTypedVar(element) &&
+ !shouldIgnoreVarNode(element)) {
+
+ PsiElement matchedElement = myGlobalVisitor.getElement();
+ PsiElement newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement);
+ while (newElement != matchedElement) {
+ matchedElement = newElement;
+ newElement = SkippingHandler.skipNodeIfNeccessary(matchedElement);
+ }
+
+ myGlobalVisitor.setResult(myGlobalVisitor.handleTypedElement(element, matchedElement));
+ }
+ else if (element instanceof LeafElement) {
+ myGlobalVisitor.setResult(element.getText().equals(myGlobalVisitor.getElement().getText()));
+ }
+ else if (element.getFirstChild() == null && element.getTextLength() == 0) {
+ myGlobalVisitor.setResult(true);
+ }
+ else {
+ PsiElement patternChild = element.getFirstChild();
+ PsiElement matchedChild = myGlobalVisitor.getElement().getFirstChild();
+
+ FilteringNodeIterator patternIterator = new SsrFilteringNodeIterator(patternChild);
+ FilteringNodeIterator matchedIterator = new SsrFilteringNodeIterator(matchedChild);
+
+ boolean matched = myGlobalVisitor.matchSequentially(patternIterator, matchedIterator);
+ myGlobalVisitor.setResult(matched);
+ }
+ }
+
+ public void visitLiteral(PsiElement literal) {
+ final PsiElement l2 = myGlobalVisitor.getElement();
+
+ MatchingHandler handler = (MatchingHandler)literal.getUserData(CompiledPattern.HANDLER_KEY);
+
+ if (handler instanceof SubstitutionHandler) {
+ int offset = 0;
+ int length = l2.getTextLength();
+ final String text = l2.getText();
+
+ if (length > 2 &&
+ (text.charAt(0) == '"' && text.charAt(length - 1) == '"') ||
+ (text.charAt(0) == '\'' && text.charAt(length - 1) == '\'')) {
+ length--;
+ offset++;
+ }
+ myGlobalVisitor.setResult(((SubstitutionHandler)handler).handle(l2, offset, length, myGlobalVisitor.getMatchContext()));
+ }
+ else if (handler != null) {
+ myGlobalVisitor.setResult(handler.match(literal, l2, myGlobalVisitor.getMatchContext()));
+ }
+ else {
+ myGlobalVisitor.setResult(literal.textMatches(l2));
+ }
+ }
+ }
+
+ private static class MySubstitutionHandler extends SubstitutionHandler {
+ final Set<PsiElement> myExceptedNodes;
+
+ public MySubstitutionHandler(String name, boolean target, int minOccurs, int maxOccurs, boolean greedy) {
+ super(name, target, minOccurs, maxOccurs, greedy);
+ myExceptedNodes = new HashSet<PsiElement>();
+ }
+
+ @Override
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ if (doMatchSequentially(nodes, nodes2, context)) {
+ return true;
+ }
+ final PsiElement current = nodes.current();
+ if (current != null) {
+ myExceptedNodes.add(current);
+ }
+ final boolean result = doMatchSequentiallyBySimpleHandler(nodes, nodes2, context);
+ myExceptedNodes.remove(current);
+ return result;
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java
new file mode 100644
index 000000000000..b37c10143636
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchUtil.java
@@ -0,0 +1,169 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.fileTypes.impl.AbstractFileType;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.tokenindex.LanguageTokenizer;
+import com.intellij.tokenindex.Tokenizer;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class StructuralSearchUtil {
+ private static LanguageFileType ourDefaultFileType = null;
+
+ public static boolean ourUseUniversalMatchingAlgorithm = false;
+ private static StructuralSearchProfile[] ourNewStyleProfiles;
+ private static List<Configuration> ourPredefinedConfigurations = null;
+
+ private StructuralSearchUtil() {}
+
+ @Nullable
+ public static StructuralSearchProfile getProfileByPsiElement(@NotNull PsiElement element) {
+ return getProfileByLanguage(element.getLanguage());
+ }
+
+ @Contract("null -> false")
+ public static boolean isIdentifier(PsiElement element) {
+ final StructuralSearchProfile profile = getProfileByPsiElement(element);
+ return profile != null && profile.isIdentifier(element);
+ }
+
+ private static StructuralSearchProfile[] getNewStyleProfiles() {
+ if (ourNewStyleProfiles == null) {
+ final List<StructuralSearchProfile> list = new ArrayList<StructuralSearchProfile>();
+
+ for (StructuralSearchProfile profile : StructuralSearchProfile.EP_NAME.getExtensions()) {
+ if (profile instanceof StructuralSearchProfileBase) {
+ list.add(profile);
+ }
+ }
+ list.add(new XmlStructuralSearchProfile());
+ ourNewStyleProfiles = list.toArray(new StructuralSearchProfile[list.size()]);
+ }
+ return ourNewStyleProfiles;
+ }
+
+ private static StructuralSearchProfile[] getProfiles() {
+ return ourUseUniversalMatchingAlgorithm
+ ? getNewStyleProfiles()
+ : StructuralSearchProfile.EP_NAME.getExtensions();
+ }
+
+ public static FileType getDefaultFileType() {
+ if (ourDefaultFileType == null) {
+ for (StructuralSearchProfile profile : getProfiles()) {
+ ourDefaultFileType = profile.getDefaultFileType(ourDefaultFileType);
+ }
+ if (ourDefaultFileType == null) {
+ ourDefaultFileType = StdFileTypes.XML;
+ }
+ }
+ assert isValidFileType(ourDefaultFileType) : "file type not valid for structural search: " + ourDefaultFileType.getName();
+ return ourDefaultFileType;
+ }
+
+ @Nullable
+ public static StructuralSearchProfile getProfileByLanguage(@NotNull Language language) {
+
+ for (StructuralSearchProfile profile : getProfiles()) {
+ if (profile.isMyLanguage(language)) {
+ return profile;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public static Tokenizer getTokenizerForLanguage(@NotNull Language language) {
+ return LanguageTokenizer.INSTANCE.forLanguage(language);
+ }
+
+ public static boolean isTypedVariable(@NotNull final String name) {
+ return name.charAt(0)=='$' && name.charAt(name.length()-1)=='$';
+ }
+
+ @Nullable
+ public static StructuralSearchProfile getProfileByFileType(FileType fileType) {
+
+ for (StructuralSearchProfile profile : getProfiles()) {
+ if (profile.canProcess(fileType)) {
+ return profile;
+ }
+ }
+
+ return null;
+ }
+
+ @NotNull
+ public static FileType[] getSuitableFileTypes() {
+ Set<FileType> allFileTypes = new HashSet<FileType>();
+ Collections.addAll(allFileTypes, FileTypeManager.getInstance().getRegisteredFileTypes());
+ for (Language language : Language.getRegisteredLanguages()) {
+ FileType fileType = language.getAssociatedFileType();
+ if (fileType != null) {
+ allFileTypes.add(fileType);
+ }
+ }
+
+ List<FileType> result = new ArrayList<FileType>();
+ for (FileType fileType : allFileTypes) {
+ if (isValidFileType(fileType)) {
+ result.add(fileType);
+ }
+ }
+
+ return result.toArray(new FileType[result.size()]);
+ }
+
+ private static boolean isValidFileType(FileType fileType) {
+ return fileType != StdFileTypes.GUI_DESIGNER_FORM &&
+ fileType != StdFileTypes.IDEA_MODULE &&
+ fileType != StdFileTypes.IDEA_PROJECT &&
+ fileType != StdFileTypes.IDEA_WORKSPACE &&
+ fileType != FileTypes.ARCHIVE &&
+ fileType != FileTypes.UNKNOWN &&
+ fileType != FileTypes.PLAIN_TEXT &&
+ !(fileType instanceof AbstractFileType) &&
+ !fileType.isBinary() &&
+ !fileType.isReadOnly();
+ }
+
+ public static String shieldSpecialChars(String word) {
+ final StringBuilder buf = new StringBuilder(word.length());
+
+ for (int i = 0; i < word.length(); ++i) {
+ if (MatchUtils.SPECIAL_CHARS.indexOf(word.charAt(i)) != -1) {
+ buf.append("\\");
+ }
+ buf.append(word.charAt(i));
+ }
+
+ return buf.toString();
+ }
+
+ public static List<Configuration> getPredefinedTemplates() {
+ if (ourPredefinedConfigurations == null) {
+ final List<Configuration> result = new ArrayList<Configuration>();
+ for (StructuralSearchProfile profile : getProfiles()) {
+ Collections.addAll(result, profile.getPredefinedTemplates());
+ }
+ Collections.sort(result);
+ ourPredefinedConfigurations = Collections.unmodifiableList(result);
+ }
+ return ourPredefinedConfigurations;
+ }
+
+ public static boolean isDocCommentOwner(PsiElement match) {
+ final StructuralSearchProfile profile = getProfileByPsiElement(match);
+ return profile != null && profile.isDocCommentOwner(match);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/UnsupportedPatternException.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/UnsupportedPatternException.java
new file mode 100644
index 000000000000..1236264118c2
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/UnsupportedPatternException.java
@@ -0,0 +1,11 @@
+package com.intellij.structuralsearch;
+
+/**
+ * Exception about encountering yet unsupported pattern event.
+ */
+public class UnsupportedPatternException extends RuntimeException {
+
+ public UnsupportedPatternException(String _pattern) {
+ super(_pattern);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/XmlStructuralSearchProfile.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/XmlStructuralSearchProfile.java
new file mode 100644
index 000000000000..5e0ca8bde957
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/XmlStructuralSearchProfile.java
@@ -0,0 +1,229 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.codeInsight.template.XmlContextType;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.lang.xml.XMLLanguage;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlDocument;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.psi.xml.XmlText;
+import com.intellij.structuralsearch.impl.matcher.*;
+import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.compiler.XmlCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.filters.XmlLexicalNodesFilter;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacerUtil;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.LocalTimeCounter;
+import com.intellij.xml.util.HtmlUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static com.intellij.structuralsearch.PredefinedConfigurationUtil.createSearchTemplateInfo;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class XmlStructuralSearchProfile extends StructuralSearchProfile {
+
+ private XmlLexicalNodesFilter myLexicalNodesFilter;
+
+ public void compile(PsiElement[] elements, @NotNull GlobalCompilingVisitor globalVisitor) {
+ elements[0].getParent().accept(new XmlCompilingVisitor(globalVisitor));
+ }
+
+ @NotNull
+ public PsiElementVisitor createMatchingVisitor(@NotNull GlobalMatchingVisitor globalVisitor) {
+ return new XmlMatchingVisitor(globalVisitor);
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor getLexicalNodesFilter(@NotNull LexicalNodesFilter filter) {
+ if (myLexicalNodesFilter == null) {
+ myLexicalNodesFilter = new XmlLexicalNodesFilter(filter);
+ }
+ return myLexicalNodesFilter;
+ }
+
+ @NotNull
+ public CompiledPattern createCompiledPattern() {
+ return new XmlCompiledPattern();
+ }
+
+ @Override
+ public boolean canProcess(@NotNull FileType fileType) {
+ return fileType == StdFileTypes.XML || fileType == StdFileTypes.HTML || fileType == StdFileTypes.JSP ||
+ fileType == StdFileTypes.JSPX || fileType == StdFileTypes.XHTML;
+ }
+
+ public boolean isMyLanguage(@NotNull Language language) {
+ return language instanceof XMLLanguage;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement[] createPatternTree(@NotNull String text,
+ @NotNull PatternTreeContext context,
+ @NotNull FileType fileType,
+ @Nullable Language language,
+ String contextName, @Nullable String extension,
+ @NotNull Project project,
+ boolean physical) {
+ final String ext = extension != null ? extension : fileType.getDefaultExtension();
+ String text1 = context == PatternTreeContext.File ? text : "<QQQ>" + text + "</QQQ>";
+ final PsiFile fileFromText = PsiFileFactory.getInstance(project)
+ .createFileFromText("dummy." + ext, fileType, text1, LocalTimeCounter.currentTime(), physical, true);
+
+ final XmlDocument document = HtmlUtil.getRealXmlDocument(((XmlFile)fileFromText).getDocument());
+ if (context == PatternTreeContext.File) {
+ return new PsiElement[]{document};
+ }
+
+ return document.getRootTag().getValue().getChildren();
+ }
+
+ @Override
+ public Class<? extends TemplateContextType> getTemplateContextTypeClass() {
+ return XmlContextType.class;
+ }
+
+ @NotNull
+ @Override
+ public FileType detectFileType(@NotNull PsiElement context) {
+ PsiFile file = context instanceof PsiFile ? (PsiFile)context : context.getContainingFile();
+ Language contextLanguage = context instanceof PsiFile ? null : context.getLanguage();
+ if (file.getLanguage() == StdLanguages.HTML || (file.getFileType() == StdFileTypes.JSP && contextLanguage == StdLanguages.HTML)) {
+ return StdFileTypes.HTML;
+ }
+ return StdFileTypes.XML;
+ }
+
+ @Override
+ public void checkReplacementPattern(Project project, ReplaceOptions options) {
+ }
+
+ @Override
+ public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
+ return new MyReplaceHandler(context);
+ }
+
+ private static class MyReplaceHandler extends StructuralReplaceHandler {
+ private final ReplacementContext myContext;
+
+ private MyReplaceHandler(ReplacementContext context) {
+ myContext = context;
+ }
+
+ public void replace(ReplacementInfo info, ReplaceOptions options) {
+ PsiElement elementToReplace = info.getMatch(0);
+ assert elementToReplace != null;
+ PsiElement elementParent = elementToReplace.getParent();
+ String replacementToMake = info.getReplacement();
+ boolean listContext = elementToReplace.getParent() instanceof XmlTag;
+
+ if (listContext) {
+ doReplaceInContext(info, elementToReplace, replacementToMake, elementParent, myContext);
+ }
+
+ PsiElement[] statements = ReplacerUtil.createTreeForReplacement(replacementToMake, PatternTreeContext.Block, myContext);
+
+ if (statements.length > 0) {
+ PsiElement replacement = ReplacerUtil.copySpacesAndCommentsBefore(elementToReplace, statements, replacementToMake, elementParent);
+
+ // preserve comments
+ Replacer.handleComments(elementToReplace, replacement, myContext);
+ elementToReplace.replace(replacement);
+ }
+ else {
+ final PsiElement nextSibling = elementToReplace.getNextSibling();
+ elementToReplace.delete();
+ assert nextSibling != null;
+ if (nextSibling.isValid()) {
+ if (nextSibling instanceof PsiWhiteSpace) {
+ nextSibling.delete();
+ }
+ }
+ }
+ }
+ }
+
+ private static void doReplaceInContext(ReplacementInfo info,
+ PsiElement elementToReplace,
+ String replacementToMake,
+ PsiElement elementParent,
+ ReplacementContext context) {
+ PsiElement[] statements = ReplacerUtil.createTreeForReplacement(replacementToMake, PatternTreeContext.Block, context);
+
+ if (statements.length > 1) {
+ elementParent.addRangeBefore(statements[0], statements[statements.length - 1], elementToReplace);
+ }
+ else if (statements.length == 1) {
+ PsiElement replacement = statements[0];
+
+ Replacer.handleComments(elementToReplace, replacement, context);
+
+ try {
+ elementParent.addBefore(replacement, elementToReplace);
+ }
+ catch (IncorrectOperationException e) {
+ elementToReplace.replace(replacement);
+ }
+ }
+
+ final int matchSize = info.getMatchesCount();
+
+ for (int i = 0; i < matchSize; ++i) {
+ PsiElement element = info.getMatch(i);
+
+ if (element == null) continue;
+ PsiElement firstToDelete = element;
+ PsiElement lastToDelete = element;
+ PsiElement prevSibling = element.getPrevSibling();
+ PsiElement nextSibling = element.getNextSibling();
+
+ if (prevSibling instanceof PsiWhiteSpace) {
+ firstToDelete = prevSibling;
+ }
+ else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
+ lastToDelete = nextSibling;
+ }
+ if (nextSibling instanceof XmlText && i + 1 < matchSize) {
+ final PsiElement next = info.getMatch(i + 1);
+ if (next != null && next == nextSibling.getNextSibling()) {
+ lastToDelete = nextSibling;
+ }
+ }
+ element.getParent().deleteChildRange(firstToDelete, lastToDelete);
+ }
+ }
+
+ @Override
+ Configuration[] getPredefinedTemplates() {
+ return XmlPredefinedConfigurations.createPredefinedTemplates();
+ }
+
+ private static class XmlPredefinedConfigurations {
+ private static final String HTML_XML = SSRBundle.message("xml_html.category");
+
+ private static Configuration[] createPredefinedTemplates() {
+ return new Configuration[]{
+ createSearchTemplateInfo("xml tag", "<'a/>", HTML_XML, StdFileTypes.XML),
+ createSearchTemplateInfo("xml attribute", "<'_tag 'attribute=\"'_value\"/>", HTML_XML, StdFileTypes.XML),
+ createSearchTemplateInfo("xml attribute value", "<'_tag '_attribute=\"'value\"/>", HTML_XML, StdFileTypes.XML),
+ createSearchTemplateInfo("xml/html tag value", "<table>'_content*</table>", HTML_XML, StdFileTypes.HTML),
+ };
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java
new file mode 100644
index 000000000000..565f80ac01ce
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java
@@ -0,0 +1,182 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SimpleHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Class to hold compiled pattern information
+ */
+public abstract class CompiledPattern {
+ public static final String ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME = "__class_unmatched__";
+ private SearchScope scope;
+ private NodeIterator nodes;
+ private MatchingStrategy strategy;
+ private PsiElement targetNode;
+ private int optionsHashStamp;
+ private int nodeCount;
+
+ // @todo support this property during matching (how many nodes should be advanced)
+ // when match is not successful (or successful partially)
+ //private int advancement = 1;
+
+ public abstract String[] getTypedVarPrefixes();
+ public abstract boolean isTypedVar(String str);
+
+ public void setTargetNode(final PsiElement element) {
+ targetNode = element;
+ }
+
+ public PsiElement getTargetNode() {
+ return targetNode;
+ }
+
+ public int getOptionsHashStamp() {
+ return optionsHashStamp;
+ }
+
+ public void setOptionsHashStamp(final int optionsHashStamp) {
+ this.optionsHashStamp = optionsHashStamp;
+ }
+
+ public static final Key<Object> HANDLER_KEY = Key.create("ss.handler");
+
+ public MatchingStrategy getStrategy() {
+ return strategy;
+ }
+
+ public void setStrategy(MatchingStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ public NodeIterator getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(List<PsiElement> elements) {
+ this.nodes = new ArrayBackedNodeIterator(PsiUtilCore.toPsiElementArray(elements));
+ this.nodeCount = elements.size();
+ }
+
+ public boolean isTypedVar(final PsiElement element) {
+ return element!=null && isTypedVar( element.getText() );
+ }
+
+ public boolean isRealTypedVar(PsiElement element) {
+ if (element!=null && element.getTextLength()>0) {
+ String str = getTypedVarString(element);
+ if (str.length()==0) {
+ return false;
+ }
+ return isTypedVar( str );
+ } else {
+ return false;
+ }
+ }
+
+ public String getTypedVarString(PsiElement element) {
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
+ if (profile == null) {
+ return element.getText();
+ }
+ return profile.getTypedVarString(element);
+ }
+
+ private final HashMap<Object,MatchingHandler> handlers = new HashMap<Object,MatchingHandler>();
+
+ public MatchingHandler getHandlerSimple(PsiElement node) {
+ return handlers.get(node);
+ }
+
+ private PsiElement last;
+ private MatchingHandler lastHandler;
+
+ public MatchingHandler getHandler(PsiElement node) {
+ if (node==last) {
+ return lastHandler;
+ }
+ MatchingHandler handler = handlers.get(node);
+
+ if (handler==null) {
+ handler = new SimpleHandler();
+ setHandler(node,handler);
+ }
+
+ last = node;
+ lastHandler = handler;
+
+ return handler;
+ }
+
+ public MatchingHandler getHandler(String name) {
+ return handlers.get(name);
+ }
+
+ public void setHandler(PsiElement node, MatchingHandler handler) {
+ last = null;
+ handlers.put(node,handler);
+ }
+
+ public SubstitutionHandler createSubstitutionHandler(
+ String name, String compiledName, boolean target,int minOccurs, int maxOccurs, boolean greedy) {
+
+ SubstitutionHandler handler = (SubstitutionHandler) handlers.get(compiledName);
+ if (handler != null) return handler;
+
+ handler = doCreateSubstitutionHandler(name, target, minOccurs, maxOccurs, greedy);
+
+ handlers.put(compiledName,handler);
+
+ return handler;
+ }
+
+ protected SubstitutionHandler doCreateSubstitutionHandler(String name, boolean target, int minOccurs, int maxOccurs, boolean greedy) {
+ return new SubstitutionHandler(name, target, minOccurs, maxOccurs, greedy);
+ }
+
+ public SearchScope getScope() {
+ return scope;
+ }
+
+ public void setScope(SearchScope scope) {
+ this.scope = scope;
+ }
+
+ public void clearHandlers() {
+ handlers.clear();
+ last = null;
+ lastHandler = null;
+ }
+
+ void clearHandlersState() {
+ for (final MatchingHandler h : handlers.values()) {
+ if (h != null) h.reset();
+ }
+ }
+
+ public boolean isToResetHandler(PsiElement element) {
+ return true;
+ }
+
+ @Nullable
+ public String getAlternativeTextToMatch(PsiElement node, String previousText) {
+ return null;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
new file mode 100644
index 000000000000..e7327fad7e5e
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
@@ -0,0 +1,16 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 07.01.2004
+ * Time: 1:06:51
+ * To change this template use Options | File Templates.
+ */
+public interface DataProvider {
+ Editor getEditor();
+ Project getProject();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java
new file mode 100644
index 000000000000..bfbe065e461c
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/GlobalMatchingVisitor.java
@@ -0,0 +1,319 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.dupLocator.AbstractMatchingVisitor;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.lang.Language;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.DelegatingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Visitor class to manage pattern matching
+ */
+@SuppressWarnings({"RefusedBequest"})
+public class GlobalMatchingVisitor extends AbstractMatchingVisitor {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor");
+
+ // the pattern element for visitor check
+ private PsiElement myElement;
+
+ // the result of matching in visitor
+ private boolean myResult;
+
+ // context of matching
+ private MatchContext matchContext;
+
+ private MatchingHandler myLastHandler;
+
+ private Map<Language, PsiElementVisitor> myLanguage2MatchingVisitor = new HashMap<Language, PsiElementVisitor>(1);
+
+ public PsiElement getElement() {
+ return myElement;
+ }
+
+ public boolean getResult() {
+ return myResult;
+ }
+
+ public void setElement(PsiElement element) {
+ this.myElement = element;
+ }
+
+ public void setResult(boolean result) {
+ this.myResult = result;
+ }
+
+ public MatchContext getMatchContext() {
+ return matchContext;
+ }
+
+ @Override
+ protected boolean doMatchInAnyOrder(NodeIterator elements, NodeIterator elements2) {
+ return matchContext.getPattern().getHandler(elements.current()).matchInAnyOrder(
+ elements,
+ elements2,
+ matchContext
+ );
+ }
+
+ @NotNull
+ @Override
+ protected NodeFilter getNodeFilter() {
+ return LexicalNodesFilter.getInstance();
+ }
+
+ public final boolean handleTypedElement(final PsiElement typedElement, final PsiElement match) {
+ MatchingHandler handler = matchContext.getPattern().getHandler(typedElement);
+ final MatchingHandler initialHandler = handler;
+ if (handler instanceof DelegatingHandler) {
+ handler = ((DelegatingHandler)handler).getDelegate();
+ }
+ assert handler instanceof SubstitutionHandler :
+ handler != null ? handler.getClass() : "null" + ' ' + (initialHandler != null ? initialHandler.getClass() : "null");
+
+ return ((SubstitutionHandler)handler).handle(match, matchContext);
+ }
+
+ /**
+ * Identifies the match between given element of program tree and pattern element
+ *
+ * @param el1 the pattern for matching
+ * @param el2 the tree element for matching
+ * @return true if equal and false otherwise
+ */
+ public boolean match(final PsiElement el1, final PsiElement el2) {
+ // null
+ if (el1 == el2) return true;
+ if (el2 == null || el1 == null) {
+ // this a bug!
+ return false;
+ }
+
+ // copy changed data to local stack
+ PsiElement prevElement = myElement;
+ myElement = el2;
+
+ try {
+ /*if (el1 instanceof XmlElement) {
+ el1.accept(myXmlVisitor);
+ }
+ else {
+ el1.accept(myJavaVisitor);
+ }*/
+ PsiElementVisitor visitor = getVisitorForElement(el1);
+ if (visitor != null) {
+ el1.accept(visitor);
+ }
+ }
+ catch (ClassCastException ex) {
+ myResult = false;
+ }
+ finally {
+ myElement = prevElement;
+ }
+
+ return myResult;
+ }
+
+ @Nullable
+ private PsiElementVisitor getVisitorForElement(PsiElement element) {
+ Language language = element.getLanguage();
+ PsiElementVisitor visitor = myLanguage2MatchingVisitor.get(language);
+ if (visitor == null) {
+ visitor = createMatchingVisitor(language);
+ myLanguage2MatchingVisitor.put(language, visitor);
+ }
+ return visitor;
+ }
+
+ @Nullable
+ private PsiElementVisitor createMatchingVisitor(Language language) {
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(language);
+ if (profile == null) {
+ LOG.warn("there is no StructuralSearchProfile for language " + language.getID());
+ return null;
+ }
+ else {
+ return profile.createMatchingVisitor(this);
+ }
+ }
+
+ /**
+ * Matches tree segments starting with given elements to find equality
+ *
+ * @param nodes the pattern element for matching
+ * @param nodes2 the tree element for matching
+ * @return if they are equal and false otherwise
+ */
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2) {
+ if (!nodes.hasNext()) {
+ return nodes.hasNext() == nodes2.hasNext();
+ }
+
+ myLastHandler = matchContext.getPattern().getHandler(nodes.current());
+ return myLastHandler.matchSequentially(
+ nodes,
+ nodes2,
+ matchContext
+ );
+ }
+
+ public static boolean continueMatchingSequentially(final NodeIterator nodes, final NodeIterator nodes2, MatchContext matchContext) {
+ if (!nodes.hasNext()) {
+ return nodes.hasNext() == nodes2.hasNext();
+ }
+
+ return matchContext.getPattern().getHandler(nodes.current()).matchSequentially(
+ nodes,
+ nodes2,
+ matchContext
+ );
+ }
+
+ /**
+ * Descents the tree in depth finding matches
+ *
+ * @param elements the element for which the sons are looked for match
+ */
+ public void matchContext(final NodeIterator elements) {
+ final CompiledPattern pattern = matchContext.getPattern();
+ final NodeIterator patternNodes = pattern.getNodes().clone();
+ final MatchResultImpl saveResult = matchContext.hasResult() ? matchContext.getResult() : null;
+ final List<PsiElement> saveMatchedNodes = matchContext.getMatchedNodes();
+
+ try {
+ matchContext.setResult(null);
+ matchContext.setMatchedNodes(null);
+
+ if (!patternNodes.hasNext()) return;
+ final MatchingHandler firstMatchingHandler = pattern.getHandler(patternNodes.current());
+
+ for (; elements.hasNext(); elements.advance()) {
+ final PsiElement elementNode = elements.current();
+
+ boolean matched = firstMatchingHandler.matchSequentially(patternNodes, elements, matchContext);
+
+ if (matched) {
+ MatchingHandler matchingHandler = matchContext.getPattern().getHandler(Configuration.CONTEXT_VAR_NAME);
+ if (matchingHandler != null) {
+ matched = ((SubstitutionHandler)matchingHandler).handle(elementNode, matchContext);
+ }
+ }
+
+ final List<PsiElement> matchedNodes = matchContext.getMatchedNodes();
+
+ if (matched) {
+ dispatchMatched(matchedNodes, matchContext.getResult());
+ }
+
+ matchContext.setMatchedNodes(null);
+ matchContext.setResult(null);
+
+ patternNodes.reset();
+ if (matchedNodes != null && matchedNodes.size() > 0 && matched) {
+ elements.rewind();
+ }
+ }
+ }
+ finally {
+ matchContext.setResult(saveResult);
+ matchContext.setMatchedNodes(saveMatchedNodes);
+ }
+ }
+
+ private void dispatchMatched(final List<PsiElement> matchedNodes, MatchResultImpl result) {
+ if (!matchContext.getOptions().isResultIsContextMatch() && doDispatch(result, result)) return;
+
+ // There is no substitutions so show the context
+
+ processNoSubstitutionMatch(matchedNodes, result);
+ matchContext.getSink().newMatch(result);
+ }
+
+ private boolean doDispatch(final MatchResultImpl result, MatchResultImpl context) {
+ boolean ret = false;
+
+ for (MatchResult _r : result.getAllSons()) {
+ final MatchResultImpl r = (MatchResultImpl)_r;
+
+ if ((r.isScopeMatch() && !r.isTarget()) || r.isMultipleMatch()) {
+ ret |= doDispatch(r, context);
+ }
+ else if (r.isTarget()) {
+ r.setContext(context);
+ matchContext.getSink().newMatch(r);
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+ private static void processNoSubstitutionMatch(List<PsiElement> matchedNodes, MatchResultImpl result) {
+ boolean complexMatch = matchedNodes.size() > 1;
+ final PsiElement match = matchedNodes.get(0);
+
+ if (!complexMatch) {
+ result.setMatchRef(new SmartPsiPointer(match));
+ result.setMatchImage(match.getText());
+ }
+ else {
+ MatchResultImpl sonresult;
+
+ for (final PsiElement matchStatement : matchedNodes) {
+ result.getMatches().add(
+ sonresult = new MatchResultImpl(
+ MatchResult.LINE_MATCH,
+ matchStatement.getText(),
+ new SmartPsiPointer(matchStatement),
+ true
+ )
+ );
+
+ sonresult.setParent(result);
+ }
+
+ result.setMatchRef(
+ new SmartPsiPointer(match)
+ );
+ result.setMatchImage(
+ match.getText()
+ );
+ result.setName(MatchResult.MULTI_LINE_MATCH);
+ }
+ }
+
+ public void setMatchContext(MatchContext matchContext) {
+ this.matchContext = matchContext;
+ }
+
+ // Matches the sons of given elements to find equality
+ // @param el1 the pattern element for matching
+ // @param el2 the tree element for matching
+ // @return if they are equal and false otherwise
+
+ @Override
+ protected boolean isLeftLooseMatching() {
+ return matchContext.getOptions().isLooseMatching();
+ }
+
+ @Override
+ protected boolean isRightLooseMatching() {
+ return false;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchConstraintsSink.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchConstraintsSink.java
new file mode 100644
index 000000000000..2036c83d56f4
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchConstraintsSink.java
@@ -0,0 +1,85 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchResultSink;
+import com.intellij.structuralsearch.MatchingProcess;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.psi.PsiFile;
+import com.intellij.openapi.progress.ProgressIndicator;
+
+import javax.swing.*;
+import java.util.HashMap;
+
+/**
+ * Sink to detect
+ */
+class MatchConstraintsSink implements MatchResultSink {
+ private final MatchResultSink delegate;
+ private MatchingProcess process;
+ private final boolean distinct;
+ private final boolean caseSensitive;
+ private int matchCount;
+ private final int maxMatches;
+ private final HashMap<Object, MatchResult> matches = new HashMap<Object, MatchResult>();
+
+ MatchConstraintsSink(MatchResultSink _delegate, int _maxMatches,boolean distinct, boolean _caseSensitive) {
+ delegate = _delegate;
+ maxMatches = _maxMatches;
+ this.distinct = distinct;
+ caseSensitive = _caseSensitive;
+ }
+
+ public void newMatch(MatchResult result) {
+ if (distinct) {
+ String matchImage = result.getMatchImage();
+
+ if (!caseSensitive) matchImage = matchImage.toLowerCase();
+
+ if (matches.get(matchImage)!=null) {
+ return;
+ }
+
+ matches.put(matchImage,result);
+ }
+ else {
+ final PsiElement match = result.getMatch();
+ if (matches.containsKey(match)) {
+ return;
+ }
+ matches.put(match, result);
+ }
+
+ delegate.newMatch(result);
+ ++matchCount;
+
+ if (matchCount==maxMatches) {
+ JOptionPane.showMessageDialog(null, SSRBundle.message("search.produced.too.many.results.message"));
+ process.stop();
+ }
+ }
+
+ /* Notifies sink about starting the matching for given element
+ * @param element the current file
+ * @param task process continuation reference
+ */
+ public void processFile(PsiFile element) {
+ delegate.processFile(element);
+ }
+
+ public void setMatchingProcess(MatchingProcess matchingProcess) {
+ process = matchingProcess;
+ delegate.setMatchingProcess(process);
+ }
+
+ public void matchingFinished() {
+ matchCount = 0;
+ matches.clear();
+ delegate.matchingFinished();
+ }
+
+ public ProgressIndicator getProgressIndicator() {
+ return delegate.getProgressIndicator();
+ }
+
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchContext.java
new file mode 100644
index 000000000000..c4c8d21e3ab3
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchContext.java
@@ -0,0 +1,130 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchResultSink;
+import com.intellij.util.containers.Stack;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Global context of matching process
+ */
+public class MatchContext {
+ private MatchResultSink sink;
+ private final Stack<MatchResultImpl> previousResults = new Stack<MatchResultImpl>();
+ private MatchResultImpl result;
+ private CompiledPattern pattern;
+ private MatchOptions options;
+ private GlobalMatchingVisitor matcher;
+ private boolean shouldRecursivelyMatch = true;
+ private boolean myWithAlternativePatternRoots = true;
+
+ private List<PsiElement> myMatchedNodes;
+
+ public List<PsiElement> getMatchedNodes() {
+ return myMatchedNodes;
+ }
+
+ public void setMatchedNodes(final List<PsiElement> matchedNodes) {
+ myMatchedNodes = matchedNodes;
+ }
+
+ public boolean isWithAlternativePatternRoots() {
+ return myWithAlternativePatternRoots;
+ }
+
+ public void setWithAlternativePatternRoots(boolean withAlternativePatternRoots) {
+ myWithAlternativePatternRoots = withAlternativePatternRoots;
+ }
+
+ public interface MatchedElementsListener {
+ void matchedElements(Collection<PsiElement> matchedElements);
+ void commitUnmatched();
+ }
+
+ private MatchedElementsListener myMatchedElementsListener;
+
+ public void setMatcher(GlobalMatchingVisitor matcher) {
+ this.matcher = matcher;
+ }
+
+ public GlobalMatchingVisitor getMatcher() {
+ return matcher;
+ }
+
+ public MatchOptions getOptions() {
+ return options;
+ }
+
+ public void setOptions(MatchOptions options) {
+ this.options = options;
+ }
+
+ public MatchResultImpl getPreviousResult() {
+ return previousResults.isEmpty() ? null : previousResults.peek();
+ }
+
+ public MatchResultImpl getResult() {
+ if (result==null) result = new MatchResultImpl();
+ return result;
+ }
+
+ public void pushResult() {
+ previousResults.push(result);
+ result = null;
+ }
+
+ public void popResult() {
+ result = previousResults.pop();
+ }
+
+ public void setResult(MatchResultImpl result) {
+ this.result = result;
+ if (result == null) {
+ pattern.clearHandlersState();
+ }
+ }
+
+ public boolean hasResult() {
+ return result!=null;
+ }
+
+ public CompiledPattern getPattern() {
+ return pattern;
+ }
+
+ public void setPattern(CompiledPattern pattern) {
+ this.pattern = pattern;
+ }
+
+ public MatchResultSink getSink() {
+ return sink;
+ }
+
+ public void setSink(MatchResultSink sink) {
+ this.sink = sink;
+ }
+
+ void clear() {
+ result = null;
+ pattern = null;
+ }
+
+ public boolean shouldRecursivelyMatch() {
+ return shouldRecursivelyMatch;
+ }
+
+ public void setShouldRecursivelyMatch(boolean shouldRecursivelyMatch) {
+ this.shouldRecursivelyMatch = shouldRecursivelyMatch;
+ }
+
+ public void setMatchedElementsListener(MatchedElementsListener _matchedElementsListener) {
+ myMatchedElementsListener = _matchedElementsListener;
+ }
+
+ public MatchedElementsListener getMatchedElementsListener() {
+ return myMatchedElementsListener;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchPredicateProvider.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchPredicateProvider.java
new file mode 100644
index 000000000000..b75ffb5d0f5d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchPredicateProvider.java
@@ -0,0 +1,16 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchVariableConstraint;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+
+import java.util.Set;
+
+public abstract class MatchPredicateProvider {
+ public static final ExtensionPointName<MatchPredicateProvider> EP_NAME = ExtensionPointName.create("com.intellij.structuralsearch.matchPredicateProvider");
+ public abstract void collectPredicates(MatchVariableConstraint constraint,
+ String name,
+ MatchOptions options,
+ Set<MatchPredicate> predicates);
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java
new file mode 100644
index 000000000000..8761472d813a
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchResultImpl.java
@@ -0,0 +1,207 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Class describing the match result
+ */
+public final class MatchResultImpl extends MatchResult {
+ private String name;
+ private SmartPsiPointer matchRef;
+ private int start;
+ private int end = -1;
+ private String matchImage;
+ private List<MatchResult> matches;
+ private MatchResult parent;
+ private boolean target;
+
+ @NonNls public static final String DEFAULT_NAME2 = "end of context match";
+ @NonNls public static final String DEFAULT_NAME = "start of context match";
+ private boolean myScopeMatch;
+ private boolean myMultipleMatch;
+ @NonNls private static final String NULL = "null";
+ private MatchResultImpl myContext;
+
+ MatchResultImpl() {
+ }
+
+ public MatchResultImpl(String name, String image, SmartPsiPointer ref, boolean target) {
+ this(name,image,ref,0,-1,target);
+ }
+
+ public MatchResultImpl(String name, String image, SmartPsiPointer ref, int start, int end,boolean target) {
+ matchRef = ref;
+ this.name = name;
+ matchImage = image;
+ this.target = target;
+ this.start = start;
+ this.end = end;
+ }
+
+ public String getMatchImage() {
+ if (matchImage==null) {
+ matchImage = NULL;
+ }
+ return matchImage;
+ }
+
+ public void setParent(MatchResult parent) {
+ this.parent = parent;
+ }
+
+ public SmartPsiPointer getMatchRef() {
+ return matchRef;
+ }
+
+ public PsiElement getMatch() {
+ return matchRef.getElement();
+ }
+
+ public void setMatchRef(SmartPsiPointer matchStart) {
+ matchRef = matchStart;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<MatchResult> getMatches() {
+ if (matches==null) matches = new ArrayList<MatchResult>();
+ return matches;
+ }
+
+ public List<MatchResult> getAllSons() {
+ return getMatches();
+ }
+
+ public boolean hasSons() {
+ return matches!=null;
+ }
+
+ public boolean isScopeMatch() {
+ return myScopeMatch;
+ }
+
+ public boolean isMultipleMatch() {
+ return myMultipleMatch;
+ }
+
+ public void clear() {
+ if (matchRef != null) {
+ matchRef.clear();
+ matchRef = null;
+ }
+
+ if (matches != null) {
+ for (final MatchResult match : matches) {
+ ((MatchResultImpl)match).clear();
+ }
+ matches = null;
+ }
+
+ name = null;
+ matchImage = null;
+ }
+
+ public void clearMatches() {
+ matches = null;
+ }
+
+ public void setScopeMatch(final boolean scopeMatch) {
+ myScopeMatch = scopeMatch;
+ }
+
+ public void setMultipleMatch(final boolean multipleMatch) {
+ myMultipleMatch = multipleMatch;
+ }
+
+ public MatchResultImpl findSon(String name) {
+ if (matches!=null) {
+ // @todo this could be performance bottleneck, replace with hash lookup!
+ for (final MatchResult match : matches) {
+ final MatchResultImpl res = (MatchResultImpl)match;
+
+ if (name.equals(res.getName())) {
+ return res;
+ }
+ }
+ }
+ return null;
+ }
+
+ public MatchResultImpl removeSon(String typedVar) {
+ if (matches == null) return null;
+
+ // @todo this could be performance bottleneck, replace with hash lookup!
+ for(Iterator<MatchResult> i=matches.iterator();i.hasNext();) {
+ final MatchResultImpl res = (MatchResultImpl)i.next();
+ if (typedVar.equals(res.getName())) {
+ i.remove();
+ return res;
+ }
+ }
+
+ return null;
+ }
+
+ public void addSon(MatchResultImpl result) {
+ getMatches().add(result);
+ }
+
+ public void setMatchImage(String matchImage) {
+ this.matchImage = matchImage;
+ }
+
+ public boolean isTarget() {
+ return target;
+ }
+
+ public void setTarget(boolean target) {
+ this.target = target;
+ }
+
+ public boolean isMatchImageNull() {
+ return matchImage==null;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+
+ public void setEnd(int end) {
+ this.end = end;
+ }
+
+ public void setContext(final MatchResultImpl context) {
+ myContext = context;
+ }
+
+ public MatchResultImpl getContext() {
+ return myContext;
+ }
+
+ @Override
+ public String toString() {
+ return "MatchResultImpl{name='" + name + '\'' + ", matchImage='" + matchImage + '\'' + "}";
+ }
+}
+
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchUtils.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchUtils.java
new file mode 100644
index 000000000000..38c31d16524f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatchUtils.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 24.12.2003
+ * Time: 22:10:20
+ * To change this template use Options | File Templates.
+ */
+public class MatchUtils {
+ public static final String SPECIAL_CHARS = "*(){}[]^$\\.-|";
+
+ public static final boolean compareWithNoDifferenceToPackage(final String typeImage,@NonNls final String typeImage2) {
+ if (typeImage == null || typeImage2 == null) return typeImage == typeImage2;
+ return typeImage2.endsWith(typeImage) && (
+ typeImage.length() == typeImage2.length() ||
+ typeImage2.charAt(typeImage2.length()-typeImage.length()-1)=='.' // package separator
+ );
+ }
+
+ public static PsiElement getReferencedElement(final PsiElement element) {
+ if (element instanceof PsiReference) {
+ return ((PsiReference)element).resolve();
+ }
+
+ /*if (element instanceof PsiTypeElement) {
+ PsiType type = ((PsiTypeElement)element).getType();
+
+ if (type instanceof PsiArrayType) {
+ type = ((PsiArrayType)type).getComponentType();
+ }
+ if (type instanceof PsiClassType) {
+ return ((PsiClassType)type).resolve();
+ }
+ return null;
+ }*/
+ return element;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java
new file mode 100644
index 000000000000..d667b068ee48
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java
@@ -0,0 +1,737 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentIterator;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.psi.search.DelegatingGlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.util.CollectingMatchResultSink;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.SmartList;
+import com.intellij.util.indexing.FileBasedIndex;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class makes program structure tree matching:
+ */
+public class MatcherImpl {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.impl.matcher.MatcherImpl");
+ // project being worked on
+ private final Project project;
+
+ // context of matching
+ private final MatchContext matchContext;
+ private boolean isTesting;
+
+ // visitor to delegate the real work
+ private final GlobalMatchingVisitor visitor = new GlobalMatchingVisitor();
+ private ProgressIndicator progress;
+ private final TaskScheduler scheduler = new TaskScheduler();
+
+ private int totalFilesToScan;
+ private int scannedFilesCount;
+
+ public MatcherImpl(final Project project, final MatchOptions matchOptions) {
+ this.project = project;
+ matchContext = new MatchContext();
+ matchContext.setMatcher(visitor);
+
+ if (matchOptions != null) {
+ matchContext.setOptions(matchOptions);
+ cacheCompiledPattern(matchOptions, PatternCompiler.compilePattern(project,matchOptions));
+ }
+ }
+
+ static class LastMatchData {
+ CompiledPattern lastPattern;
+ MatchOptions lastOptions;
+ }
+
+ private static SoftReference<LastMatchData> lastMatchData;
+
+ protected MatcherImpl(Project project) {
+ this(project, null);
+ }
+
+ public static void validate(Project project, MatchOptions options) {
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+
+ synchronized(MatcherImpl.class) {
+ final LastMatchData data = new LastMatchData();
+ data.lastPattern = PatternCompiler.compilePattern(project, options);
+ data.lastOptions = options;
+ lastMatchData = new SoftReference<LastMatchData>(data);
+ }
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(options.getFileType());
+ profile.checkSearchPattern(project, options);
+ }
+
+ public static class CompiledOptions {
+ public final List<Pair<MatchContext, Configuration>> matchContexts;
+
+ public CompiledOptions(final List<Pair<MatchContext, Configuration>> matchContexts) {
+ this.matchContexts = matchContexts;
+ }
+
+ public List<Pair<MatchContext, Configuration>> getMatchContexts() {
+ return matchContexts;
+ }
+ }
+
+ public static boolean checkIfShouldAttemptToMatch(MatchContext context, NodeIterator matchedNodes) {
+ final CompiledPattern pattern = context.getPattern();
+ final NodeIterator patternNodes = pattern.getNodes();
+ try {
+ while (true) {
+ final PsiElement patternNode = patternNodes.current();
+ if (patternNode == null) {
+ return true;
+ }
+ final PsiElement matchedNode = matchedNodes.current();
+ if (matchedNode == null) {
+ return false;
+ }
+ final MatchingHandler matchingHandler = pattern.getHandler(patternNode);
+ if (matchingHandler == null || !matchingHandler.canMatch(patternNode, matchedNode)) {
+ return false;
+ }
+ matchedNodes.advance();
+ patternNodes.advance();
+ }
+ } finally {
+ patternNodes.reset();
+ matchedNodes.reset();
+ }
+ }
+
+ public void processMatchesInElement(MatchContext context, Configuration configuration,
+ NodeIterator matchedNodes,
+ PairProcessor<MatchResult, Configuration> processor) {
+ try {
+ configureOptions(context, configuration, matchedNodes.current(), processor);
+ context.setShouldRecursivelyMatch(false);
+ visitor.matchContext(matchedNodes);
+ } finally {
+ matchedNodes.reset();
+ }
+ }
+
+ public void clearContext() {
+ matchContext.clear();
+ }
+
+ private void configureOptions(MatchContext context,
+ final Configuration configuration,
+ PsiElement psiFile,
+ final PairProcessor<MatchResult, Configuration> processor) {
+ if (psiFile == null) return;
+ LocalSearchScope scope = new LocalSearchScope(psiFile);
+
+ matchContext.clear();
+ matchContext.setMatcher(visitor);
+
+ MatchOptions options = context.getOptions();
+ matchContext.setOptions(options);
+ matchContext.setPattern(context.getPattern());
+ matchContext.setShouldRecursivelyMatch(context.shouldRecursivelyMatch());
+ visitor.setMatchContext(matchContext);
+
+ matchContext.setSink(
+ new MatchConstraintsSink(
+ new MatchResultSink() {
+ public void newMatch(MatchResult result) {
+ processor.process(result, configuration);
+ }
+
+ public void processFile(PsiFile element) {
+ }
+
+ public void setMatchingProcess(MatchingProcess matchingProcess) {
+ }
+
+ public void matchingFinished() {
+ }
+
+ public ProgressIndicator getProgressIndicator() {
+ return null;
+ }
+ },
+ options.getMaxMatchesCount(),
+ options.isDistinct(),
+ options.isCaseSensitiveMatch()
+ )
+ );
+ options.setScope(scope);
+ }
+
+ public CompiledOptions precompileOptions(List<Configuration> configurations) {
+ List<Pair<MatchContext, Configuration>> contexts = new ArrayList<Pair<MatchContext, Configuration>>();
+
+ for (Configuration configuration : configurations) {
+ MatchContext matchContext = new MatchContext();
+ matchContext.setMatcher(visitor);
+ MatchOptions matchOptions = configuration.getMatchOptions();
+ matchContext.setOptions(matchOptions);
+
+ try {
+ CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, matchOptions);
+ matchContext.setPattern(compiledPattern);
+ contexts.add(Pair.create(matchContext, configuration));
+ }
+ catch (UnsupportedPatternException ignored) {}
+ catch (MalformedPatternException ignored) {}
+ }
+ return new CompiledOptions(contexts);
+ }
+
+ Project getProject() {
+ return project;
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ protected void findMatches(MatchResultSink sink, final MatchOptions options) throws MalformedPatternException, UnsupportedPatternException
+ {
+ CompiledPattern compiledPattern = prepareMatching(sink, options);
+ if (compiledPattern== null) {
+ return;
+ }
+
+ matchContext.getSink().setMatchingProcess( scheduler );
+ scheduler.init();
+ progress = matchContext.getSink().getProgressIndicator();
+
+ if (/*TokenBasedSearcher.canProcess(compiledPattern)*/ false) {
+ //TokenBasedSearcher searcher = new TokenBasedSearcher(this);
+ //searcher.search(compiledPattern);
+ if (isTesting) {
+ matchContext.getSink().matchingFinished();
+ return;
+ }
+ }
+ else {
+ if (isTesting) {
+ // testing mode;
+ final PsiElement[] elements = ((LocalSearchScope)options.getScope()).getScope();
+
+ PsiElement parent = elements[0].getParent();
+ if (elements.length > 0 && matchContext.getPattern().getStrategy().continueMatching(parent != null ? parent : elements[0])) {
+ visitor.matchContext(new SsrFilteringNodeIterator(new ArrayBackedNodeIterator(elements)));
+ }
+ else {
+ for (PsiElement element : elements) {
+ match(element);
+ }
+ }
+
+ matchContext.getSink().matchingFinished();
+ return;
+ }
+ if (!findMatches(options, compiledPattern)) {
+ return;
+ }
+ }
+
+ if (scheduler.getTaskQueueEndAction()==null) {
+ scheduler.setTaskQueueEndAction(
+ new Runnable() {
+ public void run() {
+ matchContext.getSink().matchingFinished();
+ }
+ }
+ );
+ }
+
+ scheduler.executeNext();
+ }
+
+ private boolean findMatches(MatchOptions options, CompiledPattern compiledPattern) {
+ LanguageFileType languageFileType = (LanguageFileType)options.getFileType();
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(languageFileType.getLanguage());
+ assert profile != null;
+ PsiElement node = compiledPattern.getNodes().current();
+ final Language ourPatternLanguage = node != null ? profile.getLanguage(node) : ((LanguageFileType)options.getFileType()).getLanguage();
+ final Language ourPatternLanguage2 = ourPatternLanguage == StdLanguages.XML ? StdLanguages.XHTML:null;
+ SearchScope searchScope = compiledPattern.getScope();
+ boolean ourOptimizedScope = searchScope != null;
+ if (!ourOptimizedScope) searchScope = options.getScope();
+
+ if (searchScope instanceof GlobalSearchScope) {
+ final GlobalSearchScope scope = (GlobalSearchScope)searchScope;
+
+ final ContentIterator ci = new ContentIterator() {
+ public boolean processFile(final VirtualFile fileOrDir) {
+ if (!fileOrDir.isDirectory() && scope.contains(fileOrDir) && fileOrDir.getFileType() != FileTypes.UNKNOWN) {
+ ++totalFilesToScan;
+ scheduler.addOneTask(new MatchOneVirtualFile(fileOrDir, profile, ourPatternLanguage, ourPatternLanguage2));
+ }
+ return true;
+ }
+ };
+
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ FileBasedIndex.getInstance().iterateIndexableFiles(ci, project, progress);
+ }
+ });
+ progress.setText2("");
+ }
+ else {
+ final PsiElement[] elementsToScan = ((LocalSearchScope)searchScope).getScope();
+ totalFilesToScan = elementsToScan.length;
+
+ for (int i = 0; i < elementsToScan.length; ++i) {
+ final PsiElement psiElement = elementsToScan[i];
+
+ if (psiElement == null) continue;
+ final Language language = psiElement.getLanguage();
+
+ PsiFile file = psiElement instanceof PsiFile ? (PsiFile)psiElement : psiElement.getContainingFile();
+
+ if (profile.isMyFile(file, language, ourPatternLanguage, ourPatternLanguage2)) {
+ scheduler.addOneTask(new MatchOnePsiFile(psiElement));
+ }
+ if (ourOptimizedScope) elementsToScan[i] = null; // to prevent long PsiElement reference
+ }
+ }
+ return true;
+ }
+
+ private CompiledPattern prepareMatching(final MatchResultSink sink, final MatchOptions options) {
+ CompiledPattern savedPattern = null;
+
+ if (matchContext.getOptions() == options && matchContext.getPattern() != null &&
+ matchContext.getOptions().hashCode() == matchContext.getPattern().getOptionsHashStamp()) {
+ savedPattern = matchContext.getPattern();
+ }
+
+ matchContext.clear();
+ matchContext.setSink(
+ new MatchConstraintsSink(
+ sink,
+ options.getMaxMatchesCount(),
+ options.isDistinct(),
+ options.isCaseSensitiveMatch()
+ )
+ );
+ matchContext.setOptions(options);
+ matchContext.setMatcher(visitor);
+ visitor.setMatchContext(matchContext);
+
+ CompiledPattern compiledPattern = savedPattern;
+
+ if (compiledPattern == null) {
+
+ synchronized(getClass()) {
+ final LastMatchData data = com.intellij.reference.SoftReference.dereference(lastMatchData);
+ if (data != null && options == data.lastOptions) {
+ compiledPattern = data.lastPattern;
+ }
+ lastMatchData = null;
+ }
+
+ if (compiledPattern==null) {
+ compiledPattern = ApplicationManager.getApplication().runReadAction(new Computable<CompiledPattern>() {
+ @Override
+ public CompiledPattern compute() {
+ return PatternCompiler.compilePattern(project,options);
+ }
+ });
+ }
+ }
+
+ cacheCompiledPattern(options, compiledPattern);
+ return compiledPattern;
+ }
+
+ private void cacheCompiledPattern(final MatchOptions options, final CompiledPattern compiledPattern) {
+ matchContext.setPattern(compiledPattern);
+ compiledPattern.setOptionsHashStamp(options.hashCode());
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @param sink match result destination
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ protected void testFindMatches(MatchResultSink sink, MatchOptions options)
+ throws MalformedPatternException, UnsupportedPatternException {
+ isTesting = true;
+ try {
+ findMatches(sink,options);
+ } finally {
+ isTesting = false;
+ }
+ }
+
+ /**
+ * Finds the matches of given pattern starting from given tree element.
+ * @param source string for search
+ * @param pattern to be searched
+ * @return list of matches found
+ * @throws MalformedPatternException
+ * @throws UnsupportedPatternException
+ */
+ protected List<MatchResult> testFindMatches(String source,
+ String pattern,
+ MatchOptions options,
+ boolean filePattern,
+ FileType sourceFileType,
+ String sourceExtension,
+ boolean physicalSourceFile)
+ throws MalformedPatternException, UnsupportedPatternException {
+
+ CollectingMatchResultSink sink = new CollectingMatchResultSink();
+
+ try {
+ PsiElement[] elements = MatcherImplUtil.createSourceTreeFromText(source,
+ filePattern ? PatternTreeContext.File : PatternTreeContext.Block,
+ sourceFileType,
+ sourceExtension,
+ project, physicalSourceFile);
+
+ options.setSearchPattern(pattern);
+ options.setScope(new LocalSearchScope(elements));
+ testFindMatches(sink, options);
+ }
+ catch (IncorrectOperationException e) {
+ MalformedPatternException exception = new MalformedPatternException();
+ exception.initCause(e);
+ throw exception;
+ }
+
+ return sink.getMatches();
+ }
+
+ protected List<MatchResult> testFindMatches(String source, String pattern, MatchOptions options, boolean filePattern) {
+ return testFindMatches(source, pattern, options, filePattern, options.getFileType(), null, false);
+ }
+
+ class TaskScheduler implements MatchingProcess {
+ private LinkedList<Runnable> tasks = new LinkedList<Runnable>();
+ private boolean ended;
+ private Runnable taskQueueEndAction;
+
+ private boolean suspended;
+
+ public void stop() {
+ ended = true;
+ }
+
+ public void pause() {
+ suspended = true;
+ }
+
+ public void resume() {
+ if (!suspended) return;
+ suspended = false;
+ executeNext();
+ }
+
+ public boolean isSuspended() {
+ return suspended;
+ }
+
+ public boolean isEnded() {
+ return ended;
+ }
+
+ void setTaskQueueEndAction(Runnable taskQueueEndAction) {
+ this.taskQueueEndAction = taskQueueEndAction;
+ }
+ Runnable getTaskQueueEndAction () {
+ return taskQueueEndAction;
+ }
+
+ void addOneTask(Runnable runnable) {
+ tasks.add(runnable);
+ }
+
+ private void executeNext() {
+ while(!suspended && !ended) {
+ if (tasks.isEmpty()) {
+ ended = true;
+ break;
+ }
+
+ final Runnable task = tasks.removeFirst();
+ try {
+ task.run();
+ }
+ catch (ProcessCanceledException e) {
+ ended = true;
+ clearSchedule();
+ throw e;
+ }
+ catch (StructuralSearchException e) {
+ ended = true;
+ clearSchedule();
+ throw e;
+ }
+ catch (Throwable th) {
+ LOG.error(th);
+ }
+ }
+
+ if (ended) clearSchedule();
+ }
+
+ private void init() {
+ ended = false;
+ suspended = false;
+ PsiManager.getInstance(project).startBatchFilesProcessingMode();
+ }
+
+ private void clearSchedule() {
+ if (tasks != null) {
+ taskQueueEndAction.run();
+ if (!project.isDisposed()) {
+ PsiManager.getInstance(project).finishBatchFilesProcessingMode();
+ }
+ tasks = null;
+ }
+ }
+
+ }
+
+ private class MatchOnePsiFile extends MatchOneFile {
+ private PsiElement file;
+
+ MatchOnePsiFile(PsiElement file) {
+ this.file = file;
+ }
+
+ @Nullable
+ @Override
+ protected List<PsiElement> getPsiElementsToProcess() {
+ PsiElement file = this.file;
+ this.file = null;
+ return new SmartList<PsiElement>(file);
+ }
+ }
+
+ private abstract class MatchOneFile implements Runnable {
+ public void run() {
+ List<PsiElement> files = getPsiElementsToProcess();
+
+ if (progress!=null) {
+ progress.setFraction((double)scannedFilesCount/totalFilesToScan);
+ }
+
+ ++scannedFilesCount;
+
+ if (files == null || files.size() == 0) return;
+ final PsiFile psiFile = files.get(0).getContainingFile();
+
+ if (psiFile!=null) {
+ final Runnable action = new Runnable() {
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ if (project.isDisposed()) return;
+ final PsiDocumentManager manager = PsiDocumentManager.getInstance(project);
+ Document document = manager.getDocument(psiFile);
+ if (document != null) manager.commitDocument(document);
+ }
+ });
+ }
+ };
+
+ if (ApplicationManager.getApplication().isDispatchThread()) {
+ action.run();
+ } else {
+ ApplicationManager.getApplication().invokeAndWait(
+ action,
+ ModalityState.defaultModalityState()
+ );
+ }
+ }
+
+ if (project.isDisposed()) return;
+
+ for(PsiElement file:files) {
+ if (file instanceof PsiFile) {
+ matchContext.getSink().processFile((PsiFile)file);
+ }
+
+ final PsiElement finalFile = file;
+ ApplicationManager.getApplication().runReadAction(
+ new Runnable() {
+ public void run() {
+ PsiElement file = finalFile;
+ if (!file.isValid()) return;
+ file = StructuralSearchUtil.getProfileByLanguage(file.getLanguage()).extendMatchOnePsiFile(file);
+ match(file);
+ }
+ }
+ );
+ }
+ }
+
+ protected abstract @Nullable List<PsiElement> getPsiElementsToProcess();
+ }
+
+ // Initiates the matching process for given element
+ // @param element the current search tree element
+ public void match(PsiElement element) {
+ MatchingStrategy strategy = matchContext.getPattern().getStrategy();
+
+ if (strategy.continueMatching(element)) {
+ visitor.matchContext(new ArrayBackedNodeIterator(new PsiElement[] {element}));
+ return;
+ }
+ for(PsiElement el=element.getFirstChild();el!=null;el=el.getNextSibling()) {
+ match(el);
+ }
+ if (element instanceof PsiLanguageInjectionHost) {
+ InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ @Override
+ public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
+ match(injectedPsi);
+ }
+ });
+ }
+ }
+
+ @Nullable
+ protected MatchResult isMatchedByDownUp(PsiElement element, final MatchOptions options) {
+ final CollectingMatchResultSink sink = new CollectingMatchResultSink();
+ CompiledPattern compiledPattern = prepareMatching(sink, options);
+
+ if (compiledPattern== null) {
+ assert false;
+ return null;
+ }
+
+ PsiElement targetNode = compiledPattern.getTargetNode();
+ PsiElement elementToStartMatching = null;
+
+ if (targetNode == null) {
+ targetNode = compiledPattern.getNodes().current();
+ if (targetNode != null) {
+ compiledPattern.getNodes().advance();
+ assert !compiledPattern.getNodes().hasNext();
+ compiledPattern.getNodes().rewind();
+
+ while (element.getClass() != targetNode.getClass()) {
+ element = element.getParent();
+ if (element == null) return null;
+ }
+
+ elementToStartMatching = element;
+ }
+ } else {
+ targetNode = StructuralSearchUtil.getProfileByPsiElement(element).extendMatchedByDownUp(targetNode);
+
+ MatchingHandler handler = null;
+
+ while (element.getClass() == targetNode.getClass() ||
+ compiledPattern.isTypedVar(targetNode) && compiledPattern.getHandler(targetNode).canMatch(targetNode, element)
+ ) {
+ handler = compiledPattern.getHandler(targetNode);
+ handler.setPinnedElement(element);
+ elementToStartMatching = element;
+ if (handler instanceof TopLevelMatchingHandler) break;
+ element = element.getParent();
+ targetNode = targetNode.getParent();
+
+ if (options.isLooseMatching()) {
+ element = StructuralSearchUtil.getProfileByPsiElement(element).updateCurrentNode(element);
+ targetNode = StructuralSearchUtil.getProfileByPsiElement(element).updateCurrentNode(targetNode);
+ }
+ }
+
+ if (!(handler instanceof TopLevelMatchingHandler)) return null;
+ }
+
+ assert targetNode != null : "Could not match down up when no target node";
+
+ match(elementToStartMatching);
+ matchContext.getSink().matchingFinished();
+ final int matchCount = sink.getMatches().size();
+ assert matchCount <= 1;
+ return matchCount > 0 ? sink.getMatches().get(0) : null;
+ }
+
+ private class MatchOneVirtualFile extends MatchOneFile {
+ private final VirtualFile myFileOrDir;
+ private final StructuralSearchProfile myProfile;
+ private final Language myOurPatternLanguage;
+ private final Language myOurPatternLanguage2;
+
+ public MatchOneVirtualFile(VirtualFile fileOrDir,
+ StructuralSearchProfile profile,
+ Language ourPatternLanguage,
+ Language ourPatternLanguage2) {
+ myFileOrDir = fileOrDir;
+ myProfile = profile;
+ myOurPatternLanguage = ourPatternLanguage;
+ myOurPatternLanguage2 = ourPatternLanguage2;
+ }
+
+ @Nullable
+ @Override
+ protected List<PsiElement> getPsiElementsToProcess() {
+ return ApplicationManager.getApplication().runReadAction(new Computable<List<PsiElement>>() {
+ @Override
+ public List<PsiElement> compute() {
+ PsiFile file = PsiManager.getInstance(project).findFile(myFileOrDir);
+ if (file == null) {
+ return null;
+ }
+
+ final FileViewProvider viewProvider = file.getViewProvider();
+ List<PsiElement> elementsToProcess = new SmartList<PsiElement>();
+
+ for(Language lang: viewProvider.getLanguages()) {
+ if (myProfile.isMyFile(file, lang, myOurPatternLanguage, myOurPatternLanguage2)) {
+ elementsToProcess.add(viewProvider.getPsi(lang));
+ }
+ }
+
+ return elementsToProcess;
+ }
+ });
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImplUtil.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImplUtil.java
new file mode 100644
index 000000000000..ffc9ae78e876
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImplUtil.java
@@ -0,0 +1,67 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+import com.intellij.util.IncorrectOperationException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 19, 2004
+ * Time: 6:56:25 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class MatcherImplUtil {
+
+ public static void transform(MatchOptions options) {
+ if (options.hasVariableConstraints()) return;
+ PatternCompiler.transformOldPattern(options);
+ }
+
+ public static PsiElement[] createTreeFromText(String text, PatternTreeContext context, FileType fileType, Project project)
+ throws IncorrectOperationException {
+ return createTreeFromText(text, context, fileType, null, null, project, false);
+ }
+
+ public static PsiElement[] createSourceTreeFromText(String text,
+ PatternTreeContext context,
+ FileType fileType,
+ String extension,
+ Project project,
+ boolean physical) {
+ if (fileType instanceof LanguageFileType) {
+ Language language = ((LanguageFileType)fileType).getLanguage();
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(language);
+ if (profile != null) {
+ return profile.createPatternTree(text, context, fileType, null, null, extension, project, physical);
+ }
+ }
+ return PsiElement.EMPTY_ARRAY;
+ }
+
+ public static PsiElement[] createTreeFromText(String text,
+ PatternTreeContext context,
+ FileType fileType,
+ Language language,
+ String contextName,
+ Project project,
+ boolean physical) throws IncorrectOperationException {
+ if (language == null && fileType instanceof LanguageFileType) {
+ language = ((LanguageFileType)fileType).getLanguage();
+ }
+ if (language != null) {
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(language);
+ if (profile != null) {
+ return profile.createPatternTree(text, context, fileType, language, contextName, null, project, physical);
+ }
+ }
+ return PsiElement.EMPTY_ARRAY;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/PatternTreeContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/PatternTreeContext.java
new file mode 100644
index 000000000000..7d93c9ae82e0
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/PatternTreeContext.java
@@ -0,0 +1,8 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public enum PatternTreeContext {
+ File, Block, Class
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlCompiledPattern.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlCompiledPattern.java
new file mode 100644
index 000000000000..0c9f4945e3a5
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlCompiledPattern.java
@@ -0,0 +1,22 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.structuralsearch.impl.matcher.strategies.XmlMatchingStrategy;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class XmlCompiledPattern extends CompiledPattern {
+ private static final String XML_TYPED_VAR_PREFIX = "__";
+
+ public XmlCompiledPattern() {
+ setStrategy(XmlMatchingStrategy.getInstance());
+ }
+
+ public String[] getTypedVarPrefixes() {
+ return new String[] {XML_TYPED_VAR_PREFIX};
+ }
+
+ public boolean isTypedVar(final String str) {
+ return str.startsWith(XML_TYPED_VAR_PREFIX);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlMatchingVisitor.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlMatchingVisitor.java
new file mode 100644
index 000000000000..d2e1e210534b
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/XmlMatchingVisitor.java
@@ -0,0 +1,130 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.psi.XmlElementVisitor;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.psi.xml.*;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class XmlMatchingVisitor extends XmlElementVisitor {
+ private final GlobalMatchingVisitor myMatchingVisitor;
+ private final boolean myCaseSensitive;
+
+ public XmlMatchingVisitor(GlobalMatchingVisitor matchingVisitor) {
+ myMatchingVisitor = matchingVisitor;
+ myCaseSensitive = myMatchingVisitor.getMatchContext().getOptions().isCaseSensitiveMatch();
+ }
+
+ @Override
+ public void visitElement(final PsiElement element) {
+ myMatchingVisitor.setResult(element.textMatches(element));
+ }
+
+ @Override public void visitXmlAttribute(XmlAttribute attribute) {
+ final XmlAttribute another = (XmlAttribute)myMatchingVisitor.getElement();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(attribute.getName());
+
+ myMatchingVisitor.setResult(matches(attribute.getName(), another.getName()) || isTypedVar);
+ if (myMatchingVisitor.getResult()) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(attribute.getValueElement(), another.getValueElement()));
+ }
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(attribute.getName());
+ myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(another, myMatchingVisitor.getMatchContext()));
+ }
+ }
+
+ @Override public void visitXmlAttributeValue(XmlAttributeValue value) {
+ final XmlAttributeValue another = (XmlAttributeValue)myMatchingVisitor.getElement();
+ final String text = value.getValue();
+
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(text);
+ MatchingHandler handler;
+
+ if (isTypedVar && (handler = myMatchingVisitor.getMatchContext().getPattern().getHandler( text )) instanceof SubstitutionHandler) {
+ String text2 = another.getText();
+ int offset = text2.length() > 0 && ( text2.charAt(0) == '"' || text2.charAt(0) == '\'') ? 1:0;
+ myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(another, offset, text2.length() - offset,
+ myMatchingVisitor.getMatchContext()));
+ } else {
+ myMatchingVisitor.setResult(matches(text, another.getValue()));
+ }
+ }
+
+ @Override public void visitXmlTag(XmlTag tag) {
+ final XmlTag another = (XmlTag)myMatchingVisitor.getElement();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(tag.getName());
+
+ myMatchingVisitor.setResult((matches(tag.getName(), another.getName()) || isTypedVar) &&
+ myMatchingVisitor.matchInAnyOrder(tag.getAttributes(), another.getAttributes()));
+
+ if(myMatchingVisitor.getResult()) {
+ final XmlTagChild[] contentChildren = tag.getValue().getChildren();
+
+ if (contentChildren.length > 0) {
+ PsiElement[] patternNodes = contentChildren;
+ PsiElement[] matchedNodes = another.getValue().getChildren();
+
+ if (contentChildren.length != 1) {
+ patternNodes = expandXmlTexts(patternNodes);
+ matchedNodes = expandXmlTexts(matchedNodes);
+ }
+
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(
+ new ArrayBackedNodeIterator(patternNodes),
+ new ArrayBackedNodeIterator(matchedNodes)
+ ));
+ }
+ }
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler( tag.getName() );
+ myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(another, myMatchingVisitor.getMatchContext()));
+ }
+ }
+
+ private static PsiElement[] expandXmlTexts(PsiElement[] children) {
+ List<PsiElement> result = new ArrayList<PsiElement>(children.length);
+ for(PsiElement c:children) {
+ if (c instanceof XmlText) {
+ for(PsiElement p:c.getChildren()) {
+ if (!(p instanceof PsiWhiteSpace)) result.add(p);
+ }
+ } else if (!(c instanceof PsiWhiteSpace)) {
+ result.add(c);
+ }
+ }
+ return PsiUtilCore.toPsiElementArray(result);
+ }
+
+ @Override public void visitXmlText(XmlText text) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(text.getFirstChild(), myMatchingVisitor.getElement().getFirstChild()));
+ }
+
+ @Override public void visitXmlToken(XmlToken token) {
+ if (token.getTokenType() == XmlTokenType.XML_DATA_CHARACTERS) {
+ String text = token.getText();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(text);
+
+ if (isTypedVar) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(token, myMatchingVisitor.getElement()));
+ } else {
+ myMatchingVisitor.setResult(matches(text, myMatchingVisitor.getElement().getText()));
+ }
+ }
+ }
+
+ private boolean matches(String a, String b) {
+ return myCaseSensitive ? a.equals(b) : a.equalsIgnoreCase(b);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/CompileContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/CompileContext.java
new file mode 100644
index 000000000000..09758a5e2191
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/CompileContext.java
@@ -0,0 +1,71 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 17.11.2004
+ * Time: 19:26:37
+ * To change this template use File | Settings | File Templates.
+ */
+public class CompileContext {
+ private OptimizingSearchHelper searchHelper;
+
+ private CompiledPattern pattern;
+ private MatchOptions options;
+ private Project project;
+
+ public void clear() {
+ if (searchHelper!=null) searchHelper.clear();
+
+ project = null;
+ pattern = null;
+ options = null;
+ }
+
+ public void init(final CompiledPattern _result, final MatchOptions _options, final Project _project, final boolean _findMatchingFiles) {
+ options = _options;
+ project = _project;
+ pattern = _result;
+
+ searchHelper = ApplicationManager.getApplication().isUnitTestMode() ?
+ new TestModeOptimizingSearchHelper(this) :
+ new FindInFilesOptimizingSearchHelper(this, _findMatchingFiles, _project);
+ }
+
+ public OptimizingSearchHelper getSearchHelper() {
+ return searchHelper;
+ }
+
+ void setSearchHelper(OptimizingSearchHelper searchHelper) {
+ this.searchHelper = searchHelper;
+ }
+
+ public CompiledPattern getPattern() {
+ return pattern;
+ }
+
+ void setPattern(CompiledPattern pattern) {
+ this.pattern = pattern;
+ }
+
+ MatchOptions getOptions() {
+ return options;
+ }
+
+ void setOptions(MatchOptions options) {
+ this.options = options;
+ }
+
+ Project getProject() {
+ return project;
+ }
+
+ void setProject(Project project) {
+ this.project = project;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/DeleteNodesAction.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/DeleteNodesAction.java
new file mode 100644
index 000000000000..4b5ad7c64545
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/DeleteNodesAction.java
@@ -0,0 +1,59 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.ArrayList;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 17.11.2004
+ * Time: 19:24:40
+ * To change this template use File | Settings | File Templates.
+ */
+class DeleteNodesAction implements Runnable {
+ private final ArrayList elements;
+
+ DeleteNodesAction(ArrayList _elements) {
+ elements = _elements;
+ }
+
+ private void delete(PsiElement first, PsiElement last) throws Exception {
+ if (last==first) {
+ first.delete();
+ } else {
+ first.getParent().deleteChildRange(first,last);
+ }
+ }
+ public void run() {
+ try {
+ PsiElement first= null;
+ PsiElement last = null;
+
+ for(int i = 0;i < elements.size(); ++i) {
+ final PsiElement el = (PsiElement)elements.get(i);
+
+ if (!el.isValid()) continue;
+
+ if (first==null) {
+ first = last = el;
+ } else if (last.getNextSibling()==el) {
+ last = el;
+ } else {
+ delete(first,last);
+ first = last = null;
+ --i;
+ continue;
+ }
+ }
+
+ if (first!=null) {
+ delete(first,last);
+ }
+ } catch(Throwable ex) {
+ ex.printStackTrace();
+ } finally {
+ elements.clear();
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/FindInFilesOptimizingSearchHelper.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/FindInFilesOptimizingSearchHelper.java
new file mode 100644
index 000000000000..ff7f06a36d5b
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/FindInFilesOptimizingSearchHelper.java
@@ -0,0 +1,103 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageNamesValidation;
+import com.intellij.lang.refactoring.NamesValidator;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiSearchHelper;
+import com.intellij.util.Processor;
+import gnu.trove.THashMap;
+
+import java.util.Set;
+
+/**
+ * @author Maxim.Mossienko
+*/
+class FindInFilesOptimizingSearchHelper extends OptimizingSearchHelperBase {
+ private PsiSearchHelper helper;
+ private THashMap<PsiFile,PsiFile> filesToScan;
+ private THashMap<PsiFile,PsiFile> filesToScan2;
+ private Lexer javaLexer;
+
+ private final boolean findMatchingFiles;
+
+ FindInFilesOptimizingSearchHelper(CompileContext _context, boolean _findMatchngFiles, Project project) {
+ super(_context);
+ findMatchingFiles = _findMatchngFiles;
+
+ if (findMatchingFiles) {
+ helper = PsiSearchHelper.SERVICE.getInstance(project);
+
+ if (filesToScan == null) {
+ filesToScan = new THashMap<PsiFile,PsiFile>();
+ filesToScan2 = new THashMap<PsiFile,PsiFile>();
+ }
+ }
+ }
+
+ public boolean doOptimizing() {
+ return findMatchingFiles;
+ }
+
+ public void clear() {
+ super.clear();
+
+ if (filesToScan != null) {
+ filesToScan.clear();
+ filesToScan2.clear();
+
+ helper = null;
+ }
+ }
+
+ protected void doAddSearchWordInCode(final String refname) {
+ final FileType fileType = context.getOptions().getFileType();
+ final Language language = fileType instanceof LanguageFileType ? ((LanguageFileType)fileType).getLanguage() : Language.ANY;
+ final NamesValidator namesValidator = LanguageNamesValidation.INSTANCE.forLanguage(language);
+ if (namesValidator.isKeyword(refname, context.getProject())) {
+ helper.processAllFilesWithWordInText(refname, (GlobalSearchScope)context.getOptions().getScope(), new MyFileProcessor(), true);
+ } else {
+ helper.processAllFilesWithWord(refname, (GlobalSearchScope)context.getOptions().getScope(), new MyFileProcessor(), true);
+ }
+ }
+
+ protected void doAddSearchWordInText(final String refname) {
+ helper.processAllFilesWithWordInText(refname, (GlobalSearchScope)context.getOptions().getScope(), new MyFileProcessor(), true);
+ }
+
+ protected void doAddSearchWordInComments(final String refname) {
+ helper.processAllFilesWithWordInComments(refname, (GlobalSearchScope)context.getOptions().getScope(), new MyFileProcessor());
+ }
+
+ protected void doAddSearchWordInLiterals(final String refname) {
+ helper.processAllFilesWithWordInLiterals(refname, (GlobalSearchScope)context.getOptions().getScope(), new MyFileProcessor());
+ }
+
+ public void endTransaction() {
+ super.endTransaction();
+ THashMap<PsiFile,PsiFile> map = filesToScan;
+ if (map.size() > 0) map.clear();
+ filesToScan = filesToScan2;
+ filesToScan2 = map;
+ }
+
+ public Set<PsiFile> getFilesSetToScan() {
+ return filesToScan.keySet();
+ }
+
+ private class MyFileProcessor implements Processor<PsiFile> {
+ public boolean process(PsiFile file) {
+ if (scanRequest == 0 ||
+ filesToScan.get(file)!=null) {
+ filesToScan2.put(file,file);
+ }
+ return true;
+ }
+ }
+
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/GlobalCompilingVisitor.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/GlobalCompilingVisitor.java
new file mode 100644
index 000000000000..130751adec67
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/GlobalCompilingVisitor.java
@@ -0,0 +1,314 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.filters.CompositeFilter;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.LiteralWithSubstitutionHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.intellij.structuralsearch.MatchOptions.INSTANCE_MODIFIER_NAME;
+import static com.intellij.structuralsearch.MatchOptions.MODIFIER_ANNOTATION_NAME;
+
+/**
+ * @author maxim
+ */
+public class GlobalCompilingVisitor {
+ @NonNls private static final String SUBSTITUTION_PATTERN_STR = "\\b(__\\$_\\w+)\\b";
+ private static final Pattern ourSubstitutionPattern = Pattern.compile(SUBSTITUTION_PATTERN_STR);
+ private static final Set<String> ourReservedWords = new HashSet<String>(Arrays.asList(MODIFIER_ANNOTATION_NAME, INSTANCE_MODIFIER_NAME)) {
+ {
+ for (StructuralSearchProfile profile : Extensions.getExtensions(StructuralSearchProfile.EP_NAME)) {
+ addAll(profile.getReservedWords());
+ }
+ }
+ };
+ private static final Pattern ourAlternativePattern = Pattern.compile("^\\((.+)\\)$");
+ @NonNls private static final String WORD_SEARCH_PATTERN_STR = ".*?\\b(.+?)\\b.*?";
+ private static final Pattern ourWordSearchPattern = Pattern.compile(WORD_SEARCH_PATTERN_STR);
+ private CompileContext context;
+ private final ArrayList<PsiElement> myLexicalNodes = new ArrayList<PsiElement>();
+
+ private int myCodeBlockLevel;
+
+ private static final NodeFilter ourFilter = LexicalNodesFilter.getInstance();
+
+ public static NodeFilter getFilter() {
+ return ourFilter;
+ }
+
+ public void setHandler(PsiElement element, MatchingHandler handler) {
+ MatchingHandler realHandler = context.getPattern().getHandlerSimple(element);
+
+ if (realHandler instanceof SubstitutionHandler) {
+ ((SubstitutionHandler)realHandler).setMatchHandler(handler);
+ }
+ else {
+ // @todo care about composite handler in this case of simple handler!
+ context.getPattern().setHandler(element, handler);
+ }
+ }
+
+ public final void handle(PsiElement element) {
+
+ if ((!ourFilter.accepts(element) ||
+ StructuralSearchUtil.isIdentifier(element)) &&
+ context.getPattern().isRealTypedVar(element) &&
+ context.getPattern().getHandlerSimple(element) == null
+ ) {
+ String name = context.getPattern().getTypedVarString(element);
+ // name is the same for named element (clazz,methods, etc) and token (name of ... itself)
+ // @todo need fix this
+ final SubstitutionHandler handler;
+
+ context.getPattern().setHandler(
+ element,
+ handler = (SubstitutionHandler)context.getPattern().getHandler(name)
+ );
+
+ if (handler != null && context.getOptions().getVariableConstraint(handler.getName()).isPartOfSearchResults()) {
+ handler.setTarget(true);
+ context.getPattern().setTargetNode(element);
+ }
+ }
+ }
+
+ public CompileContext getContext() {
+ return context;
+ }
+
+ public int getCodeBlockLevel() {
+ return myCodeBlockLevel;
+ }
+
+ public void setCodeBlockLevel(int codeBlockLevel) {
+ this.myCodeBlockLevel = codeBlockLevel;
+ }
+
+ static void setFilter(MatchingHandler handler, NodeFilter filter) {
+ if (handler.getFilter() != null &&
+ handler.getFilter().getClass() != filter.getClass()
+ ) {
+ // for constructor we will have the same handler for class and method and tokens itselfa
+ handler.setFilter(
+ new CompositeFilter(
+ filter,
+ handler.getFilter()
+ )
+ );
+ }
+ else {
+ handler.setFilter(filter);
+ }
+ }
+
+ public ArrayList<PsiElement> getLexicalNodes() {
+ return myLexicalNodes;
+ }
+
+ public void addLexicalNode(PsiElement node) {
+ myLexicalNodes.add(node);
+ }
+
+ void compile(PsiElement[] elements, CompileContext context) {
+ myCodeBlockLevel = 0;
+ this.context = context;
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(context.getOptions().getFileType());
+ assert profile != null;
+ profile.compile(elements, this);
+
+ if (context.getPattern().getStrategy() == null) {
+ System.out.println();
+ }
+ }
+
+ @Nullable
+ public MatchingHandler processPatternStringWithFragments(String pattern, OccurenceKind kind) {
+ return processPatternStringWithFragments(pattern, kind, ourSubstitutionPattern);
+ }
+
+ @Nullable
+ public MatchingHandler processPatternStringWithFragments(String pattern, OccurenceKind kind, Pattern substitutionPattern) {
+ String content;
+
+ if (kind == OccurenceKind.LITERAL) {
+ content = pattern.substring(1, pattern.length() - 1);
+ }
+ else if (kind == OccurenceKind.COMMENT) {
+ content = pattern;
+ }
+ else {
+ return null;
+ }
+
+ @NonNls StringBuilder buf = new StringBuilder(content.length());
+ Matcher matcher = substitutionPattern.matcher(content);
+ List<SubstitutionHandler> handlers = null;
+ int start = 0;
+ String word;
+ boolean hasLiteralContent = false;
+
+ SubstitutionHandler handler = null;
+ while (matcher.find()) {
+ if (handlers == null) handlers = new ArrayList<SubstitutionHandler>();
+ handler = (SubstitutionHandler)getContext().getPattern().getHandler(matcher.group(1));
+ if (handler != null) handlers.add(handler);
+
+ word = content.substring(start, matcher.start());
+
+ if (word.length() > 0) {
+ buf.append(StructuralSearchUtil.shieldSpecialChars(word));
+ hasLiteralContent = true;
+
+ processTokenizedName(word, false, kind);
+ }
+
+ RegExpPredicate predicate = MatchingHandler.getSimpleRegExpPredicate(handler);
+
+ if (predicate == null || !predicate.isWholeWords()) {
+ buf.append("(.*?)");
+ }
+ else {
+ buf.append(".*?\\b(").append(predicate.getRegExp()).append(")\\b.*?");
+ }
+
+ if (isSuitablePredicate(predicate, handler)) {
+ processTokenizedName(predicate.getRegExp(), false, kind);
+ }
+
+ start = matcher.end();
+ }
+
+ word = content.substring(start, content.length());
+
+ if (word.length() > 0) {
+ hasLiteralContent = true;
+ buf.append(StructuralSearchUtil.shieldSpecialChars(word));
+
+ processTokenizedName(word, false, kind);
+ }
+
+ if (hasLiteralContent) {
+ if (kind == OccurenceKind.LITERAL) {
+ buf.insert(0, "[\"']");
+ buf.append("[\"']");
+ }
+ buf.append("$");
+ }
+
+ if (handlers != null) {
+ return hasLiteralContent ? new LiteralWithSubstitutionHandler(buf.toString(), handlers) : handler;
+ }
+
+ return null;
+ }
+
+ @Contract("null,_ -> false")
+ static boolean isSuitablePredicate(RegExpPredicate predicate, SubstitutionHandler handler) {
+ return predicate != null && handler.getMinOccurs() != 0 && predicate.couldBeOptimized();
+ }
+
+ public static void addFilesToSearchForGivenWord(String refname,
+ boolean endTransaction,
+ GlobalCompilingVisitor.OccurenceKind kind,
+ CompileContext compileContext) {
+ if (!compileContext.getSearchHelper().doOptimizing()) {
+ return;
+ }
+ if (ourReservedWords.contains(refname)) return; // skip our special annotations !!!
+
+ boolean addedSomething = false;
+
+ if (kind == GlobalCompilingVisitor.OccurenceKind.CODE) {
+ addedSomething = compileContext.getSearchHelper().addWordToSearchInCode(refname);
+ }
+ else if (kind == GlobalCompilingVisitor.OccurenceKind.COMMENT) {
+ addedSomething = compileContext.getSearchHelper().addWordToSearchInComments(refname);
+ }
+ else if (kind == GlobalCompilingVisitor.OccurenceKind.LITERAL) {
+ addedSomething = compileContext.getSearchHelper().addWordToSearchInLiterals(refname);
+ }
+
+ if (addedSomething && endTransaction) {
+ compileContext.getSearchHelper().endTransaction();
+ }
+ }
+
+ public void processTokenizedName(String name, boolean skipComments, GlobalCompilingVisitor.OccurenceKind kind) {
+ WordTokenizer tokenizer = new WordTokenizer(name);
+ for (Iterator<String> i = tokenizer.iterator(); i.hasNext();) {
+ String nextToken = i.next();
+ if (skipComments &&
+ (nextToken.equals("/*") || nextToken.equals("/**") || nextToken.equals("*/") || nextToken.equals("*") || nextToken.equals("//"))
+ ) {
+ continue;
+ }
+
+ Matcher matcher = ourAlternativePattern.matcher(nextToken);
+ if (matcher.matches()) {
+ StringTokenizer alternatives = new StringTokenizer(matcher.group(1), "|");
+ while (alternatives.hasMoreTokens()) {
+ addFilesToSearchForGivenWord(alternatives.nextToken(), !alternatives.hasMoreTokens(), kind, getContext());
+ }
+ }
+ else {
+ addFilesToSearchForGivenWord(nextToken, true, kind, getContext());
+ }
+ }
+ }
+
+ public enum OccurenceKind {
+ LITERAL, COMMENT, CODE
+ }
+
+ private static class WordTokenizer {
+ private final List<String> myWords = new ArrayList<String>();
+
+ WordTokenizer(String text) {
+ final StringTokenizer tokenizer = new StringTokenizer(text);
+ Matcher matcher = null;
+
+ while (tokenizer.hasMoreTokens()) {
+ String nextToken = tokenizer.nextToken();
+ if (matcher == null) {
+ matcher = ourWordSearchPattern.matcher(nextToken);
+ }
+ else {
+ matcher.reset(nextToken);
+ }
+
+ nextToken = (matcher.matches()) ? matcher.group(1) : nextToken;
+ int lastWordStart = 0;
+ int i;
+ for (i = 0; i < nextToken.length(); ++i) {
+ if (!Character.isJavaIdentifierStart(nextToken.charAt(i))) {
+ if (i != lastWordStart) {
+ myWords.add(nextToken.substring(lastWordStart, i));
+ }
+ lastWordStart = i + 1;
+ }
+ }
+
+ if (i != lastWordStart) {
+ myWords.add(nextToken.substring(lastWordStart, i));
+ }
+ }
+ }
+
+ Iterator<String> iterator() {
+ return myWords.iterator();
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelper.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelper.java
new file mode 100644
index 000000000000..8d6a08b6ef95
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelper.java
@@ -0,0 +1,27 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.psi.PsiFile;
+
+import java.util.Set;
+
+/**
+ * @author Maxim.Mossienko
+*/
+public interface OptimizingSearchHelper {
+ boolean doOptimizing();
+ void clear();
+
+ boolean addWordToSearchInCode(final String refname);
+
+ boolean addWordToSearchInText(final String refname);
+
+ boolean addWordToSearchInComments(final String refname);
+
+ boolean addWordToSearchInLiterals(final String refname);
+
+ void endTransaction();
+
+ boolean isScannedSomething();
+
+ Set<PsiFile> getFilesSetToScan();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelperBase.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelperBase.java
new file mode 100644
index 000000000000..2d6f2bc41b37
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/OptimizingSearchHelperBase.java
@@ -0,0 +1,85 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import gnu.trove.THashSet;
+
+/**
+ * @author Maxim.Mossienko
+*/
+abstract class OptimizingSearchHelperBase implements OptimizingSearchHelper {
+ private final THashSet<String> scanned;
+ private final THashSet<String> scannedText;
+ private final THashSet<String> scannedComments;
+ private final THashSet<String> scannedLiterals;
+ protected int scanRequest;
+
+
+ protected final CompileContext context;
+
+ OptimizingSearchHelperBase(CompileContext _context) {
+ context = _context;
+
+ scanRequest = 0;
+ scanned = new THashSet<String>();
+ scannedText = new THashSet<String>();
+ scannedComments = new THashSet<String>();
+ scannedLiterals = new THashSet<String>();
+ }
+
+ public void clear() {
+ scanned.clear();
+ scannedComments.clear();
+ scannedLiterals.clear();
+ }
+
+ public boolean addWordToSearchInCode(final String refname) {
+ if (!scanned.contains(refname)) {
+ doAddSearchWordInCode(refname);
+ scanned.add( refname );
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean addWordToSearchInText(final String refname) {
+ if (!scannedText.contains(refname)) {
+ doAddSearchWordInText(refname);
+ scannedText.add(refname);
+ return true;
+ }
+ return false;
+ }
+
+ protected abstract void doAddSearchWordInCode(final String refname);
+ protected abstract void doAddSearchWordInText(final String refname);
+
+ protected abstract void doAddSearchWordInComments(final String refname);
+ protected abstract void doAddSearchWordInLiterals(final String refname);
+
+ public void endTransaction() {
+ scanRequest++;
+ }
+
+ public boolean addWordToSearchInComments(final String refname) {
+ if (!scannedComments.contains(refname)) {
+ doAddSearchWordInComments(refname);
+
+ scannedComments.add( refname );
+ return true;
+ }
+ return false;
+ }
+
+ public boolean addWordToSearchInLiterals(final String refname) {
+ if (!scannedLiterals.contains(refname)) {
+ doAddSearchWordInLiterals(refname);
+ scannedLiterals.add( refname );
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isScannedSomething() {
+ return scanned.size() > 0 || scannedComments.size() > 0 || scannedLiterals.size() > 0;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java
new file mode 100644
index 000000000000..e290ebb70793
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java
@@ -0,0 +1,512 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.codeInsight.template.Template;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.lang.Language;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiErrorElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
+import com.intellij.psi.impl.source.PsiFileImpl;
+import com.intellij.psi.impl.source.tree.LeafElement;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.MatchPredicateProvider;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.structuralsearch.impl.matcher.predicates.*;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.util.IncorrectOperationException;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Compiles the handlers for usability
+ */
+public class PatternCompiler {
+ private static CompileContext lastTestingContext;
+
+ public static void transformOldPattern(MatchOptions options) {
+ StringToConstraintsTransformer.transformOldPattern(options);
+ }
+
+ public static CompiledPattern compilePattern(final Project project, final MatchOptions options) throws MalformedPatternException,
+ UnsupportedOperationException {
+ FileType fileType = options.getFileType();
+ assert fileType instanceof LanguageFileType;
+ Language language = ((LanguageFileType)fileType).getLanguage();
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByLanguage(language);
+ assert profile != null;
+ CompiledPattern result = profile.createCompiledPattern();
+
+ final String[] prefixes = result.getTypedVarPrefixes();
+ assert prefixes.length > 0;
+
+ final CompileContext context = new CompileContext();
+ if (ApplicationManager.getApplication().isUnitTestMode()) lastTestingContext = context;
+
+ /*CompiledPattern result = options.getFileType() == StdFileTypes.JAVA ?
+ new JavaCompiledPattern() :
+ new XmlCompiledPattern();*/
+
+ try {
+ context.init(result, options, project, options.getScope() instanceof GlobalSearchScope);
+
+ List<PsiElement> elements = compileByAllPrefixes(project, options, result, context, prefixes);
+
+ context.getPattern().setNodes(elements);
+
+ if (context.getSearchHelper().doOptimizing() && context.getSearchHelper().isScannedSomething()) {
+ final Set<PsiFile> set = context.getSearchHelper().getFilesSetToScan();
+ final List<PsiFile> filesToScan = new ArrayList<PsiFile>(set.size());
+ final GlobalSearchScope scope = (GlobalSearchScope)options.getScope();
+
+ for (final PsiFile file : set) {
+ if (!scope.contains(file.getVirtualFile())) {
+ continue;
+ }
+
+ if (file instanceof PsiFileImpl) {
+ ((PsiFileImpl)file).clearCaches();
+ }
+ filesToScan.add(file);
+ }
+
+ if (filesToScan.size() == 0) {
+ throw new MalformedPatternException(SSRBundle.message("ssr.will.not.find.anything"));
+ }
+ result.setScope(
+ new LocalSearchScope(PsiUtilCore.toPsiElementArray(filesToScan))
+ );
+ }
+ } finally {
+ context.clear();
+ }
+
+ return result;
+ }
+
+ public static String getLastFindPlan() {
+ return ((TestModeOptimizingSearchHelper)lastTestingContext.getSearchHelper()).getSearchPlan();
+ }
+
+ @NotNull
+ private static List<PsiElement> compileByAllPrefixes(Project project,
+ MatchOptions options,
+ CompiledPattern pattern,
+ CompileContext context,
+ String[] applicablePrefixes) {
+ if (applicablePrefixes.length == 0) {
+ return Collections.emptyList();
+ }
+
+ List<PsiElement> elements = doCompile(project, options, pattern, new ConstantPrefixProvider(applicablePrefixes[0]), context);
+ if (elements.isEmpty()) {
+ return elements;
+ }
+
+ final PsiFile file = elements.get(0).getContainingFile();
+ if (file == null) {
+ return elements;
+ }
+
+ final PsiElement last = elements.get(elements.size() - 1);
+ final Pattern[] patterns = new Pattern[applicablePrefixes.length];
+
+ for (int i = 0; i < applicablePrefixes.length; i++) {
+ String s = StructuralSearchUtil.shieldSpecialChars(applicablePrefixes[i]);
+ patterns[i] = Pattern.compile(s + "\\w+\\b");
+ }
+
+ final int[] varEndOffsets = findAllTypedVarOffsets(file, patterns);
+
+ final int patternEndOffset = last.getTextRange().getEndOffset();
+ if (elements.size() == 0 ||
+ checkErrorElements(file, patternEndOffset, patternEndOffset, varEndOffsets, true) != Boolean.TRUE) {
+ return elements;
+ }
+
+ final int varCount = varEndOffsets.length;
+ final String[] prefixSequence = new String[varCount];
+
+ for (int i = 0; i < varCount; i++) {
+ prefixSequence[i] = applicablePrefixes[0];
+ }
+
+ final List<PsiElement> finalElements =
+ compileByPrefixes(project, options, pattern, context, applicablePrefixes, patterns, prefixSequence, 0);
+ return finalElements != null
+ ? finalElements
+ : doCompile(project, options, pattern, new ConstantPrefixProvider(applicablePrefixes[0]), context);
+ }
+
+ @Nullable
+ private static List<PsiElement> compileByPrefixes(Project project,
+ MatchOptions options,
+ CompiledPattern pattern,
+ CompileContext context,
+ String[] applicablePrefixes,
+ Pattern[] substitutionPatterns,
+ String[] prefixSequence,
+ int index) {
+ if (index >= prefixSequence.length) {
+ final List<PsiElement> elements = doCompile(project, options, pattern, new ArrayPrefixProvider(prefixSequence), context);
+ if (elements.isEmpty()) {
+ return elements;
+ }
+
+ final PsiElement parent = elements.get(0).getParent();
+ final PsiElement last = elements.get(elements.size() - 1);
+ final int[] varEndOffsets = findAllTypedVarOffsets(parent.getContainingFile(), substitutionPatterns);
+ final int patternEndOffset = last.getTextRange().getEndOffset();
+ return checkErrorElements(parent, patternEndOffset, patternEndOffset, varEndOffsets, false) != Boolean.TRUE
+ ? elements
+ : null;
+ }
+
+ String[] alternativeVariant = null;
+
+ for (String applicablePrefix : applicablePrefixes) {
+ prefixSequence[index] = applicablePrefix;
+
+ List<PsiElement> elements = doCompile(project, options, pattern, new ArrayPrefixProvider(prefixSequence), context);
+ if (elements.isEmpty()) {
+ return elements;
+ }
+
+ final PsiFile file = elements.get(0).getContainingFile();
+ if (file == null) {
+ return elements;
+ }
+
+ final int[] varEndOffsets = findAllTypedVarOffsets(file, substitutionPatterns);
+ final int offset = varEndOffsets[index];
+
+ final int patternEndOffset = elements.get(elements.size() - 1).getTextRange().getEndOffset();
+ final Boolean result = checkErrorElements(file, offset, patternEndOffset, varEndOffsets, false);
+
+ if (result == Boolean.TRUE) {
+ continue;
+ }
+
+ if (result == Boolean.FALSE || (result == null && alternativeVariant == null)) {
+ final List<PsiElement> finalElements =
+ compileByPrefixes(project, options, pattern, context, applicablePrefixes, substitutionPatterns, prefixSequence, index + 1);
+ if (finalElements != null) {
+ if (result == Boolean.FALSE) {
+ return finalElements;
+ }
+ alternativeVariant = new String[prefixSequence.length];
+ System.arraycopy(prefixSequence, 0, alternativeVariant, 0, prefixSequence.length);
+ }
+ }
+ }
+
+ return alternativeVariant != null ?
+ compileByPrefixes(project, options, pattern, context, applicablePrefixes, substitutionPatterns, alternativeVariant, index + 1) :
+ null;
+ }
+
+ @NotNull
+ private static int[] findAllTypedVarOffsets(final PsiFile file, final Pattern[] substitutionPatterns) {
+ final TIntHashSet result = new TIntHashSet();
+
+ file.accept(new PsiRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+
+ if (element instanceof LeafElement) {
+ final String text = element.getText();
+
+ for (Pattern pattern : substitutionPatterns) {
+ final Matcher matcher = pattern.matcher(text);
+
+ while (matcher.find()) {
+ result.add(element.getTextRange().getStartOffset() + matcher.end());
+ }
+ }
+ }
+ }
+ });
+
+ final int[] resultArray = result.toArray();
+ Arrays.sort(resultArray);
+ return resultArray;
+ }
+
+
+ /**
+ * False: there are no error elements before offset, except patternEndOffset
+ * Null: there are only error elements located exactly after template variables or at the end of the pattern
+ * True: otherwise
+ */
+ @Nullable
+ private static Boolean checkErrorElements(PsiElement element,
+ final int offset,
+ final int patternEndOffset,
+ final int[] varEndOffsets,
+ final boolean strict) {
+ final TIntArrayList errorOffsets = new TIntArrayList();
+ final boolean[] containsErrorTail = {false};
+ final TIntHashSet varEndOffsetsSet = new TIntHashSet(varEndOffsets);
+
+ element.accept(new PsiRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ super.visitElement(element);
+
+ if (!(element instanceof PsiErrorElement)) {
+ return;
+ }
+
+ final int startOffset = element.getTextRange().getStartOffset();
+
+ if ((strict || !varEndOffsetsSet.contains(startOffset)) && startOffset != patternEndOffset) {
+ errorOffsets.add(startOffset);
+ }
+
+ if (startOffset == offset) {
+ containsErrorTail[0] = true;
+ }
+ }
+ });
+
+ for (int i = 0; i < errorOffsets.size(); i++) {
+ final int errorOffset = errorOffsets.get(i);
+ if (errorOffset <= offset) {
+ return true;
+ }
+ }
+ return containsErrorTail[0] ? null : false;
+ }
+
+ private interface PrefixProvider {
+ String getPrefix(int varIndex);
+ }
+
+ private static class ConstantPrefixProvider implements PrefixProvider {
+ private final String myPrefix;
+
+ private ConstantPrefixProvider(String prefix) {
+ myPrefix = prefix;
+ }
+
+ @Override
+ public String getPrefix(int varIndex) {
+ return myPrefix;
+ }
+ }
+
+ private static class ArrayPrefixProvider implements PrefixProvider {
+ private final String[] myPrefixes;
+
+ private ArrayPrefixProvider(String[] prefixes) {
+ myPrefixes = prefixes;
+ }
+
+ @Override
+ public String getPrefix(int varIndex) {
+ try {
+ return myPrefixes[varIndex];
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+ }
+
+ private static List<PsiElement> doCompile(Project project,
+ MatchOptions options,
+ CompiledPattern result,
+ PrefixProvider prefixProvider,
+ CompileContext context) {
+ result.clearHandlers();
+ context.init(result, options, project, options.getScope() instanceof GlobalSearchScope);
+
+ final StringBuilder buf = new StringBuilder();
+
+ Template template = TemplateManager.getInstance(project).createTemplate("","",options.getSearchPattern());
+
+ int segmentsCount = template.getSegmentsCount();
+ String text = template.getTemplateText();
+ buf.setLength(0);
+ int prevOffset = 0;
+
+ for(int i=0;i<segmentsCount;++i) {
+ final int offset = template.getSegmentOffset(i);
+ final String name = template.getSegmentName(i);
+
+ final String prefix = prefixProvider.getPrefix(i);
+ if (prefix == null) {
+ throw new MalformedPatternException();
+ }
+
+ buf.append(text.substring(prevOffset,offset));
+ buf.append(prefix);
+ buf.append(name);
+
+ MatchVariableConstraint constraint = options.getVariableConstraint(name);
+ if (constraint==null) {
+ // we do not edited the constraints
+ constraint = new MatchVariableConstraint();
+ constraint.setName( name );
+ options.addVariableConstraint(constraint);
+ }
+
+ SubstitutionHandler handler = result.createSubstitutionHandler(
+ name,
+ prefix + name,
+ constraint.isPartOfSearchResults(),
+ constraint.getMinCount(),
+ constraint.getMaxCount(),
+ constraint.isGreedy()
+ );
+
+ if(constraint.isWithinHierarchy()) {
+ handler.setSubtype(true);
+ }
+
+ if(constraint.isStrictlyWithinHierarchy()) {
+ handler.setStrictSubtype(true);
+ }
+
+ MatchPredicate predicate;
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getRegExp())) {
+ predicate = new RegExpPredicate(
+ constraint.getRegExp(),
+ options.isCaseSensitiveMatch(),
+ name,
+ constraint.isWholeWordsOnly(),
+ constraint.isPartOfSearchResults()
+ );
+ if (constraint.isInvertRegExp()) {
+ predicate = new NotPredicate(predicate);
+ }
+ addPredicate(handler,predicate);
+ }
+
+ if (constraint.isReference()) {
+ predicate = new ReferencePredicate( constraint.getNameOfReferenceVar() );
+
+ if (constraint.isInvertReference()) {
+ predicate = new NotPredicate(predicate);
+ }
+ addPredicate(handler,predicate);
+ }
+
+ Set<MatchPredicate> predicates = new LinkedHashSet<MatchPredicate>();
+ for (MatchPredicateProvider matchPredicateProvider : Extensions.getExtensions(MatchPredicateProvider.EP_NAME)) {
+ matchPredicateProvider.collectPredicates(constraint, name, options, predicates);
+ }
+ for (MatchPredicate matchPredicate : predicates) {
+ addPredicate(handler, matchPredicate);
+ }
+
+ addScriptConstraint(name, constraint, handler);
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getContainsConstraint())) {
+ predicate = new ContainsPredicate(name, constraint.getContainsConstraint());
+ if (constraint.isInvertContainsConstraint()) {
+ predicate = new NotPredicate(predicate);
+ }
+ addPredicate(handler,predicate);
+ }
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getWithinConstraint())) {
+ assert false;
+ }
+
+ prevOffset = offset;
+ }
+
+ MatchVariableConstraint constraint = options.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
+ if (constraint != null) {
+ SubstitutionHandler handler = result.createSubstitutionHandler(
+ Configuration.CONTEXT_VAR_NAME,
+ Configuration.CONTEXT_VAR_NAME,
+ constraint.isPartOfSearchResults(),
+ constraint.getMinCount(),
+ constraint.getMaxCount(),
+ constraint.isGreedy()
+ );
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getWithinConstraint())) {
+ MatchPredicate predicate = new WithinPredicate(Configuration.CONTEXT_VAR_NAME, constraint.getWithinConstraint(), project);
+ if (constraint.isInvertWithinConstraint()) {
+ predicate = new NotPredicate(predicate);
+ }
+ addPredicate(handler,predicate);
+ }
+
+ addScriptConstraint(Configuration.CONTEXT_VAR_NAME, constraint, handler);
+ }
+
+ buf.append(text.substring(prevOffset,text.length()));
+
+ PsiElement[] matchStatements;
+
+ try {
+ final String pattern = buf.toString();
+ matchStatements = MatcherImplUtil.createTreeFromText(pattern, PatternTreeContext.Block, options.getFileType(),
+ options.getDialect(), options.getPatternContext(), project, false);
+ if (matchStatements.length==0) throw new MalformedPatternException(pattern);
+ } catch (IncorrectOperationException e) {
+ throw new MalformedPatternException(e.getMessage());
+ }
+
+ NodeFilter filter = LexicalNodesFilter.getInstance();
+
+ GlobalCompilingVisitor compilingVisitor = new GlobalCompilingVisitor();
+ compilingVisitor.compile(matchStatements,context);
+ ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
+
+ for (PsiElement matchStatement : matchStatements) {
+ if (!filter.accepts(matchStatement)) {
+ elements.add(matchStatement);
+ }
+ }
+
+ new DeleteNodesAction(compilingVisitor.getLexicalNodes()).run();
+ return elements;
+ }
+
+ private static void addScriptConstraint(String name, MatchVariableConstraint constraint, SubstitutionHandler handler) {
+ MatchPredicate predicate;
+ if (constraint.getScriptCodeConstraint()!= null && constraint.getScriptCodeConstraint().length() > 2) {
+ final String script = StringUtil.stripQuotesAroundValue(constraint.getScriptCodeConstraint());
+ final String s = ScriptSupport.checkValidScript(script);
+ if (s != null) throw new MalformedPatternException("Script constraint for " + constraint.getName() + " has problem "+s);
+ predicate = new ScriptPredicate(name, script);
+ addPredicate(handler,predicate);
+ }
+ }
+
+ static void addPredicate(SubstitutionHandler handler, MatchPredicate predicate) {
+ if (handler.getPredicate()==null) {
+ handler.setPredicate(predicate);
+ } else {
+ handler.setPredicate(new BinaryPredicate(handler.getPredicate(), predicate, false));
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformer.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformer.java
new file mode 100644
index 000000000000..0d684503a14d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformer.java
@@ -0,0 +1,436 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 17.11.2004
+ * Time: 19:29:05
+ * To change this template use File | Settings | File Templates.
+ */
+class StringToConstraintsTransformer {
+ @NonNls private static final String P_STR = "(\\w+)\\('(\\w+)\\)";
+ private static final Pattern p = Pattern.compile(P_STR);
+ @NonNls private static final String P2_STR = "(\\w+)";
+ private static final Pattern p2 = Pattern.compile(P2_STR);
+ @NonNls private static final String P3_STR = "(\\w+)\\(( ?(?:[\\\"\\*<>!\\.\\?\\:\\$\\\\\\(\\)\\[\\]\\w\\|\\+ =]*|(?:\\\"[^\\\"]*\\\")) ?)\\)";
+ private static final Pattern p3 = Pattern.compile(P3_STR);
+ @NonNls private static final String REF = "ref";
+ @NonNls private static final String READ = "read";
+ @NonNls private static final String WRITE = "write";
+ @NonNls private static final String REGEX = "regex";
+ @NonNls private static final String REGEXW = "regexw";
+ @NonNls private static final String EXPRTYPE = "exprtype";
+ @NonNls private static final String FORMAL = "formal";
+ @NonNls private static final String SCRIPT = "script";
+ @NonNls private static final String CONTAINS = "contains";
+ @NonNls private static final String WITHIN = "within";
+
+ static void transformOldPattern(MatchOptions options) {
+ final String pattern = options.getSearchPattern();
+
+ final StringBuilder buf = new StringBuilder();
+
+ StringBuilder miscBuffer = null;
+ int anonymousTypedVarsCount = 0;
+
+ for(int index=0;index < pattern.length();++index) {
+ char ch = pattern.charAt(index);
+
+ if (ch=='\'') {
+ // doubling '
+ final int length = pattern.length();
+ if (index + 1 < length &&
+ pattern.charAt(index + 1)=='\''
+ ) {
+ // ignore next '
+ index++;
+ } else if (index + 2 < length &&
+ pattern.charAt(index + 2)=='\''
+ ) {
+ // eat simple character
+ buf.append(ch);
+ buf.append(pattern.charAt(++index));
+ ch = pattern.charAt(++index);
+ } else if (index + 3 < length &&
+ pattern.charAt(index + 1)=='\\' &&
+ pattern.charAt(index + 3)=='\''
+ ) {
+ // eat simple escape character
+ buf.append(ch);
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ ch = pattern.charAt(++index);
+ } else if (index + 7 < length &&
+ pattern.charAt(index + 1)=='\\' &&
+ pattern.charAt(index + 2)=='u' &&
+ pattern.charAt(index + 7)=='\'') {
+ // eat simple escape character
+ buf.append(ch);
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ buf.append(pattern.charAt(++index));
+ ch = pattern.charAt(++index);
+ } else {
+ // typed variable
+
+ buf.append("$");
+ if (miscBuffer == null) miscBuffer = new StringBuilder();
+ else miscBuffer.setLength(0);
+
+ // eat the name of typed var
+ for(++index; index< length && Character.isJavaIdentifierPart(ch = pattern.charAt(index)); ++index) {
+ miscBuffer.append(ch);
+ buf.append(ch);
+ }
+
+ boolean anonymous = false;
+
+ if (miscBuffer.length() == 0) throw new MalformedPatternException(SSRBundle.message("error.expected.character"));
+ if (miscBuffer.charAt(0)=='_') {
+ anonymous = true;
+
+ if(miscBuffer.length() == 1) {
+ // anonymous var, make it unique for the case of constraints
+ anonymousTypedVarsCount++;
+ miscBuffer.append(anonymousTypedVarsCount);
+ buf.append(anonymousTypedVarsCount);
+ } else {
+ buf.deleteCharAt(buf.length()-miscBuffer.length());
+ miscBuffer.deleteCharAt(0);
+ }
+ }
+
+
+ buf.append("$");
+ String typedVar = miscBuffer.toString();
+ int minOccurs = 1;
+ int maxOccurs = 1;
+ boolean greedy = true;
+ MatchVariableConstraint constraint = options.getVariableConstraint(typedVar);
+ boolean constraintCreated = false;
+
+ if (constraint==null) {
+ constraint = new MatchVariableConstraint();
+ constraint.setName( typedVar );
+ constraintCreated = true;
+ }
+
+ // Check the number of occurrences for typed variable
+ if (index < length) {
+ char possibleQuantifier = pattern.charAt(index);
+
+ if (possibleQuantifier=='+') {
+ maxOccurs = Integer.MAX_VALUE;
+ ++index;
+ } else if (possibleQuantifier=='?') {
+ minOccurs = 0;
+ ++index;
+ } else if (possibleQuantifier=='*') {
+ minOccurs = 0;
+ maxOccurs = Integer.MAX_VALUE;
+ ++index;
+ } else if (possibleQuantifier=='{') {
+ ++index;
+ minOccurs = 0;
+ while (index < length && (ch = pattern.charAt(index)) >= '0' && ch <= '9') {
+ minOccurs *= 10;
+ minOccurs += (ch - '0');
+ if (minOccurs < 0) throw new MalformedPatternException(SSRBundle.message("error.overflow"));
+ ++index;
+ }
+
+ if (ch==',') {
+ ++index;
+ maxOccurs = 0;
+
+ while (index < length && (ch = pattern.charAt(index)) >= '0' && ch <= '9') {
+ maxOccurs *= 10;
+ maxOccurs += (ch - '0');
+ if (maxOccurs < 0) throw new MalformedPatternException(SSRBundle.message("error.overflow"));
+ ++index;
+ }
+ } else {
+ maxOccurs = Integer.MAX_VALUE;
+ }
+
+ if (ch != '}') {
+ if (maxOccurs == Integer.MAX_VALUE) throw new MalformedPatternException(SSRBundle.message("error.expected.brace1"));
+ else throw new MalformedPatternException(SSRBundle.message("error.expected.brace2"));
+ }
+ ++index;
+ }
+
+ if (index < length) {
+ ch = pattern.charAt(index);
+ if (ch=='?') {
+ greedy = false;
+ ++index;
+ }
+ }
+ }
+
+ if (constraintCreated) {
+ constraint.setMinCount(minOccurs);
+ constraint.setMaxCount(maxOccurs);
+ constraint.setGreedy(greedy);
+ constraint.setPartOfSearchResults(!anonymous);
+ }
+
+ if (index < length && pattern.charAt(index) == ':') {
+ ++index;
+ if (index >= length) throw new MalformedPatternException(SSRBundle.message("error.expected.condition", ':'));
+ ch = pattern.charAt(index);
+ if (ch == ':') {
+ // double colon instead of condition
+ buf.append(ch);
+ }
+ else {
+ index = eatTypedVarCondition(index, pattern, miscBuffer, constraint);
+ }
+ }
+
+ if (constraintCreated) {
+ if (constraint.getWithinConstraint().length() > 0) {
+ constraint.setName(Configuration.CONTEXT_VAR_NAME);
+ }
+ options.addVariableConstraint(constraint);
+ }
+
+ if (index == length) break;
+ // fall through to append white space
+ ch = pattern.charAt(index);
+ }
+ }
+
+ buf.append(ch);
+ }
+
+ options.setSearchPattern( buf.toString() );
+ }
+
+ private static int eatTypedVarCondition(int index,
+ String pattern,
+ StringBuilder miscBuffer,
+ MatchVariableConstraint constraint) {
+ final int length = pattern.length();
+
+ char ch = pattern.charAt(index);
+ if (ch == '+' || ch == '*') {
+ // this is type axis navigation relation
+ switch(ch) {
+ case '+':
+ constraint.setStrictlyWithinHierarchy(true);
+ break;
+ case '*':
+ constraint.setWithinHierarchy(true);
+ break;
+ }
+
+ ++index;
+ if (index >= length) throw new MalformedPatternException(SSRBundle.message("error.expected.condition", ch));
+ ch = pattern.charAt(index);
+ }
+
+ if (ch == '[') {
+ // eat complete condition
+
+ miscBuffer.setLength(0);
+ for(++index; index < length && ((ch = pattern.charAt(index))!=']' || pattern.charAt(index-1)=='\\'); ++index) {
+ miscBuffer.append(ch);
+ }
+ if (ch != ']') throw new MalformedPatternException(SSRBundle.message("error.expected.condition.or.bracket"));
+ ++index;
+ parseCondition(constraint, miscBuffer.toString());
+ } else {
+ // eat reg exp constraint
+ miscBuffer.setLength(0);
+ index = handleRegExp(index, pattern, miscBuffer, constraint);
+ }
+ return index;
+ }
+
+ private static int handleRegExp(int index,
+ String pattern,
+ StringBuilder miscBuffer,
+ MatchVariableConstraint constraint) {
+ char c = pattern.charAt(index - 1);
+ final int length = pattern.length();
+ for(char ch; index < length && !Character.isWhitespace(ch = pattern.charAt(index)); ++index) {
+ miscBuffer.append(ch);
+ }
+
+ if (miscBuffer.length() == 0)
+ if (c == ':') throw new MalformedPatternException(SSRBundle.message("error.expected.condition", c));
+ else return index;
+ String regexp = miscBuffer.toString();
+
+ if (constraint.getRegExp()!=null &&
+ constraint.getRegExp().length() > 0 &&
+ !constraint.getRegExp().equals(regexp)) {
+ throw new MalformedPatternException(SSRBundle.message("error.two.different.type.constraints"));
+ } else {
+ try {
+ Pattern.compile(regexp);
+ } catch (PatternSyntaxException e) {
+ throw new MalformedPatternException(SSRBundle.message("invalid.regular.expression"));
+ }
+ constraint.setRegExp(regexp);
+ }
+
+ return index;
+ }
+
+ private static void parseCondition(MatchVariableConstraint constraint, String condition) {
+ if (condition.isEmpty()) throw new MalformedPatternException(SSRBundle.message("error.expected.condition", "["));
+ final List<String> tokens = StringUtil.split(condition, "&&", true, false);
+
+ for (String token : tokens) {
+ token = token.trim();
+ if (token.isEmpty()) throw new MalformedPatternException(SSRBundle.message("error.expected.condition", "&&"));
+ boolean hasNot = false;
+ boolean consumed = false;
+
+ if (StringUtil.startsWithChar(token, '!')) {
+ token = token.substring(1);
+ if (token.isEmpty()) throw new MalformedPatternException(SSRBundle.message("error.expected.condition", "!"));
+ hasNot = true;
+ }
+
+ Matcher m = p.matcher(token);
+
+ if (m.matches()) {
+ String option = m.group(1);
+
+ if (option.equalsIgnoreCase(REF)) {
+ String name = m.group(2);
+
+ constraint.setReference(true);
+ constraint.setInvertReference(hasNot);
+ constraint.setNameOfReferenceVar(name);
+ consumed = true;
+ }
+ } else {
+ m = p2.matcher(token);
+
+ if (m.matches()) {
+ String option = m.group(1);
+
+ if (option.equalsIgnoreCase(READ)) {
+ constraint.setReadAccess(true);
+ constraint.setInvertReadAccess(hasNot);
+ consumed = true;
+ } else if (option.equalsIgnoreCase(WRITE)) {
+ constraint.setWriteAccess(true);
+ constraint.setInvertWriteAccess(hasNot);
+ consumed = true;
+ }
+ } else {
+ m = p3.matcher(token);
+
+ if (m.matches()) {
+ String option = m.group(1);
+
+ if (option.equalsIgnoreCase(REGEX) || option.equalsIgnoreCase(REGEXW)) {
+ String typePattern = getSingleParameter(m, SSRBundle.message("reg.exp.should.be.delimited.with.spaces.error.message"));
+ if (typePattern.isEmpty()) throw new MalformedPatternException(SSRBundle.message("no.reg.exp.specified.error.message"));
+
+ if (StringUtil.startsWithChar(typePattern, '*')) {
+ typePattern = typePattern.substring(1);
+ constraint.setWithinHierarchy(true);
+ }
+ try {
+ Pattern.compile(typePattern);
+ } catch (PatternSyntaxException e) {
+ throw new MalformedPatternException(SSRBundle.message("invalid.regular.expression"));
+ }
+ constraint.setRegExp( typePattern );
+ constraint.setInvertRegExp( hasNot );
+ consumed = true;
+ if (option.equalsIgnoreCase(REGEXW)) {
+ constraint.setWholeWordsOnly(true);
+ }
+ } else if (option.equalsIgnoreCase(EXPRTYPE)) {
+ String exprTypePattern = getSingleParameter(m, SSRBundle.message(
+ "reg.exp.in.expr.type.should.be.delimited.with.spaces.error.message"));
+
+ if (StringUtil.startsWithChar(exprTypePattern, '*')) {
+ exprTypePattern = exprTypePattern.substring(1);
+ constraint.setExprTypeWithinHierarchy(true);
+ }
+ try {
+ Pattern.compile(exprTypePattern);
+ } catch (PatternSyntaxException e) {
+ throw new MalformedPatternException(SSRBundle.message("invalid.regular.expression"));
+ }
+ constraint.setNameOfExprType( exprTypePattern );
+ constraint.setInvertExprType( hasNot );
+ consumed = true;
+ } else if (option.equalsIgnoreCase(FORMAL)) {
+ String exprTypePattern = getSingleParameter(m, SSRBundle.message(
+ "reg.exp.in.formal.arg.type.should.be.delimited.with.spaces.error.message"));
+
+ if (StringUtil.startsWithChar(exprTypePattern, '*')) {
+ exprTypePattern = exprTypePattern.substring(1);
+ constraint.setFormalArgTypeWithinHierarchy(true);
+ }
+ try {
+ Pattern.compile(exprTypePattern);
+ } catch (PatternSyntaxException e) {
+ throw new MalformedPatternException(SSRBundle.message("invalid.regular.expression"));
+ }
+ constraint.setNameOfFormalArgType( exprTypePattern );
+ constraint.setInvertFormalType( hasNot );
+ consumed = true;
+ } else if (option.equalsIgnoreCase(SCRIPT)) {
+ String script = getSingleParameter(m, SSRBundle.message("script.should.be.delimited.with.spaces.error.message"));
+
+ constraint.setScriptCodeConstraint( script );
+ consumed = true;
+ } else if (option.equalsIgnoreCase(CONTAINS)) {
+ if (hasNot) constraint.setInvertContainsConstraint(true);
+ String script = getSingleParameter(m, SSRBundle.message("script.should.be.delimited.with.spaces.error.message"));
+
+ constraint.setContainsConstraint(script );
+ consumed = true;
+ } else if (option.equalsIgnoreCase(WITHIN)) {
+ if (hasNot) constraint.setInvertWithinConstraint(true);
+ String script = getSingleParameter(m, SSRBundle.message("script.should.be.delimited.with.spaces.error.message"));
+
+ constraint.setWithinConstraint(script);
+ consumed = true;
+ }
+ }
+ }
+ }
+
+ if (!consumed) {
+ throw new UnsupportedPatternException(
+ SSRBundle.message("option.is.not.recognized.error.message", token)
+ );
+ }
+ }
+ }
+
+ private static String getSingleParameter(Matcher m, String errorMessage) {
+ final String value = m.group(2);
+ if (value.isEmpty()) return value;
+
+ if (value.charAt(0)!=' ' || value.charAt(value.length()-1)!=' ') {
+ throw new MalformedPatternException(errorMessage);
+ }
+ return value.trim();
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/TestModeOptimizingSearchHelper.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/TestModeOptimizingSearchHelper.java
new file mode 100644
index 000000000000..e341b57da8ce
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/TestModeOptimizingSearchHelper.java
@@ -0,0 +1,70 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.psi.PsiFile;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class TestModeOptimizingSearchHelper extends OptimizingSearchHelperBase {
+ private static String lastString;
+ private final StringBuilder builder = new StringBuilder();
+ private int lastLength;
+
+ TestModeOptimizingSearchHelper(CompileContext _context) {
+ super(_context);
+ }
+
+ public boolean doOptimizing() {
+ return true;
+ }
+
+ public void clear() {
+ lastString = builder.toString();
+ builder.setLength(0);
+ lastLength = 0;
+ }
+
+ protected void doAddSearchWordInCode(final String refname) {
+ append(refname, "reserved in code:");
+ }
+
+ @Override
+ protected void doAddSearchWordInText(String refname) {
+ append(refname, "in text:");
+ }
+
+ private void append(final String refname, final String str) {
+ if (builder.length() == lastLength) builder.append("[");
+ else builder.append("|");
+ builder.append(str).append(refname);
+ }
+
+ protected void doAddSearchWordInComments(final String refname) {
+ append(refname, "in comments:");
+ }
+
+ protected void doAddSearchWordInLiterals(final String refname) {
+ append(refname, "in literals:");
+ }
+
+ public void endTransaction() {
+ super.endTransaction();
+ builder.append("]");
+ lastLength = builder.length();
+ }
+
+ public boolean isScannedSomething() {
+ return false;
+ }
+
+ public Set<PsiFile> getFilesSetToScan() {
+ return Collections.emptySet();
+ }
+
+ public String getSearchPlan() {
+ return lastString;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/XmlCompilingVisitor.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/XmlCompilingVisitor.java
new file mode 100644
index 000000000000..99917ad23240
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/XmlCompilingVisitor.java
@@ -0,0 +1,53 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.XmlRecursiveElementVisitor;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.psi.xml.XmlText;
+import com.intellij.psi.xml.XmlToken;
+import com.intellij.structuralsearch.impl.matcher.filters.TagValueFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.XmlTextHandler;
+import com.intellij.structuralsearch.impl.matcher.strategies.XmlMatchingStrategy;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class XmlCompilingVisitor extends XmlRecursiveElementVisitor {
+ private final GlobalCompilingVisitor myCompilingVisitor;
+
+ public XmlCompilingVisitor(GlobalCompilingVisitor compilingVisitor) {
+ this.myCompilingVisitor = compilingVisitor;
+ }
+
+ @Override public void visitElement(PsiElement element) {
+ myCompilingVisitor.handle(element);
+ super.visitElement(element);
+ }
+
+ @Override public void visitXmlToken(XmlToken token) {
+ super.visitXmlToken(token);
+
+ if (token.getParent() instanceof XmlText && myCompilingVisitor.getContext().getPattern().isRealTypedVar(token)) {
+ final MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(token);
+ handler.setFilter(TagValueFilter.getInstance());
+
+ final XmlTextHandler parentHandler = new XmlTextHandler();
+ myCompilingVisitor.getContext().getPattern().setHandler(token.getParent(), parentHandler);
+ parentHandler.setFilter(TagValueFilter.getInstance());
+ }
+ }
+
+ @Override public void visitXmlTag(XmlTag xmlTag) {
+ myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() + 1);
+ super.visitXmlTag(xmlTag);
+ myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() - 1);
+
+ if (myCompilingVisitor.getCodeBlockLevel() == 1) {
+ myCompilingVisitor.getContext().getPattern().setStrategy(XmlMatchingStrategy.getInstance());
+ myCompilingVisitor.getContext().getPattern()
+ .setHandler(xmlTag, new TopLevelMatchingHandler(myCompilingVisitor.getContext().getPattern().getHandler(xmlTag)));
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/CompositeFilter.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/CompositeFilter.java
new file mode 100644
index 000000000000..db962ed8edf1
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/CompositeFilter.java
@@ -0,0 +1,27 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 28.12.2003
+ * Time: 0:13:19
+ * To change this template use Options | File Templates.
+ */
+public class CompositeFilter implements NodeFilter {
+ private final NodeFilter first;
+ private final NodeFilter second;
+ protected boolean result;
+
+ public boolean accepts(PsiElement element) {
+ return first.accepts(element) ||
+ second.accepts(element);
+ }
+
+ public CompositeFilter(NodeFilter _first, NodeFilter _second) {
+ first = _first;
+ second = _second;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/DefaultFilter.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/DefaultFilter.java
new file mode 100644
index 000000000000..267f37699945
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/DefaultFilter.java
@@ -0,0 +1,16 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.tree.LeafElement;
+
+/**
+ * Default searching filter
+ */
+public class DefaultFilter {
+ public static boolean accepts(PsiElement element, PsiElement element2) {
+ if (element instanceof LeafElement && element2 instanceof LeafElement) {
+ return ((LeafElement)element).getElementType() == ((LeafElement)element2).getElementType();
+ }
+ return element.getClass()==element2.getClass();
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/LexicalNodesFilter.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/LexicalNodesFilter.java
new file mode 100644
index 000000000000..3cef402b09d3
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/LexicalNodesFilter.java
@@ -0,0 +1,51 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+
+/**
+ * Filter for lexical nodes
+ */
+public final class LexicalNodesFilter implements NodeFilter {
+ private boolean careKeyWords;
+ private boolean result;
+
+ private LexicalNodesFilter() {}
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ public boolean getResult() {
+ return result;
+ }
+
+ public void setResult(boolean result) {
+ this.result = result;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new LexicalNodesFilter();
+ }
+
+ public boolean isCareKeyWords() {
+ return careKeyWords;
+ }
+
+ public void setCareKeyWords(boolean careKeyWords) {
+ this.careKeyWords = careKeyWords;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) {
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
+ if (profile != null) {
+ element.accept(profile.getLexicalNodesFilter(this));
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/TagValueFilter.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/TagValueFilter.java
new file mode 100644
index 000000000000..97ed9627e3fc
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/TagValueFilter.java
@@ -0,0 +1,43 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.XmlElementVisitor;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.psi.xml.XmlText;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim.mossienko
+ * Date: Oct 12, 2005
+ * Time: 4:44:19 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TagValueFilter extends XmlElementVisitor implements NodeFilter {
+ private boolean result;
+
+ @Override public void visitXmlText(XmlText text) {
+ result = true;
+ }
+
+ @Override public void visitXmlTag(XmlTag tag) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new TagValueFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private TagValueFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/XmlLexicalNodesFilter.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/XmlLexicalNodesFilter.java
new file mode 100644
index 000000000000..89c295ce1d80
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/filters/XmlLexicalNodesFilter.java
@@ -0,0 +1,19 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.psi.XmlElementVisitor;
+import com.intellij.psi.xml.XmlText;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class XmlLexicalNodesFilter extends XmlElementVisitor {
+ private final LexicalNodesFilter myLexicalNodesFilter;
+
+ public XmlLexicalNodesFilter(LexicalNodesFilter lexicalNodesFilter) {
+ this.myLexicalNodesFilter = lexicalNodesFilter;
+ }
+
+ @Override public void visitXmlText(XmlText text) {
+ myLexicalNodesFilter.setResult(true);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/DelegatingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/DelegatingHandler.java
new file mode 100644
index 000000000000..c95a85623753
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/DelegatingHandler.java
@@ -0,0 +1,8 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface DelegatingHandler {
+ MatchingHandler getDelegate();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LightTopLevelMatchingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LightTopLevelMatchingHandler.java
new file mode 100644
index 000000000000..34941cfa0257
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LightTopLevelMatchingHandler.java
@@ -0,0 +1,46 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import org.jetbrains.annotations.NotNull;
+
+public final class LightTopLevelMatchingHandler extends MatchingHandler implements DelegatingHandler {
+ private final MatchingHandler myDelegate;
+
+ public LightTopLevelMatchingHandler(@NotNull MatchingHandler delegate) {
+ myDelegate = delegate;
+ }
+
+ public boolean match(final PsiElement patternNode, final PsiElement matchedNode, final MatchContext matchContext) {
+ return myDelegate.match(patternNode, matchedNode, matchContext);
+ }
+
+ @Override
+ public boolean canMatch(PsiElement patternNode, PsiElement matchedNode) {
+ return myDelegate.canMatch(patternNode, matchedNode);
+ }
+
+ @Override
+ public boolean matchSequentially(final NodeIterator nodes, final NodeIterator nodes2, final MatchContext context) {
+ return myDelegate.matchSequentially(nodes, nodes2, context);
+ }
+
+ public boolean match(final PsiElement patternNode,
+ final PsiElement matchedNode, final int start, final int end, final MatchContext context) {
+ return myDelegate.match(patternNode, matchedNode, start, end, context);
+ }
+
+ public boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
+ return true;
+ }
+
+ @Override
+ public boolean shouldAdvanceTheMatchFor(final PsiElement patternElement, final PsiElement matchedElement) {
+ return myDelegate.shouldAdvanceTheMatchFor(patternElement, matchedElement);
+ }
+
+ public MatchingHandler getDelegate() {
+ return myDelegate;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LiteralWithSubstitutionHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LiteralWithSubstitutionHandler.java
new file mode 100644
index 000000000000..78967106755f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/LiteralWithSubstitutionHandler.java
@@ -0,0 +1,49 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Jun 30, 2004
+ * Time: 5:07:33 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class LiteralWithSubstitutionHandler extends MatchingHandler {
+ private final String matchExpression;
+ private Matcher matcher;
+ private final List<SubstitutionHandler> handlers;
+
+ public LiteralWithSubstitutionHandler(String _matchedExpression,List<SubstitutionHandler> _handlers) {
+ matchExpression = _matchedExpression;
+ handlers = _handlers;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ final String text = RegExpPredicate.getMeaningfulText(matchedNode);
+ int offset = matchedNode.getText().indexOf(text);
+ if (matcher==null) {
+ matcher = Pattern.compile(matchExpression).matcher(text);
+ } else {
+ matcher.reset(text);
+ }
+
+ while (matcher.find()) {
+ for (int i = 0; i < handlers.size(); ++i) {
+ SubstitutionHandler handler = handlers.get(i);
+
+ if (!handler.handle(matchedNode,offset + matcher.start(i+1), offset + matcher.end(i+1),context)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchPredicate.java
new file mode 100644
index 000000000000..cba96681ab71
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchPredicate.java
@@ -0,0 +1,27 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Root of handlers for pattern node matching. Handles simpliest type of the match.
+ */
+public abstract class MatchPredicate {
+ /**
+ * Matches given handler node against given value.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successfull and false otherwise
+ */
+ public boolean match(PsiElement patternNode,PsiElement matchedNode, int start, int end, MatchContext context) {
+ return match(patternNode,matchedNode,context);
+ }
+
+ /**
+ * Matches given handler node against given value.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successfull and false otherwise
+ */
+ public abstract boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context);
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchingHandler.java
new file mode 100644
index 000000000000..c53b08412b6b
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/MatchingHandler.java
@@ -0,0 +1,271 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import com.intellij.structuralsearch.impl.matcher.filters.DefaultFilter;
+import com.intellij.structuralsearch.impl.matcher.predicates.BinaryPredicate;
+import com.intellij.structuralsearch.impl.matcher.predicates.NotPredicate;
+import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
+import com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Root of handlers for pattern node matching. Handles simplest type of the match.
+ */
+public abstract class MatchingHandler extends MatchPredicate {
+ protected NodeFilter filter;
+ private PsiElement pinnedElement;
+
+ public void setFilter(NodeFilter filter) {
+ this.filter = filter;
+ }
+
+ /**
+ * Matches given handler node against given value.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successful and false otherwise
+ */
+ public boolean match(PsiElement patternNode,PsiElement matchedNode, int start, int end, MatchContext context) {
+ return match(patternNode,matchedNode,context);
+ }
+
+ /**
+ * Matches given handler node against given value.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successful and false otherwise
+ */
+ public boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context) {
+ if (patternNode == null) {
+ return matchedNode == null;
+ }
+
+ return canMatch(patternNode, matchedNode);
+ }
+
+ public boolean canMatch(final PsiElement patternNode, final PsiElement matchedNode) {
+ if (filter!=null) {
+ return filter.accepts(matchedNode);
+ } else {
+ return DefaultFilter.accepts(patternNode, matchedNode);
+ }
+ }
+
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ PsiElement patternElement;
+ MatchingHandler handler;
+ MatchingStrategy strategy = context.getPattern().getStrategy();
+
+ skipIfNecessary(nodes, nodes2, strategy);
+ skipIfNecessary(nodes2, nodes, strategy);
+
+ if (nodes2.hasNext() &&
+ (handler = context.getPattern().getHandler(nodes.current())).match(patternElement = nodes.current(),nodes2.current(),context)) {
+
+ nodes.advance();
+
+ if (shouldAdvanceTheMatchFor(patternElement, nodes2.current())) {
+ nodes2.advance();
+ skipIfNecessary(nodes, nodes2, strategy);
+ }
+ skipIfNecessary(nodes2, nodes, strategy);
+
+ if (nodes.hasNext()) {
+ final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
+
+ if (nextHandler.matchSequentially(nodes,nodes2,context)) {
+ // match was found!
+ return true;
+ } else {
+ // rewind, we was not able to match descendants
+ nodes.rewind();
+ nodes2.rewind();
+ }
+ } else {
+ // match was found
+ return handler.isMatchSequentiallySucceeded(nodes2);
+ }
+ }
+ return false;
+ }
+
+ private static void skipIfNecessary(NodeIterator nodes, NodeIterator nodes2, MatchingStrategy strategy) {
+ while (strategy.shouldSkip(nodes2.current(), nodes.current())) {
+ nodes2.advance();
+ }
+ }
+
+ protected boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
+ return !nodes2.hasNext();
+ }
+
+ private static MatchPredicate findRegExpPredicate(MatchPredicate start) {
+ if (start==null) return null;
+ if (start instanceof RegExpPredicate) return start;
+
+ if(start instanceof BinaryPredicate) {
+ BinaryPredicate binary = (BinaryPredicate)start;
+ final MatchPredicate result = findRegExpPredicate(binary.getFirst());
+ if (result!=null) return result;
+
+ return findRegExpPredicate(binary.getSecond());
+ } else if (start instanceof NotPredicate) {
+ return null;
+ }
+ return null;
+ }
+
+ public static RegExpPredicate getSimpleRegExpPredicate(SubstitutionHandler handler) {
+ if (handler == null) return null;
+ return (RegExpPredicate)findRegExpPredicate(handler.getPredicate());
+ }
+
+ static class ClearStateVisitor extends PsiRecursiveElementWalkingVisitor {
+ private CompiledPattern pattern;
+
+ ClearStateVisitor() {
+ super(true);
+ }
+
+ @Override public void visitElement(PsiElement element) {
+ // We do not reset certain handlers because they are also bound to higher level nodes
+ // e.g. Identifier handler in name is also bound to PsiMethod
+ if (pattern.isToResetHandler(element)) {
+ MatchingHandler handler = pattern.getHandlerSimple(element);
+ if (handler instanceof SubstitutionHandler) {
+ handler.reset();
+ }
+ }
+ super.visitElement(element);
+ }
+
+ synchronized void clearState(CompiledPattern _pattern, PsiElement el) {
+ pattern = _pattern;
+ el.acceptChildren(this);
+ pattern = null;
+ }
+ }
+
+ protected static ClearStateVisitor clearingVisitor = new ClearStateVisitor();
+
+ public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
+ final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
+ context.setResult(null);
+
+ try {
+
+ if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
+ return validateSatisfactionOfHandlers(patternNodes, context);
+ }
+
+ Set<PsiElement> matchedElements = null;
+
+ for(; patternNodes.hasNext(); patternNodes.advance()) {
+ final PsiElement patternNode = patternNodes.current();
+ final CompiledPattern pattern = context.getPattern();
+ final MatchingHandler handler = pattern.getHandler(patternNode);
+
+ final PsiElement startMatching = matchedNodes.current();
+ do {
+ final PsiElement element = handler.getPinnedNode(null);
+ final PsiElement matchedNode = element != null ? element : matchedNodes.current();
+
+ if (element == null) matchedNodes.advance();
+ if (!matchedNodes.hasNext()) matchedNodes.reset();
+
+ if (matchedElements == null || !matchedElements.contains(matchedNode)) {
+
+ if (handler.match(patternNode, matchedNode, context)) {
+ if (matchedElements == null) matchedElements = new HashSet<PsiElement>();
+ matchedElements.add(matchedNode);
+ if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
+ break;
+ }
+ } else if (element != null) {
+ return false;
+ }
+
+ // clear state of dependent objects
+ clearingVisitor.clearState(pattern, patternNode);
+ }
+
+ // passed of elements and does not found the match
+ if (startMatching == matchedNodes.current()) {
+ final boolean result = validateSatisfactionOfHandlers(patternNodes,context);
+ if (result && context.getMatchedElementsListener() != null) {
+ context.getMatchedElementsListener().matchedElements(matchedElements);
+ }
+ return result;
+ }
+ } while(true);
+
+ if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
+ patternNodes.rewind();
+ }
+ }
+
+ final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
+ if (result && context.getMatchedElementsListener() != null) {
+ context.getMatchedElementsListener().matchedElements(matchedElements);
+ }
+ return result;
+ } finally {
+ if (saveResult!=null) {
+ if (context.hasResult()) {
+ saveResult.getMatches().addAll(context.getResult().getMatches());
+ }
+ context.setResult(saveResult);
+ }
+ }
+ }
+
+ protected static boolean validateSatisfactionOfHandlers(NodeIterator nodes, MatchContext context) {
+ while(nodes.hasNext()) {
+ final PsiElement element = nodes.current();
+ final MatchingHandler handler = context.getPattern().getHandler( element );
+
+ if (handler instanceof SubstitutionHandler) {
+ if (!((SubstitutionHandler)handler).validate(
+ context, StructuralSearchUtil.getProfileByPsiElement(element).getElementContextByPsi(element))) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ nodes.advance();
+ }
+ return true;
+ }
+
+ public NodeFilter getFilter() {
+ return filter;
+ }
+
+ public boolean shouldAdvanceThePatternFor(PsiElement patternElement, PsiElement matchedElement) {
+ return true;
+ }
+
+ public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
+ return true;
+ }
+
+ public void reset() {
+ //pinnedElement = null;
+ }
+
+ public PsiElement getPinnedNode(PsiElement context) {
+ return pinnedElement;
+ }
+
+ public void setPinnedElement(final PsiElement pinnedElement) {
+ this.pinnedElement = pinnedElement;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SimpleHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SimpleHandler.java
new file mode 100644
index 000000000000..3dffe792e308
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SimpleHandler.java
@@ -0,0 +1,20 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Root of handlers for pattern node matching. Handles simpliest type of the match.
+ */
+public final class SimpleHandler extends MatchingHandler {
+ /**
+ * Matches given handler node against given value.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successfull and false otherwise
+ */
+ public boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context) {
+ if (!super.match(patternNode,matchedNode,context)) return false;
+ return context.getMatcher().match(patternNode,matchedNode);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java
new file mode 100644
index 000000000000..389c4a7916c2
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java
@@ -0,0 +1,108 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.util.DuplocatorUtil;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class SkippingHandler extends MatchingHandler implements DelegatingHandler {
+
+ private final MatchingHandler myDelegate;
+
+ public SkippingHandler(@NotNull MatchingHandler delegate) {
+ myDelegate = delegate;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, final MatchContext matchContext) {
+ if (patternNode == null || matchedNode == null || matchedNode.getClass() == patternNode.getClass()) {
+ return myDelegate.match(patternNode, matchedNode, matchContext);
+ }
+
+ /*if (patternNode != null && matchedNode != null && patternNode.getClass() == matchedNode.getClass()) {
+ //return myDelegate.match(patternNode, matchedNode, matchContext);
+ }*/
+ PsiElement newPatternNode = skipNodeIfNeccessary(patternNode);
+ matchedNode = skipNodeIfNeccessary(matchedNode);
+
+ if (newPatternNode != patternNode) {
+ return matchContext.getPattern().getHandler(newPatternNode).match(newPatternNode, matchedNode, matchContext);
+ }
+
+ return myDelegate.match(patternNode, matchedNode, matchContext);
+ }
+
+ @Override
+ public boolean canMatch(PsiElement patternNode, PsiElement matchedNode) {
+ return myDelegate.canMatch(patternNode, matchedNode);
+ }
+
+ @Override
+ public boolean matchSequentially(final NodeIterator nodes, final NodeIterator nodes2, final MatchContext context) {
+ return myDelegate.matchSequentially(nodes, nodes2, context);
+ }
+
+ public boolean match(PsiElement patternNode,
+ PsiElement matchedNode,
+ final int start,
+ final int end,
+ final MatchContext context) {
+ if (patternNode == null || matchedNode == null || patternNode.getClass() == matchedNode.getClass()) {
+ return myDelegate.match(patternNode, matchedNode, start, end, context);
+ }
+
+ PsiElement newPatternNode = skipNodeIfNeccessary(patternNode);
+ matchedNode = skipNodeIfNeccessary(matchedNode);
+
+ if (newPatternNode != patternNode) {
+ return context.getPattern().getHandler(newPatternNode).match(newPatternNode, matchedNode, start, end, context);
+ }
+
+ return myDelegate.match(patternNode, matchedNode, start, end, context);
+ }
+
+ protected boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
+ return myDelegate.isMatchSequentiallySucceeded(nodes2);
+ }
+
+ @Override
+ public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
+ return true;
+ }
+
+ public MatchingHandler getDelegate() {
+ return myDelegate;
+ }
+
+ @Nullable
+ public static PsiElement getOnlyNonWhitespaceChild(PsiElement element) {
+ PsiElement onlyChild = null;
+ for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
+ if (DuplocatorUtil.isIgnoredNode(element) || child.getTextLength() == 0) {
+ continue;
+ }
+ if (onlyChild != null) {
+ return null;
+ }
+ onlyChild = child;
+ }
+ return onlyChild;
+ }
+
+ @Nullable
+ public static PsiElement skipNodeIfNeccessary(PsiElement element) {
+ return skipNodeIfNeccessary(element, null, null);
+ }
+
+ @Nullable
+ public static PsiElement skipNodeIfNeccessary(PsiElement element, EquivalenceDescriptor descriptor, NodeFilter filter) {
+ return DuplocatorUtil.skipNodeIfNeccessary(element, descriptor, filter != null ? filter : LexicalNodesFilter.getInstance());
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java
new file mode 100644
index 000000000000..0c84e3bb2436
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SubstitutionHandler.java
@@ -0,0 +1,557 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Matching handler that manages substitutions matching
+ */
+public class SubstitutionHandler extends MatchingHandler {
+ private final String name;
+ private final int maxOccurs;
+ private final int minOccurs;
+ private final boolean greedy;
+ private boolean target;
+ private MatchPredicate predicate;
+ private MatchingHandler matchHandler;
+ private boolean subtype;
+ private boolean strictSubtype;
+ // matchedOccurs + 1 = number of item being matched
+ private int matchedOccurs;
+ private int totalMatchedOccurs = -1;
+ private MatchResultImpl myNestedResult;
+
+ private static final NodeFilter VARS_DELIM_FILTER = new NodeFilter() {
+ @Override
+ public boolean accepts(PsiElement element) {
+ if (element == null) {
+ return false;
+ }
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
+ if (profile == null) {
+ return false;
+ }
+
+ return profile.canBeVarDelimeter(element);
+ }
+ };
+
+ public SubstitutionHandler(final String name, final boolean target, int minOccurs,
+ int maxOccurs, boolean greedy) {
+ this.name = name;
+ this.maxOccurs = maxOccurs;
+ this.minOccurs = minOccurs;
+ this.target = target;
+ this.greedy = greedy;
+ }
+
+ public SubstitutionHandler(final SubstitutionHandler substitutionHandler) {
+ this(substitutionHandler.getName(),substitutionHandler.isTarget(), substitutionHandler.getMinOccurs(),
+ substitutionHandler.getMaxOccurs(), substitutionHandler.greedy);
+ }
+
+ public boolean isSubtype() {
+ return subtype;
+ }
+
+ public boolean isStrictSubtype() {
+ return strictSubtype;
+ }
+
+ public void setStrictSubtype(boolean strictSubtype) {
+ this.strictSubtype = strictSubtype;
+ }
+
+ public void setSubtype(boolean subtype) {
+ this.subtype = subtype;
+ }
+
+ public void setPredicate(MatchPredicate handler) {
+ predicate = handler;
+ }
+
+ // Matcher
+
+ public MatchPredicate getPredicate() {
+ return predicate;
+ }
+
+ private static boolean validateOneMatch(final PsiElement match, int start, int end, final MatchResultImpl result, final MatchContext matchContext) {
+ final boolean matchresult;
+
+ if (match!=null) {
+ if (start==0 && end==-1 && result.getStart()==0 && result.getEnd()==-1) {
+ matchresult = matchContext.getMatcher().match(match,result.getMatchRef().getElement());
+ } else {
+ matchresult = StructuralSearchUtil.getProfileByPsiElement(match).getText(match, start, end).equals(
+ result.getMatchImage()
+ );
+ }
+ } else {
+ matchresult = result.isMatchImageNull();
+ }
+
+ return matchresult;
+ }
+
+ public boolean validate(final PsiElement match, int start, int end, MatchContext context) {
+ if (predicate!=null) {
+ if(!predicate.match(null,match,start,end,context)) return false;
+ }
+
+ if (maxOccurs==0) {
+ totalMatchedOccurs++;
+ return false;
+ }
+
+ MatchResultImpl result = context.getResult().findSon(name);
+
+ if (result == null && context.getPreviousResult() != null) {
+ result = context.getPreviousResult().findSon(name);
+ }
+
+ if (result!=null) {
+ if (minOccurs == 1 && maxOccurs == 1) {
+ // check if they are the same
+ return validateOneMatch(match, start, end, result,context);
+ } else if (maxOccurs > 1 && totalMatchedOccurs!=-1) {
+ final int size = result.getAllSons().size();
+ if (matchedOccurs >= size) {
+ return false;
+ }
+ result = size == 0 ?result:(MatchResultImpl)result.getAllSons().get(matchedOccurs);
+ // check if they are the same
+ return validateOneMatch(match, start, end, result, context);
+ }
+ }
+
+ return true;
+ }
+
+ public boolean match(final PsiElement node, final PsiElement match, MatchContext context) {
+ if (!super.match(node,match,context)) return false;
+
+ return matchHandler == null ?
+ context.getMatcher().match(node, match):
+ matchHandler.match(node,match,context);
+ }
+
+ public boolean handle(final PsiElement match, MatchContext context) {
+ return handle(match,0,-1,context);
+ }
+
+ public void addResult(PsiElement match,int start, int end,MatchContext context) {
+ if (totalMatchedOccurs == -1) {
+ final MatchResultImpl matchResult = context.getResult();
+ final MatchResultImpl substitution = matchResult.findSon(name);
+
+ if (substitution == null) {
+ matchResult.addSon( createMatch(match,start,end) );
+ } else if (maxOccurs > 1) {
+ final MatchResultImpl result = createMatch(match,start,end);
+
+ if (!substitution.isMultipleMatch()) {
+ // adding intermediate node to contain all multiple matches
+ MatchResultImpl sonresult = new MatchResultImpl(
+ substitution.getName(),
+ substitution.getMatchImage(),
+ substitution.getMatchRef(),
+ substitution.getStart(),
+ substitution.getEnd(),
+ target
+ );
+
+ sonresult.setParent(substitution);
+ substitution.setMatchRef(
+ new SmartPsiPointer(match == null ? null : match)
+ );
+
+ substitution.setMultipleMatch(true);
+
+ if (substitution.isScopeMatch()) {
+ substitution.setScopeMatch(false);
+ sonresult.setScopeMatch(true);
+ for(MatchResult r:substitution.getAllSons()) sonresult.addSon((MatchResultImpl)r);
+ substitution.clearMatches();
+ }
+
+ substitution.addSon( sonresult);
+ }
+
+ result.setParent(substitution);
+ substitution.addSon( result );
+ }
+ }
+ }
+
+ public boolean handle(final PsiElement match, int start, int end, MatchContext context) {
+ if (!validate(match,start,end,context)) {
+ myNestedResult = null;
+
+ //if (maxOccurs==1 && minOccurs==1) {
+ // if (context.hasResult()) context.getResult().removeSon(name);
+ //}
+ // @todo we may fail fast the match by throwing an exception
+
+ return false;
+ }
+
+ if (!Configuration.CONTEXT_VAR_NAME.equals(name)) addResult(match, start, end, context);
+
+ return true;
+ }
+
+ private MatchResultImpl createMatch(final PsiElement match, int start, int end) {
+ final String image = match == null ? null : StructuralSearchUtil.getProfileByPsiElement(match).getText(match, start, end);
+ final SmartPsiPointer ref = new SmartPsiPointer(match);
+
+ final MatchResultImpl result = myNestedResult == null ? new MatchResultImpl(
+ name,
+ image,
+ ref,
+ start,
+ end,
+ target
+ ) : myNestedResult;
+
+ if (myNestedResult != null) {
+ myNestedResult.setName( name );
+ myNestedResult.setMatchImage( image );
+ myNestedResult.setMatchRef( ref );
+ myNestedResult.setStart( start );
+ myNestedResult.setEnd( end );
+ myNestedResult.setTarget( target );
+ myNestedResult = null;
+ }
+
+ return result;
+ }
+
+ boolean validate(MatchContext context, Class elementContext) {
+ MatchResult substitution = context.getResult().findSon(name);
+
+ if (minOccurs >= 1 &&
+ ( substitution == null ||
+ StructuralSearchUtil.getProfileByFileType(context.getOptions().getFileType()).getElementContextByPsi(substitution.getMatchRef().getElement()) != elementContext
+ )
+ ) {
+ return false;
+ } else if (maxOccurs <= 1 &&
+ substitution!=null && substitution.hasSons()
+ ) {
+ return false;
+ } else if (maxOccurs==0 && totalMatchedOccurs!=-1) {
+ return false;
+ }
+ return true;
+ }
+
+ public int getMinOccurs() {
+ return minOccurs;
+ }
+
+ public int getMaxOccurs() {
+ return maxOccurs;
+ }
+
+ private void removeLastResults(int numberOfResults, MatchContext context) {
+ if (numberOfResults == 0) return;
+ final MatchResultImpl substitution = context.getResult().findSon(name);
+
+ if (substitution!=null) {
+ final List<PsiElement> matchedNodes = context.getMatchedNodes();
+
+ if (substitution.hasSons()) {
+ final List<MatchResult> sons = substitution.getMatches();
+
+ while(numberOfResults > 0) {
+ --numberOfResults;
+ final MatchResult matchResult = sons.remove(sons.size() - 1);
+ if (matchedNodes != null) matchedNodes.remove(matchResult.getMatch());
+ }
+
+ if (sons.isEmpty()) {
+ context.getResult().removeSon(name);
+ }
+ } else {
+ final MatchResultImpl matchResult = context.getResult().removeSon(name);
+ if (matchedNodes != null) matchedNodes.remove(matchResult.getMatch());
+ }
+ }
+ }
+
+ public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
+ final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
+ context.setResult(null);
+
+ try {
+
+ if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
+ return validateSatisfactionOfHandlers(patternNodes, context);
+ }
+
+ Set<PsiElement> matchedElements = null;
+
+ for(; patternNodes.hasNext(); patternNodes.advance()) {
+ int matchedOccurs = 0;
+ final PsiElement patternNode = patternNodes.current();
+ final CompiledPattern pattern = context.getPattern();
+ final MatchingHandler handler = pattern.getHandler(patternNode);
+
+ final PsiElement startMatching = matchedNodes.current();
+ do {
+ final PsiElement element = handler.getPinnedNode(null);
+ final PsiElement matchedNode = (element != null) ? element : matchedNodes.current();
+
+ if (element == null) matchedNodes.advance();
+ if (!matchedNodes.hasNext()) matchedNodes.reset();
+
+ if (matchedOccurs <= maxOccurs &&
+ (matchedElements == null || !matchedElements.contains(matchedNode))) {
+
+ if (handler.match(patternNode, matchedNode, context)) {
+ ++matchedOccurs;
+ if (matchedElements == null) matchedElements = new HashSet<PsiElement>();
+ matchedElements.add(matchedNode);
+ if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
+ break;
+ }
+ } else if (element != null) {
+ return false;
+ }
+
+ // clear state of dependent objects
+ clearingVisitor.clearState(pattern, patternNode);
+ }
+
+ // passed of elements and does not found the match
+ if (startMatching == matchedNodes.current()) {
+ final boolean result = validateSatisfactionOfHandlers(patternNodes, context) &&
+ matchedOccurs >= minOccurs && matchedOccurs <= maxOccurs;
+ if (result && context.getMatchedElementsListener() != null) {
+ context.getMatchedElementsListener().matchedElements(matchedElements);
+ }
+ return result;
+ }
+ } while(true);
+
+ if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
+ patternNodes.rewind();
+ }
+ }
+
+ final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
+ if (result && context.getMatchedElementsListener() != null) {
+ context.getMatchedElementsListener().matchedElements(matchedElements);
+ }
+ return result;
+ } finally {
+ if (saveResult!=null) {
+ if (context.hasResult()) {
+ saveResult.getMatches().addAll(context.getResult().getMatches());
+ }
+ context.setResult(saveResult);
+ }
+ }
+ }
+
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ return doMatchSequentially(nodes, nodes2, context);
+ }
+
+ protected boolean doMatchSequentiallyBySimpleHandler(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ final boolean oldValue = context.shouldRecursivelyMatch();
+ context.setShouldRecursivelyMatch(false);
+ final boolean result = super.matchSequentially(nodes, nodes2, context);
+ context.setShouldRecursivelyMatch(oldValue);
+ return result;
+ }
+
+ protected boolean doMatchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ final int previousMatchedOccurs = matchedOccurs;
+
+ FilteringNodeIterator fNodes2 = new FilteringNodeIterator(nodes2, VARS_DELIM_FILTER);
+
+ try {
+ MatchingHandler handler = context.getPattern().getHandler(nodes.current());
+ matchedOccurs = 0;
+
+ boolean flag = false;
+
+ while(fNodes2.hasNext() && matchedOccurs < minOccurs) {
+ if (handler.match(nodes.current(), nodes2.current(), context)) {
+ ++matchedOccurs;
+ } else {
+ break;
+ }
+ fNodes2.advance();
+ flag = true;
+ }
+
+ if (matchedOccurs!=minOccurs) {
+ // failed even for min occurs
+ removeLastResults(matchedOccurs, context);
+ fNodes2.rewind(matchedOccurs);
+ return false;
+ }
+
+ if (greedy) {
+ // go greedily to maxOccurs
+
+ while(fNodes2.hasNext() && matchedOccurs < maxOccurs) {
+ if (handler.match(nodes.current(), nodes2.current(), context)) {
+ ++matchedOccurs;
+ } else {
+ // no more matches could take!
+ break;
+ }
+ fNodes2.advance();
+ flag = true;
+ }
+
+ if (flag) {
+ fNodes2.rewind();
+ nodes2.advance();
+ }
+
+ nodes.advance();
+
+ if (nodes.hasNext()) {
+ final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
+
+ while(matchedOccurs >= minOccurs) {
+ if (nextHandler.matchSequentially(nodes, nodes2, context)) {
+ totalMatchedOccurs = matchedOccurs;
+ // match found
+ return true;
+ }
+
+ if (matchedOccurs > 0) {
+ nodes2.rewind();
+ removeLastResults(1,context);
+ }
+ --matchedOccurs;
+ }
+
+ if (matchedOccurs > 0) {
+ removeLastResults(matchedOccurs, context);
+ }
+ nodes.rewind();
+ return false;
+ } else {
+ // match found
+ if (handler.isMatchSequentiallySucceeded(nodes2)) {
+ return checkSameOccurrencesConstraint();
+ }
+ removeLastResults(matchedOccurs, context);
+ return false;
+ }
+ } else {
+ nodes.advance();
+
+ if (flag) {
+ fNodes2.rewind();
+ nodes2.advance();
+ }
+
+ if (nodes.hasNext()) {
+ final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
+
+ flag = false;
+
+ while(nodes2.hasNext() && matchedOccurs <= maxOccurs) {
+ if (nextHandler.matchSequentially(nodes, nodes2, context)) {
+ return checkSameOccurrencesConstraint();
+ }
+
+ if (flag) {
+ nodes2.rewind();
+ fNodes2.advance();
+ }
+
+ if (handler.match(nodes.current(), nodes2.current(), context)) {
+ matchedOccurs++;
+ } else {
+ nodes.rewind();
+ removeLastResults(matchedOccurs,context);
+ return false;
+ }
+ nodes2.advance();
+ flag = true;
+ }
+
+ nodes.rewind();
+ removeLastResults(matchedOccurs,context);
+ return false;
+ } else {
+ return checkSameOccurrencesConstraint();
+ }
+ }
+ } finally {
+ matchedOccurs = previousMatchedOccurs;
+ }
+ }
+
+ private boolean checkSameOccurrencesConstraint() {
+ if (totalMatchedOccurs == -1) {
+ totalMatchedOccurs = matchedOccurs;
+ return true;
+ }
+ else {
+ return totalMatchedOccurs == matchedOccurs;
+ }
+ }
+
+ public void setTarget(boolean target) {
+ this.target = target;
+ }
+
+ public MatchingHandler getMatchHandler() {
+ return matchHandler;
+ }
+
+ public void setMatchHandler(MatchingHandler matchHandler) {
+ this.matchHandler = matchHandler;
+ }
+
+ public boolean isTarget() {
+ return target;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void reset() {
+ super.reset();
+ totalMatchedOccurs = -1;
+ }
+
+ public boolean shouldAdvanceThePatternFor(PsiElement patternElement, PsiElement matchedElement) {
+ if(maxOccurs > 1) return false;
+ return super.shouldAdvanceThePatternFor(patternElement,matchedElement);
+ }
+
+ public void setNestedResult(final MatchResultImpl nestedResult) {
+ myNestedResult = nestedResult;
+ }
+
+ public MatchResultImpl getNestedResult() {
+ return myNestedResult;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SymbolHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SymbolHandler.java
new file mode 100644
index 000000000000..4d1f9a852940
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SymbolHandler.java
@@ -0,0 +1,21 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Search handler for symbol search
+ */
+public class SymbolHandler extends MatchingHandler {
+ private final SubstitutionHandler handler;
+
+ public SymbolHandler(SubstitutionHandler handler) {
+ this.handler = handler;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ // there is no need to do filtering since this is delegate of Substituion handler
+
+ return handler.handle(matchedNode,context);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java
new file mode 100644
index 000000000000..6711bcb1fc7f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java
@@ -0,0 +1,85 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TopLevelMatchingHandler extends MatchingHandler implements DelegatingHandler {
+ private final MatchingHandler delegate;
+
+ public TopLevelMatchingHandler(@NotNull MatchingHandler _delegate) {
+ delegate = _delegate;
+ setFilter(_delegate.getFilter());
+ }
+
+ public boolean match(final PsiElement patternNode, final PsiElement matchedNode, final MatchContext matchContext) {
+ final boolean matched = delegate.match(patternNode, matchedNode, matchContext);
+
+ if (matched) {
+ List<PsiElement> matchedNodes = matchContext.getMatchedNodes();
+ if (matchedNodes == null) {
+ matchedNodes = new ArrayList<PsiElement>();
+ matchContext.setMatchedNodes(matchedNodes);
+ }
+
+ PsiElement elementToAdd = matchedNode;
+
+ if (patternNode instanceof PsiComment && StructuralSearchUtil.isDocCommentOwner(matchedNode)) {
+ // psicomment and psidoccomment are placed inside the psimember next to them so
+ // simple topdown matching should do additional "dances" to cover this case.
+ elementToAdd = matchedNode.getFirstChild();
+ assert elementToAdd instanceof PsiComment;
+ }
+
+ matchedNodes.add(elementToAdd);
+ }
+
+ if ((!matched || matchContext.getOptions().isRecursiveSearch()) &&
+ matchContext.getPattern().getStrategy().continueMatching(matchedNode) &&
+ matchContext.shouldRecursivelyMatch()
+ ) {
+ matchContext.getMatcher().matchContext(
+ new SsrFilteringNodeIterator(
+ new SiblingNodeIterator(matchedNode.getFirstChild())
+ )
+ );
+ }
+ return matched;
+ }
+
+ @Override
+ public boolean canMatch(PsiElement patternNode, PsiElement matchedNode) {
+ return delegate.canMatch(patternNode, matchedNode);
+ }
+
+ @Override
+ public boolean matchSequentially(final NodeIterator nodes, final NodeIterator nodes2, final MatchContext context) {
+ return delegate.matchSequentially(nodes, nodes2, context);
+ }
+
+ public boolean match(final PsiElement patternNode,
+ final PsiElement matchedNode, final int start, final int end, final MatchContext context) {
+ return match(patternNode, matchedNode, context);
+ }
+
+ public boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
+ return true;
+ }
+
+ @Override
+ public boolean shouldAdvanceTheMatchFor(final PsiElement patternElement, final PsiElement matchedElement) {
+ return delegate.shouldAdvanceTheMatchFor(patternElement, matchedElement);
+ }
+
+ public MatchingHandler getDelegate() {
+ return delegate;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TypedSymbolHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TypedSymbolHandler.java
new file mode 100644
index 000000000000..08e335614d5a
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TypedSymbolHandler.java
@@ -0,0 +1,21 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiDeclarationStatement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Search handler for typed symbol ('T<a*>)
+ */
+public class TypedSymbolHandler extends MatchingHandler {
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ if (!super.match(patternNode,matchedNode,context)) {
+ return false;
+ }
+
+ return context.getMatcher().match(
+ patternNode.getFirstChild(),
+ matchedNode
+ );
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/XmlTextHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/XmlTextHandler.java
new file mode 100644
index 000000000000..cc71c02ee403
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/XmlTextHandler.java
@@ -0,0 +1,23 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+
+/**
+ * Root of handlers for pattern node matching. Handles simpliest type of the match.
+ */
+public final class XmlTextHandler extends MatchingHandler {
+ public boolean matchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
+ final PsiElement psiElement = nodes.current();
+
+ return GlobalMatchingVisitor.continueMatchingSequentially(
+ new SsrFilteringNodeIterator( new ArrayBackedNodeIterator(psiElement.getChildren()) ),
+ nodes2,
+ context
+ );
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/iterators/SsrFilteringNodeIterator.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/iterators/SsrFilteringNodeIterator.java
new file mode 100644
index 000000000000..a2b14ae83e17
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/iterators/SsrFilteringNodeIterator.java
@@ -0,0 +1,20 @@
+package com.intellij.structuralsearch.impl.matcher.iterators;
+
+import com.intellij.dupLocator.iterators.FilteringNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class SsrFilteringNodeIterator extends FilteringNodeIterator {
+ public SsrFilteringNodeIterator(final NodeIterator iterator) {
+ super(iterator, LexicalNodesFilter.getInstance());
+ }
+
+ public SsrFilteringNodeIterator(final PsiElement element) {
+ this(new SiblingNodeIterator(element));
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/AbstractStringBasedPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/AbstractStringBasedPredicate.java
new file mode 100644
index 000000000000..916fc1e15639
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/AbstractStringBasedPredicate.java
@@ -0,0 +1,22 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class AbstractStringBasedPredicate extends MatchPredicate {
+ protected final String myName;
+ protected final String myWithin;
+
+ public AbstractStringBasedPredicate(String name, String within) {
+ myName = name;
+ myWithin = within;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ return match(patternNode, matchedNode, 0, -1, context);
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/BinaryPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/BinaryPredicate.java
new file mode 100644
index 000000000000..b7d5432964d4
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/BinaryPredicate.java
@@ -0,0 +1,38 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Binary predicate
+ */
+public final class BinaryPredicate extends MatchPredicate {
+ private final MatchPredicate first;
+ private final MatchPredicate second;
+ private final boolean or;
+
+ public BinaryPredicate(MatchPredicate first, MatchPredicate second, boolean or) {
+ this.first = first;
+ this.second = second;
+ this.or = or;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ if (or) {
+ return first.match(patternNode,matchedNode,context) ||
+ second.match(patternNode,matchedNode,context);
+ } else {
+ return first.match(patternNode,matchedNode,context) &&
+ second.match(patternNode,matchedNode,context);
+ }
+ }
+
+ public MatchPredicate getFirst() {
+ return first;
+ }
+
+ public MatchPredicate getSecond() {
+ return second;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ContainsPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ContainsPredicate.java
new file mode 100644
index 000000000000..2ed894fe6b64
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ContainsPredicate.java
@@ -0,0 +1,18 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class ContainsPredicate extends AbstractStringBasedPredicate {
+
+ public ContainsPredicate(String name, String within) {
+ super(name, within);
+ }
+
+ public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/NotPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/NotPredicate.java
new file mode 100644
index 000000000000..3d28a635e3af
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/NotPredicate.java
@@ -0,0 +1,24 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+
+/**
+ * Negates predicate
+ */
+public final class NotPredicate extends MatchPredicate {
+ private final MatchPredicate handler;
+
+ public NotPredicate(final MatchPredicate _handler) {
+ handler = _handler;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ return !handler.match(patternNode,matchedNode,context);
+ }
+
+ public MatchPredicate getHandler() {
+ return handler;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ReferencePredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ReferencePredicate.java
new file mode 100644
index 000000000000..17570ed8f5df
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ReferencePredicate.java
@@ -0,0 +1,31 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+
+/**
+ * Handles finding method
+ */
+public final class ReferencePredicate extends SubstitutionHandler {
+ public ReferencePredicate(String _name) {
+ super(_name, true, 1, 1, true);
+ }
+
+ public boolean match(PsiElement node, PsiElement match, MatchContext context) {
+ if (StructuralSearchUtil.isIdentifier(match)) {
+ // since we pickup tokens
+ match = match.getParent();
+ }
+
+ PsiElement result = MatchUtils.getReferencedElement(match);
+ if (result == null) {
+ result = match;
+ //return false;
+ }
+
+ return handle(result,context);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/RegExpPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/RegExpPredicate.java
new file mode 100644
index 000000000000..f7b8ecedcf3d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/RegExpPredicate.java
@@ -0,0 +1,175 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.MalformedPatternException;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Root of handlers for pattern node matching. Handles simpliest type of the match.
+ */
+public final class RegExpPredicate extends MatchPredicate {
+ private Pattern pattern;
+ private final String baseHandlerName;
+ private boolean simpleString;
+ private final boolean couldBeOptimized;
+ private final String regexp;
+ private final boolean caseSensitive;
+ private boolean multiline;
+ private final boolean wholeWords;
+ private final boolean target;
+ private NodeTextGenerator myNodeTextGenerator;
+
+ public interface NodeTextGenerator {
+ String getText(PsiElement element);
+ }
+
+ public RegExpPredicate(final String regexp, final boolean caseSensitive, final String _baseHandlerName, boolean _wholeWords, boolean _target) {
+ couldBeOptimized = containsRegExp(regexp);
+ if (!_wholeWords) {
+ simpleString = couldBeOptimized;
+ }
+
+ this.regexp = regexp;
+ this.caseSensitive = caseSensitive;
+ this.wholeWords = _wholeWords;
+ baseHandlerName = _baseHandlerName;
+
+ if (!simpleString) {
+ compilePattern();
+ }
+ target = _target;
+ }
+
+ private static boolean containsRegExp(final String regexp) {
+ for(int i=0;i<regexp.length();++i) {
+ if(MatchUtils.SPECIAL_CHARS.indexOf(regexp.charAt(i))!=-1) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private void compilePattern() {
+ try {
+ @NonNls String realRegexp = regexp;
+ if (wholeWords) {
+ realRegexp = ".*?\\b(?:" + realRegexp + ")\\b.*?";
+ }
+
+ pattern = Pattern.compile(
+ realRegexp,
+ (caseSensitive ? 0: Pattern.CASE_INSENSITIVE) | (multiline ? Pattern.DOTALL:0)
+ );
+ } catch(PatternSyntaxException ex) {
+ throw new MalformedPatternException(SSRBundle.message("error.incorrect.regexp.constraint", regexp, baseHandlerName));
+ }
+ }
+
+ public boolean couldBeOptimized() {
+ return couldBeOptimized;
+ }
+
+ public String getRegExp() {
+ return regexp;
+ }
+
+ /**
+ * Attempts to match given handler node against given node.
+ * @param matchedNode for matching
+ * @param context of the matching
+ * @return true if matching was successfull and false otherwise
+ */
+ public boolean match(PsiElement node,PsiElement matchedNode, int start, int end, MatchContext context) {
+ if (matchedNode==null) return false;
+ String text;
+
+ text = myNodeTextGenerator != null ? myNodeTextGenerator.getText(matchedNode) : getMeaningfulText(matchedNode);
+
+ boolean result = doMatch(text, start, end, context, matchedNode);
+
+ if (!result) {
+
+ if(StructuralSearchUtil.isIdentifier(matchedNode)) {
+ matchedNode = matchedNode.getParent();
+ }
+
+ String alternativeText = context.getPattern().getAlternativeTextToMatch(matchedNode, text);
+ if (alternativeText != null) {
+ result = doMatch(alternativeText, start, end, context, matchedNode);
+ }
+ }
+
+ return result;
+ }
+
+ public static String getMeaningfulText(PsiElement matchedNode) {
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(matchedNode);
+ return profile != null ? profile.getMeaningfulText(matchedNode) : matchedNode.getText();
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ return match(patternNode,matchedNode,0,-1,context);
+ }
+
+ boolean doMatch(String text, MatchContext context, PsiElement matchedElement) {
+ return doMatch(text,0,-1,context, matchedElement);
+ }
+
+ boolean doMatch(String text, int from, int end, MatchContext context,PsiElement matchedElement) {
+ if (from > 0 || end != -1) {
+ text = text.substring(from, end == -1 || end >= text.length() ? text.length():end);
+ }
+
+ if (simpleString) {
+ return (caseSensitive)?text.equals(regexp):text.equalsIgnoreCase(regexp);
+ }
+
+ if(!multiline && text.contains("\n")) setMultiline(true);
+ final Matcher matcher = pattern.matcher(text);
+
+ if (matcher.matches()) {
+ for (int i=1;i<=matcher.groupCount();++i) {
+ context.getResult().addSon(
+ new MatchResultImpl(
+ baseHandlerName + "_" + i,
+ matcher.group(i),
+ new SmartPsiPointer(matchedElement),
+ matcher.start(i),
+ matcher.end(i),
+ target
+ )
+ );
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ public void setNodeTextGenerator(final NodeTextGenerator nodeTextGenerator) {
+ myNodeTextGenerator = nodeTextGenerator;
+ }
+
+ public void setMultiline(boolean b) {
+ multiline = b;
+ compilePattern();
+ }
+
+ public boolean isWholeWords() {
+ return wholeWords;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptPredicate.java
new file mode 100644
index 000000000000..9310eb9e70a0
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptPredicate.java
@@ -0,0 +1,28 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class ScriptPredicate extends AbstractStringBasedPredicate {
+ private final ScriptSupport scriptSupport;
+
+ public ScriptPredicate(String name, String within) {
+ super(name, within);
+ scriptSupport = new ScriptSupport(within, name);
+ }
+
+ public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) {
+ if (match == null) return false;
+
+ return Boolean.TRUE.equals(
+ Boolean.valueOf(scriptSupport.evaluate(
+ context.hasResult() ? context.getResult() : null,
+ match
+ ))
+ );
+ }
+
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java
new file mode 100644
index 000000000000..e4136ede2831
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/ScriptSupport.java
@@ -0,0 +1,91 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.StructuralSearchException;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import groovy.lang.Binding;
+import groovy.lang.GroovyRuntimeException;
+import groovy.lang.GroovyShell;
+import groovy.lang.Script;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.MultipleCompilationErrorsException;
+import org.codehaus.groovy.control.messages.Message;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.syntax.SyntaxException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: 11.06.2009
+ * Time: 16:25:12
+ */
+public class ScriptSupport {
+ private final Script script;
+
+ public ScriptSupport(String text, String name) {
+ File scriptFile = new File(text);
+ GroovyShell shell = new GroovyShell();
+ try {
+ script = scriptFile.exists() ? shell.parse(scriptFile):shell.parse(text, name);
+ } catch (Exception ex) {
+ Logger.getInstance(getClass().getName()).error(ex);
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public String evaluate(MatchResultImpl result, PsiElement context) {
+ try {
+ Binding binding = new Binding();
+
+ if (result != null) {
+ for(MatchResult r:result.getMatches()) {
+ binding.setVariable(r.getName(),r.getMatchRef().getElement());
+ }
+ }
+
+ if (context == null) {
+ context = result.getMatchRef().getElement();
+ }
+ if (StructuralSearchUtil.isIdentifier(context)) context = context.getParent();
+ binding.setVariable("__context__", context);
+ script.setBinding(binding);
+
+ Object o = script.run();
+ return String.valueOf(o);
+ } catch (GroovyRuntimeException ex) {
+ throw new StructuralSearchException(SSRBundle.message("groovy.script.error", ex.getMessage()));
+ }
+ }
+
+ public static String checkValidScript(String scriptText) {
+ try {
+ final File scriptFile = new File(scriptText);
+ final GroovyShell shell = new GroovyShell();
+ final Script script = scriptFile.exists() ? shell.parse(scriptFile) : shell.parse(scriptText);
+ return null;
+ } catch (IOException e) {
+ return e.getMessage();
+ } catch (MultipleCompilationErrorsException e) {
+ final ErrorCollector errorCollector = e.getErrorCollector();
+ final List<Message> errors = errorCollector.getErrors();
+ for (Message error : errors) {
+ if (error instanceof SyntaxErrorMessage) {
+ final SyntaxErrorMessage errorMessage = (SyntaxErrorMessage)error;
+ final SyntaxException cause = errorMessage.getCause();
+ return cause.getMessage();
+ }
+ }
+ return e.getMessage();
+ } catch (CompilationFailedException ex) {
+ return ex.getLocalizedMessage();
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/WithinPredicate.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/WithinPredicate.java
new file mode 100644
index 000000000000..3904eb397bce
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/predicates/WithinPredicate.java
@@ -0,0 +1,38 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.Matcher;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class WithinPredicate extends AbstractStringBasedPredicate {
+ private final MatchOptions myMatchOptions;
+ private Matcher matcher;
+
+ public WithinPredicate(String name, String within, Project project) {
+ super(name, within);
+ myMatchOptions = new MatchOptions();
+
+ myMatchOptions.setLooseMatching(true);
+ final String unquoted = StringUtil.stripQuotesAroundValue(within);
+ if (!unquoted.equals(within)) {
+ myMatchOptions.setSearchPattern(unquoted);
+ PatternCompiler.transformOldPattern(myMatchOptions);
+ matcher = new Matcher(project, myMatchOptions);
+ } else {
+ assert false;
+ }
+ }
+
+ public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) {
+ final MatchResult result = matcher.isMatchedByDownUp(match, myMatchOptions);
+ return result != null;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategy.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategy.java
new file mode 100644
index 000000000000..8f5b5bc2fc20
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategy.java
@@ -0,0 +1,13 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.psi.PsiElement;
+
+
+/**
+ * CommonStrategy of metching process
+ */
+public interface MatchingStrategy {
+ boolean continueMatching(PsiElement start);
+
+ boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith);
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/XmlMatchingStrategy.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/XmlMatchingStrategy.java
new file mode 100644
index 000000000000..b2ca87a176e8
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/strategies/XmlMatchingStrategy.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.XmlElementVisitor;
+import com.intellij.psi.xml.XmlTag;
+
+/**
+ * Base filtering strategy to find statements
+ */
+public class XmlMatchingStrategy extends XmlElementVisitor implements MatchingStrategy,NodeFilter {
+ protected boolean result;
+
+ @Override public void visitXmlTag(final XmlTag element) {
+ result = true;
+ }
+
+ public boolean continueMatching(final PsiElement start) {
+ return accepts(start);
+ }
+
+ @Override
+ public boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
+ return false;
+ }
+
+ protected XmlMatchingStrategy() {}
+
+ private static class XmlMatchingStrategyHolder {
+ private static final XmlMatchingStrategy instance = new XmlMatchingStrategy();
+ }
+
+ public static MatchingStrategy getInstance() {
+ return XmlMatchingStrategyHolder.instance;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java
new file mode 100644
index 000000000000..7a38ddb2ea65
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.structuralsearch.inspection.highlightTemplate;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInspection.*;
+import com.intellij.dupLocator.iterators.CountingNodeIterator;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.profile.codeInspection.InspectionProfileManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.Matcher;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.StructuralSearchException;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.ConfigurationManager;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+import com.intellij.util.PairProcessor;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+ * @author cdr
+ */
+public class SSBasedInspection extends LocalInspectionTool {
+ static final String SHORT_NAME = "SSBasedInspection";
+ private List<Configuration> myConfigurations = new ArrayList<Configuration>();
+ private Set<String> myProblemsReported = new HashSet<String>(1);
+
+ public void writeSettings(@NotNull Element node) throws WriteExternalException {
+ ConfigurationManager.writeConfigurations(node, myConfigurations, Collections.<Configuration>emptyList());
+ }
+
+ public void readSettings(@NotNull Element node) throws InvalidDataException {
+ myProblemsReported.clear();
+ myConfigurations.clear();
+ ConfigurationManager.readConfigurations(node, myConfigurations, new ArrayList<Configuration>());
+ }
+
+ @NotNull
+ public String getGroupDisplayName() {
+ return GENERAL_GROUP_NAME;
+ }
+
+ @NotNull
+ public String getDisplayName() {
+ return SSRBundle.message("SSRInspection.display.name");
+ }
+
+ @NotNull
+ @NonNls
+ public String getShortName() {
+ return SHORT_NAME;
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+ final MatcherImpl.CompiledOptions compiledOptions =
+ SSBasedInspectionCompiledPatternsCache.getCompiledOptions(holder.getProject());
+
+ if (compiledOptions == null) return super.buildVisitor(holder, isOnTheFly);
+
+ return new PsiElementVisitor() {
+ final List<Pair<MatchContext,Configuration>> contexts = compiledOptions.getMatchContexts();
+ final Matcher matcher = new Matcher(holder.getManager().getProject());
+ final PairProcessor<MatchResult, Configuration> processor = new PairProcessor<MatchResult, Configuration>() {
+ public boolean process(MatchResult matchResult, Configuration configuration) {
+ PsiElement element = matchResult.getMatch();
+ String name = configuration.getName();
+ LocalQuickFix fix = createQuickFix(holder.getManager().getProject(), matchResult, configuration);
+ holder.registerProblem(
+ holder.getManager().createProblemDescriptor(element, name, fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)
+ );
+ return true;
+ }
+ };
+
+ @Override
+ public void visitElement(PsiElement element) {
+ if (LexicalNodesFilter.getInstance().accepts(element)) return;
+ final SsrFilteringNodeIterator matchedNodes = new SsrFilteringNodeIterator(element);
+ for (Pair<MatchContext, Configuration> pair : contexts) {
+ Configuration configuration = pair.second;
+ MatchContext context = pair.first;
+
+ if (MatcherImpl.checkIfShouldAttemptToMatch(context, matchedNodes)) {
+ final int nodeCount = context.getPattern().getNodeCount();
+ try {
+ matcher.processMatchesInElement(context, configuration, new CountingNodeIterator(nodeCount, matchedNodes), processor);
+ }
+ catch (StructuralSearchException e) {
+ if (myProblemsReported.add(configuration.getName())) { // don't overwhelm the user with messages
+ Notifications.Bus.notify(new Notification(SSRBundle.message("structural.search.title"),
+ SSRBundle.message("template.problem", configuration.getName()),
+ e.getMessage(),
+ NotificationType.ERROR), element.getProject());
+ }
+ }
+ matchedNodes.reset();
+ }
+ }
+ }
+ };
+ }
+
+ private static LocalQuickFix createQuickFix(final Project project, final MatchResult matchResult, final Configuration configuration) {
+ if (!(configuration instanceof ReplaceConfiguration)) return null;
+ ReplaceConfiguration replaceConfiguration = (ReplaceConfiguration)configuration;
+ final Replacer replacer = new Replacer(project, replaceConfiguration.getOptions());
+ final ReplacementInfo replacementInfo = replacer.buildReplacement(matchResult);
+
+ return new LocalQuickFix() {
+ @NotNull
+ public String getName() {
+ return SSRBundle.message("SSRInspection.replace.with", replacementInfo.getReplacement());
+ }
+
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ if (element != null && FileModificationService.getInstance().preparePsiElementsForWrite(element)) {
+ replacer.replace(replacementInfo);
+ }
+ }
+
+ @NotNull
+ public String getFamilyName() {
+ return SSRBundle.message("SSRInspection.family.name");
+ }
+ };
+ }
+
+ @Nullable
+ public JComponent createOptionsPanel() {
+ return new SSBasedInspectionOptions(myConfigurations){
+ public void configurationsChanged(final SearchContext searchContext) {
+ super.configurationsChanged(searchContext);
+ SSBasedInspectionCompiledPatternsCache.precompileConfigurations(searchContext.getProject(), SSBasedInspection.this);
+ InspectionProfileManager.getInstance().fireProfileChanged(null);
+ }
+ }.getComponent();
+ }
+
+ @TestOnly
+ public void setConfigurations(final List<Configuration> configurations, final Project project) {
+ myConfigurations = configurations;
+ SSBasedInspectionCompiledPatternsCache.setCompiledOptions(project, configurations);
+ }
+
+ public List<Configuration> getConfigurations() {
+ return myConfigurations;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java
new file mode 100644
index 000000000000..2d6335fe10ce
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java
@@ -0,0 +1,78 @@
+package com.intellij.structuralsearch.inspection.highlightTemplate;
+
+import com.intellij.codeInspection.InspectionProfile;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.startup.StartupActivity;
+import com.intellij.openapi.util.Key;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.structuralsearch.Matcher;
+import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class SSBasedInspectionCompiledPatternsCache implements StartupActivity {
+ private static final Key<MatcherImpl.CompiledOptions> COMPILED_OPTIONS_KEY = Key.create("SSR_INSPECTION_COMPILED_OPTIONS_KEY");
+
+ @Override
+ public void runActivity(@NotNull final Project project) {
+ precompileConfigurations(project, null);
+ }
+
+ static void precompileConfigurations(final Project project, @Nullable final SSBasedInspection ssBasedInspection) {
+ if (project.isDisposed()) {
+ return;
+ }
+ final MatcherImpl.CompiledOptions currentCompiledOptions = getCompiledOptions(project);
+
+ final SSBasedInspection inspection = ssBasedInspection != null ? ssBasedInspection : getInspection(project);
+ if (inspection == null) {
+ return;
+ }
+
+ List<Configuration> configurations = inspection.getConfigurations();
+ if (configurations == null) {
+ configurations = Collections.emptyList();
+ }
+
+ if ((currentCompiledOptions == null || currentCompiledOptions.getMatchContexts().isEmpty()) &&
+ configurations.isEmpty()) {
+ return;
+ }
+
+ final Matcher matcher = new Matcher(project);
+ final MatcherImpl.CompiledOptions compiledOptions = matcher.precompileOptions(configurations);
+
+ if (compiledOptions != null) {
+ project.putUserData(COMPILED_OPTIONS_KEY, compiledOptions);
+ }
+ }
+
+ @Nullable
+ private static SSBasedInspection getInspection(@NotNull Project project) {
+ final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
+ final InspectionToolWrapper entry = profile.getInspectionTool(SSBasedInspection.SHORT_NAME, project);
+
+ return entry == null ? null : (SSBasedInspection)entry.getTool();
+ }
+
+ @Nullable
+ static MatcherImpl.CompiledOptions getCompiledOptions(@NotNull Project project) {
+ return project.getUserData(COMPILED_OPTIONS_KEY);
+ }
+
+ @TestOnly
+ static void setCompiledOptions(@NotNull Project project, @NotNull List<Configuration> configurations) {
+ final Matcher matcher = new Matcher(project);
+ project.putUserData(COMPILED_OPTIONS_KEY,
+ matcher.precompileOptions(configurations));
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java
new file mode 100644
index 000000000000..8dd7211eefb4
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.structuralsearch.inspection.highlightTemplate;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceDialog;
+import com.intellij.structuralsearch.plugin.ui.*;
+import com.intellij.ui.AnActionButton;
+import com.intellij.ui.AnActionButtonRunnable;
+import com.intellij.ui.DoubleClickListener;
+import com.intellij.ui.ToolbarDecorator;
+import com.intellij.ui.components.JBList;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author cdr
+ */
+public class SSBasedInspectionOptions {
+ private JBList myTemplatesList;
+ // for externalization
+ private final List<Configuration> myConfigurations;
+
+ public SSBasedInspectionOptions(final List<Configuration> configurations) {
+ myConfigurations = configurations;
+ myTemplatesList = new JBList(new MyListModel());
+ myTemplatesList.setCellRenderer(new DefaultListCellRenderer() {
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ JLabel component = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ Configuration configuration = myConfigurations.get(index);
+ component.setText(configuration.getName());
+ return component;
+ }
+ });
+ }
+
+ private static void copyConfiguration(final Configuration configuration, final Configuration newConfiguration) {
+ @NonNls Element temp = new Element("temp");
+ configuration.writeExternal(temp);
+ newConfiguration.readExternal(temp);
+ }
+
+ interface SearchDialogFactory {
+ SearchDialog createDialog(SearchContext searchContext);
+ }
+
+ private void addTemplate(SearchDialogFactory searchDialogFactory) {
+ SearchDialog dialog = createDialog(searchDialogFactory);
+ dialog.show();
+ if (!dialog.isOK()) return;
+ Configuration configuration = dialog.getConfiguration();
+
+ if (configuration.getName() == null || configuration.getName().equals(SearchDialog.USER_DEFINED)) {
+ String name = dialog.showSaveTemplateAsDialog();
+
+ if (name != null) {
+ name = ConfigurationManager.findAppropriateName(myConfigurations, name, dialog.getProject());
+ }
+ if (name == null) return;
+ configuration.setName(name);
+ }
+ myConfigurations.add(configuration);
+
+ configurationsChanged(dialog.getSearchContext());
+ }
+
+ private static SearchDialog createDialog(final SearchDialogFactory searchDialogFactory) {
+ SearchContext searchContext = createSearchContext();
+ return searchDialogFactory.createDialog(searchContext);
+ }
+
+ private static SearchContext createSearchContext() {
+ AnActionEvent event = new AnActionEvent(null, DataManager.getInstance().getDataContext(),
+ "", new DefaultActionGroup().getTemplatePresentation(), ActionManager.getInstance(), 0);
+ return SearchContext.buildFromDataContext(event.getDataContext());
+ }
+
+ public void configurationsChanged(final SearchContext searchContext) {
+ ((MyListModel)myTemplatesList.getModel()).fireContentsChanged();
+ }
+
+ public JPanel getComponent() {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(new JLabel(SSRBundle.message("SSRInspection.selected.templates")));
+ panel.add(
+ ToolbarDecorator.createDecorator(myTemplatesList)
+ .setAddAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ final AnAction[] children = new AnAction[]{
+ new AnAction(SSRBundle.message("SSRInspection.add.search.template.button")) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ addTemplate(new SearchDialogFactory() {
+ public SearchDialog createDialog(SearchContext searchContext) {
+ return new SearchDialog(searchContext, false, false);
+ }
+ });
+ }
+ },
+ new AnAction(SSRBundle.message("SSRInspection.add.replace.template.button")) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ addTemplate(new SearchDialogFactory() {
+ public SearchDialog createDialog(SearchContext searchContext) {
+ return new ReplaceDialog(searchContext, false, false);
+ }
+ });
+ }
+ }
+ };
+ JBPopupFactory.getInstance().createActionGroupPopup(null, new DefaultActionGroup(children),
+ DataManager.getInstance()
+ .getDataContext(button.getContextComponent()),
+ JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, true)
+ .show(button.getPreferredPopupPoint());
+ }
+ }).setEditAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ performEditAction();
+ }
+ }).setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ Object[] selected = myTemplatesList.getSelectedValues();
+ for (Object o : selected) {
+ Configuration configuration = (Configuration)o;
+ Iterator<Configuration> iterator = myConfigurations.iterator();
+ while (iterator.hasNext()) {
+ Configuration configuration1 = iterator.next();
+ if (configuration1.getName().equals(configuration.getName())) {
+ iterator.remove();
+ }
+ }
+ }
+ configurationsChanged(createSearchContext());
+ }
+ }).setMoveUpAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ performMoveUpDown(false);
+ }
+ }).setMoveDownAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ performMoveUpDown(true);
+ }
+ }).createPanel()
+ );
+ new DoubleClickListener() {
+ @Override
+ protected boolean onDoubleClick(MouseEvent e) {
+ performEditAction();
+ return true;
+ }
+ }.installOn(myTemplatesList);
+ return panel;
+ }
+
+ private void performMoveUpDown(boolean down) {
+ final int[] indices = myTemplatesList.getSelectedIndices();
+ if (indices.length == 0) return;
+ final int delta = down ? 1 : -1;
+ myTemplatesList.removeSelectionInterval(0, myConfigurations.size() - 1);
+ for (int i = down ? indices[indices.length - 1] : 0;
+ down ? i >= 0 : i < indices.length;
+ i -= delta) {
+ final int index = indices[i];
+ final Configuration temp = myConfigurations.get(index);
+ myConfigurations.set(index, myConfigurations.get(index + delta));
+ myConfigurations.set(index + delta, temp);
+ myTemplatesList.addSelectionInterval(index + delta, index + delta);
+ }
+ final int index = down ? myTemplatesList.getMaxSelectionIndex() : myTemplatesList.getMinSelectionIndex();
+ final Rectangle cellBounds = myTemplatesList.getCellBounds(index, index);
+ if (cellBounds != null) {
+ myTemplatesList.scrollRectToVisible(cellBounds);
+ }
+ }
+
+ private void performEditAction() {
+ final Configuration configuration = (Configuration)myTemplatesList.getSelectedValue();
+ if (configuration == null) return;
+
+ SearchDialog dialog = createDialog(new SearchDialogFactory() {
+ public SearchDialog createDialog(SearchContext searchContext) {
+ if (configuration instanceof SearchConfiguration) {
+ return new SearchDialog(searchContext, false, false) {
+ public Configuration createConfiguration() {
+ SearchConfiguration newConfiguration = new SearchConfiguration();
+ copyConfiguration(configuration, newConfiguration);
+ return newConfiguration;
+ }
+ };
+ }
+ else {
+ return new ReplaceDialog(searchContext, false, false) {
+ public Configuration createConfiguration() {
+ ReplaceConfiguration newConfiguration = new ReplaceConfiguration();
+ copyConfiguration(configuration, newConfiguration);
+ return newConfiguration;
+ }
+ };
+ }
+ }
+ });
+ dialog.setValuesFromConfig(configuration);
+ dialog.setUseLastConfiguration(true);
+ dialog.show();
+ if (!dialog.isOK()) return;
+ Configuration newConfiguration = dialog.getConfiguration();
+ copyConfiguration(newConfiguration, configuration);
+ configurationsChanged(dialog.getSearchContext());
+ }
+
+ private class MyListModel extends AbstractListModel {
+ public int getSize() {
+ return myConfigurations.size();
+ }
+
+ public Object getElementAt(int index) {
+ return index < myConfigurations.size() ? myConfigurations.get(index) : null;
+ }
+
+ public void fireContentsChanged() {
+ fireContentsChanged(myTemplatesList, -1, -1);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralReplaceAction.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralReplaceAction.java
new file mode 100644
index 000000000000..33e7ac5b4d4d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralReplaceAction.java
@@ -0,0 +1,55 @@
+package com.intellij.structuralsearch.plugin;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceDialog;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+
+/**
+ * Search and replace structural java code patterns action.
+ */
+public class StructuralReplaceAction extends AnAction {
+
+ public StructuralReplaceAction() {
+ super(SSRBundle.message("structuralreplace.action"));
+ }
+
+ /** Handles IDEA action event
+ * @param event the event of action
+ */
+ public void actionPerformed(AnActionEvent event) {
+ triggerAction(null, SearchContext.buildFromDataContext(event.getDataContext()));
+ }
+
+ public static void triggerAction(Configuration config, SearchContext searchContext) {
+ ReplaceDialog replaceDialog = new ReplaceDialog(searchContext);
+
+ if (config!=null) {
+ replaceDialog.setUseLastConfiguration(true);
+ replaceDialog.setValuesFromConfig(config);
+ }
+
+ replaceDialog.show();
+ }
+
+ /** Updates the state of the action
+ * @param event the action event
+ */
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final DataContext context = event.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(context);
+ final StructuralSearchPlugin plugin = (project == null)? null:StructuralSearchPlugin.getInstance( project );
+
+ if (plugin== null || plugin.isSearchInProgress() || plugin.isReplaceInProgress() || plugin.isDialogVisible()) {
+ presentation.setEnabled( false );
+ } else {
+ presentation.setEnabled( true );
+ }
+
+ super.update(event);
+ }
+}
+
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchAction.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchAction.java
new file mode 100644
index 000000000000..116f885b4679
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchAction.java
@@ -0,0 +1,54 @@
+package com.intellij.structuralsearch.plugin;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+import com.intellij.structuralsearch.plugin.ui.SearchDialog;
+
+public class StructuralSearchAction extends AnAction {
+
+ public StructuralSearchAction() {
+ super(SSRBundle.message("structuralsearch.action"));
+ }
+
+ /** Handles IDEA action event
+ * @param event the event of action
+ */
+ public void actionPerformed(AnActionEvent event) {
+ triggerAction(null, SearchContext.buildFromDataContext(event.getDataContext()));
+ }
+
+ public static void triggerAction(Configuration config, SearchContext searchContext) {
+ //StructuralSearchPlugin.getInstance(searchContext.getProject());
+ final SearchDialog searchDialog = new SearchDialog(searchContext);
+
+ if (config!=null) {
+ searchDialog.setUseLastConfiguration(true);
+ searchDialog.setValuesFromConfig(config);
+ }
+
+ searchDialog.show();
+ }
+
+ /** Updates the state of the action
+ * @param event the action event
+ */
+ public void update(AnActionEvent event) {
+ final Presentation presentation = event.getPresentation();
+ final DataContext context = event.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(context);
+ final StructuralSearchPlugin plugin = project==null ? null:StructuralSearchPlugin.getInstance( project );
+
+ if (plugin == null || plugin.isSearchInProgress() || plugin.isDialogVisible()) {
+ presentation.setEnabled( false );
+ } else {
+ presentation.setEnabled( true );
+ }
+
+ super.update(event);
+ }
+
+}
+
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchPlugin.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchPlugin.java
new file mode 100644
index 000000000000..23de5efb9cde
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/StructuralSearchPlugin.java
@@ -0,0 +1,110 @@
+package com.intellij.structuralsearch.plugin;
+
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.structuralsearch.plugin.ui.ConfigurationManager;
+import com.intellij.structuralsearch.plugin.ui.ExistingTemplatesComponent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Structural search plugin main class.
+ */
+public final class StructuralSearchPlugin implements ProjectComponent, JDOMExternalizable {
+ private boolean searchInProgress;
+ private boolean replaceInProgress;
+ private boolean myDialogVisible;
+ private final ConfigurationManager myConfigurationManager = new ConfigurationManager();
+ private ExistingTemplatesComponent myExistingTemplatesComponent;
+
+ public boolean isSearchInProgress() {
+ return searchInProgress;
+ }
+
+ public void setSearchInProgress(boolean searchInProgress) {
+ this.searchInProgress = searchInProgress;
+ }
+
+ public boolean isReplaceInProgress() {
+ return replaceInProgress;
+ }
+
+ public void setReplaceInProgress(boolean replaceInProgress) {
+ this.replaceInProgress = replaceInProgress;
+ }
+
+ public boolean isDialogVisible() {
+ return myDialogVisible;
+ }
+
+ public void setDialogVisible(boolean dialogVisible) {
+ myDialogVisible = dialogVisible;
+ }
+
+ /**
+ * Method is called after plugin is already created and configured. Plugin can start to communicate with
+ * other plugins only in this method.
+ */
+ public void initComponent() {
+ }
+
+ /**
+ * This method is called on plugin disposal.
+ */
+ public void disposeComponent() {
+ }
+
+ /**
+ * Returns the name of component
+ *
+ * @return String representing component name. Use PluginName.ComponentName notation
+ * to avoid conflicts.
+ */
+ @NotNull
+ public String getComponentName() {
+ return "StructuralSearchPlugin";
+ }
+
+ // Simple logging facility
+
+ // Logs given string to IDEA logger
+
+ private static class LoggerHolder {
+ private static final Logger logger = Logger.getInstance("Structural search");
+ }
+
+ public static void debug(String str) {
+ LoggerHolder.logger.info(str);
+ }
+
+ public void readExternal(org.jdom.Element element) {
+ myConfigurationManager.loadConfigurations(element);
+ }
+
+ public void writeExternal(org.jdom.Element element) {
+ myConfigurationManager.saveConfigurations(element);
+ }
+
+ public void projectOpened() {
+ }
+
+ public void projectClosed() {
+ }
+
+ public static StructuralSearchPlugin getInstance(Project project) {
+ return project.getComponent(StructuralSearchPlugin.class);
+ }
+
+ public ConfigurationManager getConfigurationManager() {
+ return myConfigurationManager;
+ }
+
+ public ExistingTemplatesComponent getExistingTemplatesComponent() {
+ return myExistingTemplatesComponent;
+ }
+
+ public void setExistingTemplatesComponent(ExistingTemplatesComponent existingTemplatesComponent) {
+ myExistingTemplatesComponent = existingTemplatesComponent;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplaceOptions.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplaceOptions.java
new file mode 100644
index 000000000000..d18d51acd93c
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplaceOptions.java
@@ -0,0 +1,177 @@
+package com.intellij.structuralsearch.plugin.replace;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.ReplacementVariableDefinition;
+import gnu.trove.THashMap;
+import org.jdom.Attribute;
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Mar 5, 2004
+ * Time: 7:51:38 PM
+ */
+public class ReplaceOptions implements JDOMExternalizable, Cloneable, UserDataHolder {
+ private Map<String, ReplacementVariableDefinition> variableDefs;
+ private String replacement = "";
+ private boolean toShortenFQN;
+ private boolean myToReformatAccordingToStyle;
+ private MatchOptions matchOptions = new MatchOptions();
+
+ @NonNls private static final String REFORMAT_ATTR_NAME = "reformatAccordingToStyle";
+ @NonNls private static final String REPLACEMENT_ATTR_NAME = "replacement";
+ @NonNls private static final String SHORTEN_FQN_ATTR_NAME = "shortenFQN";
+
+ private THashMap myUserMap = null;
+ @NonNls private static final String VARIABLE_DEFINITION_TAG_NAME = "variableDefinition";
+
+ public String getReplacement() {
+ return replacement;
+ }
+
+ public void setReplacement(String replacement) {
+ this.replacement = replacement;
+ }
+
+ public boolean isToShortenFQN() {
+ return toShortenFQN;
+ }
+
+ public void setToShortenFQN(boolean shortedFQN) {
+ this.toShortenFQN = shortedFQN;
+ }
+
+ public boolean isToReformatAccordingToStyle() {
+ return myToReformatAccordingToStyle;
+ }
+
+ public MatchOptions getMatchOptions() {
+ return matchOptions;
+ }
+
+ public void setMatchOptions(MatchOptions matchOptions) {
+ this.matchOptions = matchOptions;
+ }
+
+ public void setToReformatAccordingToStyle(boolean reformatAccordingToStyle) {
+ myToReformatAccordingToStyle = reformatAccordingToStyle;
+ }
+
+ public void readExternal(Element element) {
+ matchOptions.readExternal(element);
+
+ Attribute attribute = element.getAttribute(REFORMAT_ATTR_NAME);
+ try {
+ myToReformatAccordingToStyle = attribute.getBooleanValue();
+ } catch(DataConversionException ex) {
+ }
+
+ attribute = element.getAttribute(SHORTEN_FQN_ATTR_NAME);
+ try {
+ toShortenFQN = attribute.getBooleanValue();
+ } catch(DataConversionException ex) {}
+
+ replacement = element.getAttributeValue(REPLACEMENT_ATTR_NAME);
+
+ List<Element> elements = element.getChildren(VARIABLE_DEFINITION_TAG_NAME);
+
+ if (elements!=null && elements.size() > 0) {
+ for (final Element element1 : elements) {
+ final ReplacementVariableDefinition variableDefinition = new ReplacementVariableDefinition();
+ variableDefinition.readExternal(element1);
+ addVariableDefinition(variableDefinition);
+ }
+ }
+ }
+
+ public void writeExternal(Element element) {
+ matchOptions.writeExternal(element);
+
+ element.setAttribute(REFORMAT_ATTR_NAME,String.valueOf(myToReformatAccordingToStyle));
+ element.setAttribute(SHORTEN_FQN_ATTR_NAME,String.valueOf(toShortenFQN));
+ element.setAttribute(REPLACEMENT_ATTR_NAME,replacement);
+
+ if (variableDefs!=null) {
+ for (final ReplacementVariableDefinition variableDefinition : variableDefs.values()) {
+ final Element infoElement = new Element(VARIABLE_DEFINITION_TAG_NAME);
+ element.addContent(infoElement);
+ variableDefinition.writeExternal(infoElement);
+ }
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ReplaceOptions)) return false;
+
+ final ReplaceOptions replaceOptions = (ReplaceOptions)o;
+
+ if (myToReformatAccordingToStyle != replaceOptions.myToReformatAccordingToStyle) return false;
+ if (toShortenFQN != replaceOptions.toShortenFQN) return false;
+ if (matchOptions != null ? !matchOptions.equals(replaceOptions.matchOptions) : replaceOptions.matchOptions != null) return false;
+ if (replacement != null ? !replacement.equals(replaceOptions.replacement) : replaceOptions.replacement != null) return false;
+ if (variableDefs != null ? !variableDefs.equals(replaceOptions.variableDefs) : replaceOptions.variableDefs != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (replacement != null ? replacement.hashCode() : 0);
+ result = 29 * result + (toShortenFQN ? 1 : 0);
+ result = 29 * result + (myToReformatAccordingToStyle ? 1 : 0);
+ result = 29 * result + (matchOptions != null ? matchOptions.hashCode() : 0);
+ result = 29 * result + (variableDefs != null ? variableDefs.hashCode() : 0);
+ return result;
+ }
+
+ public ReplaceOptions clone() {
+ try {
+ ReplaceOptions replaceOptions = (ReplaceOptions) super.clone();
+ replaceOptions.matchOptions = matchOptions.clone();
+ return replaceOptions;
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public <T> T getUserData(@NotNull Key<T> key) {
+ if (myUserMap==null) return null;
+ return (T)myUserMap.get(key);
+ }
+
+ public <T> void putUserData(@NotNull Key<T> key, T value) {
+ if (myUserMap==null) myUserMap = new THashMap(1);
+ myUserMap.put(key,value);
+ }
+
+ public ReplacementVariableDefinition getVariableDefinition(String name) {
+ return variableDefs != null ? variableDefs.get(name): null;
+ }
+
+ public void addVariableDefinition(ReplacementVariableDefinition definition) {
+ if (variableDefs==null) {
+ variableDefs = new LinkedHashMap<String, ReplacementVariableDefinition>();
+ }
+ variableDefs.put( definition.getName(), definition );
+ }
+
+ public Collection<ReplacementVariableDefinition> getReplacementVariableDefinitions() {
+ return variableDefs != null ? variableDefs.values() : Collections.<ReplacementVariableDefinition>emptyList();
+ }
+
+ public void clearVariableDefinitions() {
+ variableDefs = null;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplacementInfo.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplacementInfo.java
new file mode 100644
index 000000000000..6b74197c19dd
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ReplacementInfo.java
@@ -0,0 +1,22 @@
+package com.intellij.structuralsearch.plugin.replace;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 03.12.2004
+ * Time: 21:33:53
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class ReplacementInfo {
+ public abstract String getReplacement();
+
+ public abstract void setReplacement(String replacement);
+
+ @Nullable
+ public abstract PsiElement getMatch(int index);
+
+ public abstract int getMatchesCount();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java
new file mode 100644
index 000000000000..43ce859b17dd
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java
@@ -0,0 +1,123 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.psi.PsiElement;
+
+public final class ParameterInfo {
+ private String name;
+ private int startIndex;
+ private boolean parameterContext;
+ private boolean methodParameterContext;
+ private boolean statementContext;
+ private boolean variableInitialContext;
+ private int afterDelimiterPos;
+ private boolean hasCommaBefore;
+ private int beforeDelimiterPos;
+ private boolean hasCommaAfter;
+ private boolean scopeParameterization;
+ private boolean replacementVariable;
+ private PsiElement myElement;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getStartIndex() {
+ return startIndex;
+ }
+
+ public void setStartIndex(int startIndex) {
+ this.startIndex = startIndex;
+ }
+
+ public boolean isParameterContext() {
+ return parameterContext;
+ }
+
+ public void setParameterContext(boolean parameterContext) {
+ this.parameterContext = parameterContext;
+ }
+
+ public boolean isMethodParameterContext() {
+ return methodParameterContext;
+ }
+
+ public void setMethodParameterContext(boolean methodParameterContext) {
+ this.methodParameterContext = methodParameterContext;
+ }
+
+ public boolean isStatementContext() {
+ return statementContext;
+ }
+
+ public void setStatementContext(boolean statementContext) {
+ this.statementContext = statementContext;
+ }
+
+ public boolean isVariableInitialContext() {
+ return variableInitialContext;
+ }
+
+ public void setVariableInitialContext(boolean variableInitialContext) {
+ this.variableInitialContext = variableInitialContext;
+ }
+
+ public int getAfterDelimiterPos() {
+ return afterDelimiterPos;
+ }
+
+ public void setAfterDelimiterPos(int afterDelimiterPos) {
+ this.afterDelimiterPos = afterDelimiterPos;
+ }
+
+ public boolean isHasCommaBefore() {
+ return hasCommaBefore;
+ }
+
+ public void setHasCommaBefore(boolean hasCommaBefore) {
+ this.hasCommaBefore = hasCommaBefore;
+ }
+
+ public int getBeforeDelimiterPos() {
+ return beforeDelimiterPos;
+ }
+
+ public void setBeforeDelimiterPos(int beforeDelimiterPos) {
+ this.beforeDelimiterPos = beforeDelimiterPos;
+ }
+
+ public boolean isHasCommaAfter() {
+ return hasCommaAfter;
+ }
+
+ public void setHasCommaAfter(boolean hasCommaAfter) {
+ this.hasCommaAfter = hasCommaAfter;
+ }
+
+ public boolean isScopeParameterization() {
+ return scopeParameterization;
+ }
+
+ public void setScopeParameterization(boolean scopeParameterization) {
+ this.scopeParameterization = scopeParameterization;
+ }
+
+ public boolean isReplacementVariable() {
+ return replacementVariable;
+ }
+
+ public void setReplacementVariable(boolean replacementVariable) {
+ this.replacementVariable = replacementVariable;
+ }
+
+ public PsiElement getElement() {
+ return myElement;
+ }
+
+ public void setElement(PsiElement element) {
+ myElement = element;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java
new file mode 100644
index 000000000000..81933d9c9a91
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java
@@ -0,0 +1,217 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.codeInsight.template.Template;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.MalformedPatternException;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.util.IncorrectOperationException;
+
+import java.util.*;
+
+/**
+ * @author maxim
+ * Date: 24.02.2004
+ * Time: 15:34:57
+ */
+public final class ReplacementBuilder {
+ private String replacement;
+ private List<ParameterInfo> parameterizations;
+ private HashMap<String,MatchResult> matchMap;
+ private final Map<String, ScriptSupport> replacementVarsMap;
+ private final ReplaceOptions options;
+ //private Map<TextRange,ParameterInfo> scopedParameterizations;
+
+ ReplacementBuilder(final Project project,final ReplaceOptions options) {
+ replacementVarsMap = new HashMap<String, ScriptSupport>();
+ this.options = options;
+ String _replacement = options.getReplacement();
+ FileType fileType = options.getMatchOptions().getFileType();
+
+ final Template template = TemplateManager.getInstance(project).createTemplate("","",_replacement);
+
+ final int segmentsCount = template.getSegmentsCount();
+ replacement = template.getTemplateText();
+
+ for(int i=0;i<segmentsCount;++i) {
+ final int offset = template.getSegmentOffset(i);
+ final String name = template.getSegmentName(i);
+
+ final ParameterInfo info = new ParameterInfo();
+ info.setStartIndex(offset);
+ info.setName(name);
+ info.setReplacementVariable(options.getVariableDefinition(name) != null);
+
+ // find delimiter
+ int pos;
+ for(pos = offset-1; pos >=0 && pos < replacement.length() && Character.isWhitespace(replacement.charAt(pos));) {
+ --pos;
+ }
+
+ if (pos >= 0) {
+ if (replacement.charAt(pos) == ',') {
+ info.setHasCommaBefore(true);
+ }
+ info.setBeforeDelimiterPos(pos);
+ }
+
+ for(pos = offset; pos < replacement.length() && Character.isWhitespace(replacement.charAt(pos));) {
+ ++pos;
+ }
+
+ if (pos < replacement.length()) {
+ final char ch = replacement.charAt(pos);
+
+ if (ch == ';') {
+ info.setStatementContext(true);
+ }
+ else if (ch == ',' || ch == ')') {
+ info.setParameterContext(true);
+ info.setHasCommaAfter(ch == ',');
+ }
+ info.setAfterDelimiterPos(pos);
+ }
+
+ if (parameterizations==null) {
+ parameterizations = new ArrayList<ParameterInfo>();
+ }
+
+ parameterizations.add(info);
+ }
+
+ final StructuralSearchProfile profile = parameterizations != null ? StructuralSearchUtil.getProfileByFileType(fileType) : null;
+ if (profile != null) {
+ try {
+ final PsiElement[] elements = MatcherImplUtil.createTreeFromText(
+ _replacement,
+ PatternTreeContext.Block,
+ fileType,
+ options.getMatchOptions().getDialect(),
+ options.getMatchOptions().getPatternContext(),
+ project,
+ false
+ );
+ if (elements.length > 0) {
+ final PsiElement patternNode = elements[0].getParent();
+ profile.provideAdditionalReplaceOptions(patternNode, options, this);
+ }
+ } catch (IncorrectOperationException e) {
+ throw new MalformedPatternException();
+ }
+ }
+ }
+
+ private static void fill(MatchResult r,Map<String,MatchResult> m) {
+ if (r.getName()!=null) {
+ if (m.get(r.getName()) == null) {
+ m.put(r.getName(), r);
+ }
+ }
+
+ if (!r.isScopeMatch() || !r.isMultipleMatch()) {
+ for (final MatchResult matchResult : r.getAllSons()) {
+ fill(matchResult, m);
+ }
+ } else if (r.hasSons()) {
+ final List<MatchResult> allSons = r.getAllSons();
+ if (allSons.size() > 0) {
+ fill(allSons.get(0),m);
+ }
+ }
+ }
+
+ String process(MatchResult match, ReplacementInfoImpl replacementInfo, FileType type) {
+ if (parameterizations==null) {
+ return replacement;
+ }
+
+ final StringBuilder result = new StringBuilder(replacement);
+ matchMap = new HashMap<String,MatchResult>();
+ fill(match, matchMap);
+
+ int offset = 0;
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(type);
+
+ for (final ParameterInfo info : parameterizations) {
+ MatchResult r = matchMap.get(info.getName());
+ if (info.isReplacementVariable()) {
+ offset = Replacer.insertSubstitution(result, offset, info, generateReplacement(info, match));
+ }
+ else if (r != null) {
+ offset = profile != null ? profile.handleSubstitution(info, r, result, offset, matchMap) : StructuralSearchProfile.defaultHandleSubstitution(info, r, result, offset);
+ }
+ else {
+ if (info.isHasCommaBefore()) {
+ result.delete(info.getBeforeDelimiterPos() + offset, info.getBeforeDelimiterPos() + 1 + offset);
+ --offset;
+ }
+ else if (info.isHasCommaAfter()) {
+ result.delete(info.getAfterDelimiterPos() + offset, info.getAfterDelimiterPos() + 1 + offset);
+ --offset;
+ }
+ else if (info.isVariableInitialContext()) {
+ //if (info.afterDelimiterPos > 0) {
+ result.delete(info.getBeforeDelimiterPos() + offset, info.getAfterDelimiterPos() + offset - 1);
+ offset -= (info.getAfterDelimiterPos() - info.getBeforeDelimiterPos() - 1);
+ //}
+ } else if (profile != null) {
+ offset = profile.processAdditionalOptions(info, offset, result, r);
+ }
+ offset = Replacer.insertSubstitution(result, offset, info, "");
+ }
+ }
+
+ replacementInfo.variableMap = (HashMap<String, MatchResult>)matchMap.clone();
+ matchMap.clear();
+ return result.toString();
+ }
+
+ private String generateReplacement(ParameterInfo info, MatchResult match) {
+ ScriptSupport scriptSupport = replacementVarsMap.get(info.getName());
+
+ if (scriptSupport == null) {
+ String constraint = options.getVariableDefinition(info.getName()).getScriptCodeConstraint();
+ scriptSupport = new ScriptSupport(StringUtil.stripQuotesAroundValue(constraint), info.getName());
+ replacementVarsMap.put(info.getName(), scriptSupport);
+ }
+ return scriptSupport.evaluate((MatchResultImpl)match, null);
+ }
+
+ public ParameterInfo findParameterization(String name) {
+ if (parameterizations==null) return null;
+
+ for (final ParameterInfo info : parameterizations) {
+
+ if (info.getName().equals(name)) {
+ return info;
+ }
+ }
+
+ return null;
+ }
+
+ public void clear() {
+ replacement = null;
+
+ if (parameterizations!=null) {
+ parameterizations.clear();
+ parameterizations = null;
+ }
+ }
+
+ public void addParametrization(ParameterInfo e) {
+ assert parameterizations != null;
+ parameterizations.add(e);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementContext.java
new file mode 100644
index 000000000000..c77d0b7ce1f1
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementContext.java
@@ -0,0 +1,57 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: 27.09.2005
+ * Time: 14:27:20
+ * To change this template use File | Settings | File Templates.
+ */
+public class ReplacementContext {
+ ReplacementInfoImpl replacementInfo;
+ ReplaceOptions options;
+ Project project;
+
+ public ReplaceOptions getOptions() {
+ return options;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ ReplacementContext(ReplaceOptions _options, Project _project) {
+ options = _options;
+ project = _project;
+ }
+
+ public Map<String, String> getNewName2PatternNameMap() {
+ Map<String, String> newNameToSearchPatternNameMap = new HashMap<String, String>(1);
+ final Map<String, MatchResult> variableMap = replacementInfo.getVariableMap();
+
+ if (variableMap != null) {
+ for (String s : variableMap.keySet()) {
+ final MatchResult matchResult = replacementInfo.getVariableMap().get(s);
+ PsiElement match = matchResult.getMatchRef() != null ? matchResult.getMatch() : null;
+ if (StructuralSearchUtil.isIdentifier(match)) match = match.getParent();
+
+ if (match instanceof PsiNamedElement) {
+ final String name = ((PsiNamedElement)match).getName();
+
+ newNameToSearchPatternNameMap.put(name, s);
+ }
+ }
+ }
+ return newNameToSearchPatternNameMap;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementInfoImpl.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementInfoImpl.java
new file mode 100644
index 000000000000..318e88f27c24
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementInfoImpl.java
@@ -0,0 +1,52 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.SmartPsiElementPointer;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 03.12.2004
+ * Time: 21:33:53
+ * To change this template use File | Settings | File Templates.
+ */
+public class ReplacementInfoImpl extends ReplacementInfo {
+ List<SmartPsiElementPointer> matchesPtrList;
+ String result;
+ MatchResult matchResult;
+ Map<String,MatchResult> variableMap;
+ Map<PsiElement,String> elementToVariableNameMap;
+
+ public String getReplacement() {
+ return result;
+ }
+
+ public void setReplacement(String replacement) {
+ result = replacement;
+ }
+
+ @Nullable
+ @Override
+ public PsiElement getMatch(int index) {
+ return matchesPtrList.get(index).getElement();
+ }
+
+ @Override
+ public int getMatchesCount() {
+ return matchesPtrList.size();
+ }
+
+ public Map<String, MatchResult> getVariableMap() {
+ return variableMap;
+ }
+
+ public MatchResult getMatchResult() {
+ return matchResult;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/Replacer.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/Replacer.java
new file mode 100644
index 000000000000..9980e95c77d7
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/Replacer.java
@@ -0,0 +1,424 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.codeInsight.template.Template;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.lang.Language;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.util.CollectingMatchResultSink;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Mar 4, 2004
+ * Time: 9:19:34 PM
+ */
+public class Replacer {
+ private final Project project;
+ private ReplacementBuilder replacementBuilder;
+ private ReplaceOptions options;
+ private ReplacementContext context;
+ private StructuralReplaceHandler replaceHandler;
+
+ public Replacer(Project project, ReplaceOptions options) {
+ this.project = project;
+ this.options = options;
+ }
+
+ public static String stripTypedVariableDecoration(final String type) {
+ return type.substring(1,type.length()-1);
+ }
+
+ public static int insertSubstitution(StringBuilder result, int offset, final ParameterInfo info, String image) {
+ if (image.length() > 0) result.insert(offset+ info.getStartIndex(),image);
+ offset += image.length();
+ return offset;
+ }
+
+ public String testReplace(String in, String what, String by, ReplaceOptions options) throws IncorrectOperationException {
+ return testReplace(in, what, by, options,false);
+ }
+
+ public String testReplace(String in, String what, String by, ReplaceOptions options, boolean filePattern) {
+ FileType type = options.getMatchOptions().getFileType();
+ return testReplace(in, what, by, options, filePattern, false, type, null);
+ }
+
+ public String testReplace(String in, String what, String by, ReplaceOptions options, boolean filePattern, boolean createPhysicalFile,
+ FileType sourceFileType, Language sourceDialect) {
+ this.options = options;
+ this.options.getMatchOptions().setSearchPattern(what);
+ this.options.setReplacement(by);
+ replacementBuilder=null;
+ context = null;
+ replaceHandler = null;
+
+ this.options.getMatchOptions().clearVariableConstraints();
+ MatcherImplUtil.transform(this.options.getMatchOptions());
+
+ checkSupportedReplacementPattern(project, options);
+
+ Matcher matcher = new Matcher(project);
+ try {
+ PsiElement firstElement, lastElement, parent;
+
+ if (options.getMatchOptions().getScope() == null) {
+ PsiElement[] elements = MatcherImplUtil.createTreeFromText(
+ in,
+ filePattern ? PatternTreeContext.File : PatternTreeContext.Block,
+ sourceFileType, sourceDialect, null,
+ project,
+ createPhysicalFile
+ );
+
+ firstElement = elements[0];
+ lastElement = elements[elements.length-1];
+ parent = firstElement.getParent();
+
+ this.options.getMatchOptions().setScope(
+ new LocalSearchScope(parent)
+ );
+ } else {
+ parent = ((LocalSearchScope)options.getMatchOptions().getScope()).getScope()[0];
+ firstElement = parent.getFirstChild();
+ lastElement = parent.getLastChild();
+ }
+
+ this.options.getMatchOptions().setResultIsContextMatch(true);
+ CollectingMatchResultSink sink = new CollectingMatchResultSink();
+ matcher.testFindMatches(sink, this.options.getMatchOptions());
+
+ final List<ReplacementInfo> resultPtrList = new ArrayList<ReplacementInfo>();
+
+ for (final MatchResult result : sink.getMatches()) {
+ resultPtrList.add(buildReplacement(result));
+ }
+
+ sink.getMatches().clear();
+
+ int startOffset = firstElement.getTextRange().getStartOffset();
+ int endOffset = filePattern ?0: parent.getTextLength() - (lastElement.getTextRange().getEndOffset());
+
+ // get nodes from text may contain
+ PsiElement prevSibling = firstElement.getPrevSibling();
+ if (prevSibling instanceof PsiWhiteSpace) {
+ startOffset -= prevSibling.getTextLength() - 1;
+ }
+
+ PsiElement nextSibling = lastElement.getNextSibling();
+ if (nextSibling instanceof PsiWhiteSpace) {
+ endOffset -= nextSibling.getTextLength() - 1;
+ }
+
+ replaceAll(resultPtrList);
+
+ String result = parent.getText();
+ result = result.substring(startOffset);
+ result = result.substring(0,result.length() - endOffset);
+
+ return result;
+ }
+ catch (Exception e) {
+ throw new IncorrectOperationException(e);
+ }
+ finally {
+ options.getMatchOptions().setScope(null);
+ }
+ }
+
+ public void replaceAll(final List<ReplacementInfo> resultPtrList) {
+ PsiElement lastAffectedElement = null;
+ PsiElement currentAffectedElement;
+
+ for (ReplacementInfo info : resultPtrList) {
+ PsiElement element = info.getMatch(0);
+ initContextAndHandler(element);
+ if (replaceHandler != null) {
+ replaceHandler.prepare(info);
+ }
+ }
+
+ for (final ReplacementInfo aResultPtrList : resultPtrList) {
+ currentAffectedElement = doReplace(aResultPtrList);
+
+ if (currentAffectedElement != lastAffectedElement) {
+ if (lastAffectedElement != null) reformatAndShortenRefs(lastAffectedElement);
+ lastAffectedElement = currentAffectedElement;
+ }
+ }
+
+ reformatAndShortenRefs(lastAffectedElement);
+ }
+
+ public void replace(ReplacementInfo info) {
+ PsiElement element = info.getMatch(0);
+ initContextAndHandler(element);
+
+ if (replaceHandler != null) {
+ replaceHandler.prepare(info);
+ }
+ reformatAndShortenRefs(doReplace(info));
+ }
+
+ @Nullable
+ private PsiElement doReplace(final ReplacementInfo info) {
+ final ReplacementInfoImpl replacementInfo = (ReplacementInfoImpl)info;
+ final PsiElement element = replacementInfo.matchesPtrList.get(0).getElement();
+
+ if (element==null || !element.isWritable() || !element.isValid()) return null;
+
+ final PsiElement elementParent = element.getParent();
+
+ //noinspection HardCodedStringLiteral
+ CommandProcessor.getInstance().executeCommand(
+ project,
+ new Runnable() {
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(
+ new Runnable() {
+ public void run() {
+ doReplace(element, replacementInfo);
+ }
+ }
+ );
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+ }
+ },
+ "ssreplace",
+ "test"
+ );
+
+ if (!elementParent.isValid() || !elementParent.isWritable()) {
+ return null;
+ }
+
+ return elementParent;
+ }
+
+ private void reformatAndShortenRefs(final PsiElement elementParent) {
+ if (elementParent == null) return;
+ final Runnable action = new Runnable() {
+ public void run() {
+ CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(PsiManager.getInstance(project).getProject());
+ final PsiFile containingFile = elementParent.getContainingFile();
+
+ if (containingFile != null && options.isToReformatAccordingToStyle()) {
+ if (containingFile.getVirtualFile() != null) {
+ PsiDocumentManager.getInstance(project)
+ .commitDocument(FileDocumentManager.getInstance().getDocument(containingFile.getVirtualFile()));
+ }
+
+ final int parentOffset = elementParent.getTextRange().getStartOffset();
+
+ codeStyleManager.reformatRange(containingFile, parentOffset, parentOffset + elementParent.getTextLength(), true);
+ }
+ }
+ };
+
+ CommandProcessor.getInstance().executeCommand(
+ project,
+ new Runnable() {
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(action);
+ }
+ },
+ "reformat and shorten refs after ssr",
+ "test"
+ );
+ }
+
+ private void doReplace(final PsiElement elementToReplace,
+ final ReplacementInfoImpl info) {
+ CodeStyleManager.getInstance(project).performActionWithFormatterDisabled(new Runnable() {
+ public void run() {
+ initContextAndHandler(elementToReplace);
+
+ context.replacementInfo = info;
+
+ if (replaceHandler != null) {
+ replaceHandler.replace(info, options);
+ }
+ }
+ }
+ );
+ }
+
+ private void initContextAndHandler(PsiElement psiContext) {
+ if (context == null) {
+ context = new ReplacementContext(options, project);
+ }
+ if (replaceHandler == null) {
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(psiContext);
+ if (profile != null) {
+ replaceHandler = profile.getReplaceHandler(this.context);
+ }
+ }
+ }
+
+ public static void handleComments(final PsiElement el, final PsiElement replacement, ReplacementContext context) throws IncorrectOperationException {
+ ReplacementInfoImpl replacementInfo = context.replacementInfo;
+ if (replacementInfo.elementToVariableNameMap == null) {
+ replacementInfo.elementToVariableNameMap = new HashMap<PsiElement, String>(1);
+ Map<String, MatchResult> variableMap = replacementInfo.variableMap;
+ if (variableMap != null) {
+ for(String name:variableMap.keySet()) {
+ fill(name,replacementInfo.variableMap.get(name),replacementInfo.elementToVariableNameMap);
+ }
+ }
+ }
+
+ PsiElement lastChild = el.getLastChild();
+ if (lastChild instanceof PsiComment &&
+ replacementInfo.elementToVariableNameMap.get(lastChild) == null &&
+ !(replacement.getLastChild() instanceof PsiComment)
+ ) {
+ PsiElement firstElementAfterStatementEnd = lastChild;
+ for(PsiElement curElement=firstElementAfterStatementEnd.getPrevSibling();curElement!=null;curElement = curElement.getPrevSibling()) {
+ if (!(curElement instanceof PsiWhiteSpace) && !(curElement instanceof PsiComment)) break;
+ firstElementAfterStatementEnd = curElement;
+ }
+ replacement.addRangeAfter(firstElementAfterStatementEnd,lastChild,replacement.getLastChild());
+ }
+
+ final PsiElement firstChild = el.getFirstChild();
+ if (firstChild instanceof PsiComment &&
+ !(firstChild instanceof PsiDocCommentBase) &&
+ replacementInfo.elementToVariableNameMap.get(firstChild) == null
+ ) {
+ PsiElement lastElementBeforeStatementStart = firstChild;
+
+ for(PsiElement curElement=lastElementBeforeStatementStart.getNextSibling();curElement!=null;curElement = curElement.getNextSibling()) {
+ if (!(curElement instanceof PsiWhiteSpace) && !(curElement instanceof PsiComment)) break;
+ lastElementBeforeStatementStart = curElement;
+ }
+ replacement.addRangeBefore(firstChild,lastElementBeforeStatementStart,replacement.getFirstChild());
+ }
+ }
+
+ private static void fill(final String name, final MatchResult matchResult, final Map<PsiElement, String> elementToVariableNameMap) {
+ boolean b = matchResult.isMultipleMatch() || matchResult.isScopeMatch();
+ if(matchResult.hasSons() && b) {
+ for(MatchResult r:matchResult.getAllSons()) {
+ fill(name, r, elementToVariableNameMap);
+ }
+ } else if (!b && matchResult.getMatchRef() != null) {
+ elementToVariableNameMap.put(matchResult.getMatch(),name);
+ }
+ }
+
+ public static void checkSupportedReplacementPattern(Project project, ReplaceOptions options) throws UnsupportedPatternException {
+ try {
+ String search = options.getMatchOptions().getSearchPattern();
+ String replacement = options.getReplacement();
+ FileType fileType = options.getMatchOptions().getFileType();
+ Template template = TemplateManager.getInstance(project).createTemplate("","",search);
+ Template template2 = TemplateManager.getInstance(project).createTemplate("","",replacement);
+
+ int segmentCount = template2.getSegmentsCount();
+ for(int i=0;i<segmentCount;++i) {
+ final String replacementSegmentName = template2.getSegmentName(i);
+ final int segmentCount2 = template.getSegmentsCount();
+ int j;
+
+ for(j=0;j<segmentCount2;++j) {
+ final String searchSegmentName = template.getSegmentName(j);
+
+ if (replacementSegmentName.equals(searchSegmentName)) break;
+
+ // Reference to
+ if (replacementSegmentName.startsWith(searchSegmentName) &&
+ replacementSegmentName.charAt(searchSegmentName.length())=='_'
+ ) {
+ try {
+ Integer.parseInt(replacementSegmentName.substring(searchSegmentName.length()+1));
+ break;
+ } catch(NumberFormatException ex) {}
+ }
+ }
+
+ if (j==segmentCount2) {
+ ReplacementVariableDefinition definition = options.getVariableDefinition(replacementSegmentName);
+
+ if (definition == null || definition.getScriptCodeConstraint().length() <= 2 /*empty quotes*/) {
+ throw new UnsupportedPatternException(
+ SSRBundle.message("replacement.variable.is.not.defined.message", replacementSegmentName)
+ );
+ } else {
+ String message = ScriptSupport.checkValidScript(StringUtil.stripQuotesAroundValue(definition.getScriptCodeConstraint()));
+ if (message != null) {
+ throw new UnsupportedPatternException(
+ SSRBundle.message("replacement.variable.is.not.valid", replacementSegmentName, message)
+ );
+ }
+ }
+ }
+ }
+
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
+
+ profile.checkReplacementPattern(project, options);
+
+ } catch(IncorrectOperationException ex) {
+ throw new UnsupportedPatternException(SSRBundle.message("incorrect.pattern.message"));
+ }
+ }
+
+ public ReplacementInfo buildReplacement(MatchResult result) {
+ List<SmartPsiElementPointer> l = new ArrayList<SmartPsiElementPointer>();
+ SmartPointerManager manager = SmartPointerManager.getInstance(project);
+
+ if (MatchResult.MULTI_LINE_MATCH.equals(result.getName())) {
+ for(Iterator<MatchResult> i=result.getAllSons().iterator();i.hasNext();) {
+ final MatchResult r = i.next();
+
+ if (MatchResult.LINE_MATCH.equals(r.getName())) {
+ PsiElement element = r.getMatchRef().getElement();
+
+ if (element instanceof PsiDocCommentBase) { // doc comment is not collapsed when created in block
+ if (i.hasNext()) {
+ MatchResult matchResult = i.next();
+
+ if (MatchResult.LINE_MATCH.equals(matchResult.getName()) &&
+ StructuralSearchUtil.isDocCommentOwner(matchResult.getMatch())) {
+ element = matchResult.getMatch();
+ } else {
+ l.add( manager.createSmartPsiElementPointer(element) );
+ element = matchResult.getMatch();
+ }
+ }
+ }
+ l.add( manager.createSmartPsiElementPointer(element) );
+ }
+ }
+ } else {
+ l.add( manager.createSmartPsiElementPointer(result.getMatchRef().getElement()));
+ }
+
+ ReplacementInfoImpl replacementInfo = new ReplacementInfoImpl();
+
+ replacementInfo.matchesPtrList = l;
+ if (replacementBuilder==null) {
+ replacementBuilder = new ReplacementBuilder(project,options);
+ }
+ replacementInfo.result = replacementBuilder.process(result, replacementInfo, options.getMatchOptions().getFileType());
+ replacementInfo.matchResult = result;
+
+ return replacementInfo;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacerUtil.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacerUtil.java
new file mode 100644
index 000000000000..365ec74bc01e
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacerUtil.java
@@ -0,0 +1,49 @@
+package com.intellij.structuralsearch.plugin.replace.impl;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class ReplacerUtil {
+ private ReplacerUtil() {
+ }
+
+ public static PsiElement[] createTreeForReplacement(String replacement, PatternTreeContext treeContext, ReplacementContext context) {
+ FileType fileType = context.getOptions().getMatchOptions().getFileType();
+ return MatcherImplUtil.createTreeFromText(replacement, treeContext, fileType, context.getProject());
+ }
+
+ public static PsiElement copySpacesAndCommentsBefore(PsiElement elementToReplace,
+ PsiElement[] patternElements,
+ String replacementToMake,
+ PsiElement elementParent) {
+ int i = 0;
+ while (true) { // if it goes out of bounds then deep error happens
+ if (!(patternElements[i] instanceof PsiComment || patternElements[i] instanceof PsiWhiteSpace)) {
+ break;
+ }
+ ++i;
+ if (patternElements.length == i) {
+ break;
+ }
+ }
+
+ if (patternElements.length == i) {
+ Logger logger = Logger.getInstance(StructuralSearchProfile.class.getName());
+ logger.error("Unexpected replacement structure:" + replacementToMake);
+ }
+
+ if (i != 0) {
+ elementParent.addRangeBefore(patternElements[0], patternElements[i - 1], elementToReplace);
+ }
+ return patternElements[i];
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceCommand.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceCommand.java
new file mode 100644
index 000000000000..32b99d76456d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceCommand.java
@@ -0,0 +1,48 @@
+package com.intellij.structuralsearch.plugin.replace.ui;
+
+import com.intellij.structuralsearch.plugin.ui.SearchCommand;
+import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.openapi.project.Project;
+import com.intellij.usages.Usage;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 31, 2004
+ * Time: 3:54:03 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ReplaceCommand extends SearchCommand {
+ private final ReplaceOptions options;
+
+ public ReplaceCommand(Project project, ReplaceUsageViewContext context) {
+ super( project, context );
+ options = ((ReplaceConfiguration)context.getConfiguration()).getOptions();
+
+ }
+
+ protected void findStarted() {
+ super.findStarted();
+
+ StructuralSearchPlugin.getInstance(project).setReplaceInProgress(true);
+ }
+
+ protected void findEnded() {
+ StructuralSearchPlugin.getInstance(project).setReplaceInProgress( false );
+
+ super.findEnded();
+ }
+
+ protected void foundUsage(MatchResult result, Usage usage) {
+ super.foundUsage(result, usage);
+
+ final ReplaceUsageViewContext replaceUsageViewContext = ((ReplaceUsageViewContext)context);
+ replaceUsageViewContext.addReplaceUsage(usage,replaceUsageViewContext.getReplacer().buildReplacement(result));
+ }
+
+ public ReplaceOptions getOptions() {
+ return options;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceConfiguration.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceConfiguration.java
new file mode 100644
index 000000000000..fa9beaa36a23
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceConfiguration.java
@@ -0,0 +1,46 @@
+package com.intellij.structuralsearch.plugin.replace.ui;
+
+import org.jdom.Element;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.MatchOptions;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Apr 14, 2004
+ * Time: 4:41:37 PM
+ */
+public class ReplaceConfiguration extends Configuration {
+ private final ReplaceOptions options = new ReplaceOptions();
+ public static final String REPLACEMENT_VARIABLE_SUFFIX = "$replacement";
+
+ public ReplaceOptions getOptions() {
+ return options;
+ }
+
+ public MatchOptions getMatchOptions() {
+ return options.getMatchOptions();
+ }
+
+ public void readExternal(Element element) {
+ super.readExternal(element);
+ options.readExternal(element);
+ }
+
+ public void writeExternal(Element element) {
+ super.writeExternal(element);
+ options.writeExternal(element);
+ }
+
+ public boolean equals(Object configuration) {
+ if (!super.equals(configuration)) return false;
+ if (configuration instanceof ReplaceConfiguration) {
+ return options.equals(((ReplaceConfiguration)configuration).options);
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return options.hashCode();
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java
new file mode 100644
index 000000000000..2ae0b18469fb
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceDialog.java
@@ -0,0 +1,206 @@
+package com.intellij.structuralsearch.plugin.replace.ui;
+
+import com.intellij.codeInsight.template.impl.Variable;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.ui.Splitter;
+import com.intellij.structuralsearch.MalformedPatternException;
+import com.intellij.structuralsearch.ReplacementVariableDefinition;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.UnsupportedPatternException;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.ui.*;
+import com.intellij.util.containers.hash.LinkedHashMap;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+// Class to show the user the request for search
+
+@SuppressWarnings({"RefusedBequest"})
+public class ReplaceDialog extends SearchDialog {
+ private Editor replaceCriteriaEdit;
+ private JCheckBox shortenFQN;
+ private JCheckBox formatAccordingToStyle;
+
+ private String mySavedEditorText;
+
+ protected String getDefaultTitle() {
+ return SSRBundle.message("structural.replace.title");
+ }
+
+ protected boolean isChanged(Configuration configuration) {
+ if (super.isChanged(configuration)) return true;
+
+ String replacement;
+
+ if (configuration instanceof ReplaceConfiguration) {
+ replacement = ((ReplaceConfiguration)configuration).getOptions().getReplacement();
+ }
+ else {
+ replacement = configuration.getMatchOptions().getSearchPattern();
+ }
+
+ if (replacement == null) return false;
+
+ return !replaceCriteriaEdit.getDocument().getText().equals(replacement);
+ }
+
+ protected JComponent createEditorContent() {
+ JPanel result = new JPanel(new BorderLayout());
+ Splitter p;
+
+ result.add(BorderLayout.CENTER, p = new Splitter(true, 0.5f));
+ p.setFirstComponent(super.createEditorContent());
+
+ replaceCriteriaEdit = createEditor(searchContext, mySavedEditorText != null ? mySavedEditorText : "");
+ JPanel replace = new JPanel(new BorderLayout());
+ replace.add(BorderLayout.NORTH, new JLabel(SSRBundle.message("replacement.template.label")));
+ replace.add(BorderLayout.CENTER, replaceCriteriaEdit.getComponent());
+ replaceCriteriaEdit.getComponent().setMinimumSize(new Dimension(150, 100));
+
+ p.setSecondComponent(replace);
+
+ return result;
+ }
+
+ protected int getRowsCount() {
+ return super.getRowsCount() + 1;
+ }
+
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.structuralsearch.plugin.replace.ui.ReplaceDialog";
+ }
+
+ protected void buildOptions(JPanel searchOptions) {
+ super.buildOptions(searchOptions);
+ searchOptions
+ .add(UIUtil.createOptionLine(shortenFQN = new JCheckBox(SSRBundle.message("shorten.fully.qualified.names.checkbox"), true)));
+
+ searchOptions
+ .add(UIUtil.createOptionLine(formatAccordingToStyle = new JCheckBox(SSRBundle.message("format.according.to.style.checkbox"), true)));
+
+ }
+
+ protected UsageViewContext createUsageViewContext(Configuration configuration) {
+ return new ReplaceUsageViewContext(searchContext, configuration);
+ }
+
+ public ReplaceDialog(SearchContext searchContext) {
+ super(searchContext);
+ }
+
+ public ReplaceDialog(SearchContext searchContext, boolean showScope, boolean runFindActionOnClose) {
+ super(searchContext, showScope, runFindActionOnClose);
+ }
+
+
+ public Configuration createConfiguration() {
+ ReplaceConfiguration configuration = new ReplaceConfiguration();
+ configuration.setName(USER_DEFINED);
+ return configuration;
+ }
+
+ protected void disposeEditorContent() {
+ mySavedEditorText = replaceCriteriaEdit.getDocument().getText();
+ EditorFactory.getInstance().releaseEditor(replaceCriteriaEdit);
+ super.disposeEditorContent();
+ }
+
+ public void setValuesFromConfig(Configuration configuration) {
+ //replaceCriteriaEdit.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, configuration);
+
+ if (configuration instanceof ReplaceConfiguration) {
+ final ReplaceConfiguration config = (ReplaceConfiguration)configuration;
+ final ReplaceOptions options = config.getOptions();
+ super.setValuesFromConfig(config);
+
+ UIUtil.setContent(replaceCriteriaEdit, config.getOptions().getReplacement(), 0, replaceCriteriaEdit.getDocument().getTextLength(),
+ searchContext.getProject());
+
+ shortenFQN.setSelected(options.isToShortenFQN());
+ formatAccordingToStyle.setSelected(options.isToReformatAccordingToStyle());
+
+ ReplaceOptions newReplaceOptions = ((ReplaceConfiguration)model.getConfig()).getOptions();
+ newReplaceOptions.clearVariableDefinitions();
+
+ for (ReplacementVariableDefinition def : options.getReplacementVariableDefinitions()) {
+ newReplaceOptions.addVariableDefinition((ReplacementVariableDefinition)def.clone());
+ }
+ }
+ else {
+ super.setValuesFromConfig(configuration);
+
+ UIUtil.setContent(replaceCriteriaEdit, configuration.getMatchOptions().getSearchPattern(), 0,
+ replaceCriteriaEdit.getDocument().getTextLength(), searchContext.getProject());
+ }
+ }
+
+ protected void setValuesToConfig(Configuration config) {
+ super.setValuesToConfig(config);
+
+ final ReplaceConfiguration replaceConfiguration = (ReplaceConfiguration)config;
+ final ReplaceOptions options = replaceConfiguration.getOptions();
+
+ options.setMatchOptions(replaceConfiguration.getMatchOptions());
+ options.setReplacement(replaceCriteriaEdit.getDocument().getText());
+ options.setToShortenFQN(shortenFQN.isSelected());
+ options.setToReformatAccordingToStyle(formatAccordingToStyle.isSelected());
+ }
+
+ protected boolean isRecursiveSearchEnabled() {
+ return false;
+ }
+
+ protected java.util.List<Variable> getVariablesFromListeners() {
+ ArrayList<Variable> vars = getVarsFrom(replaceCriteriaEdit);
+ List<Variable> searchVars = super.getVariablesFromListeners();
+ Map<String, Variable> varsMap = new LinkedHashMap<String, Variable>(searchVars.size());
+
+ for(Variable var:searchVars) varsMap.put(var.getName(), var);
+ for(Variable var:vars) {
+ if (!varsMap.containsKey(var.getName())) {
+ String newVarName = var.getName() + ReplaceConfiguration.REPLACEMENT_VARIABLE_SUFFIX;
+ varsMap.put(newVarName, new Variable(newVarName, null, null, false, false));
+ }
+ }
+ return new ArrayList<Variable>(varsMap.values());
+ }
+
+ protected boolean isValid() {
+ if (!super.isValid()) return false;
+
+ try {
+ Replacer.checkSupportedReplacementPattern(searchContext.getProject(), ((ReplaceConfiguration)model.getConfig()).getOptions());
+ }
+ catch (UnsupportedPatternException ex) {
+ reportMessage("unsupported.replacement.pattern.message", replaceCriteriaEdit, ex.getMessage());
+ return false;
+ }
+ catch (MalformedPatternException ex) {
+ reportMessage("malformed.replacement.pattern.message", replaceCriteriaEdit, ex.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ public void show() {
+ replaceCriteriaEdit.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, model.getConfig());
+
+ super.show();
+ }
+
+ protected boolean isReplaceDialog() {
+ return true;
+ }
+
+ protected void addOrReplaceSelection(final String selection) {
+ super.addOrReplaceSelection(selection);
+ addOrReplaceSelectionForEditor(selection, replaceCriteriaEdit);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
new file mode 100644
index 000000000000..6a0d352d3284
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
@@ -0,0 +1,180 @@
+package com.intellij.structuralsearch.plugin.replace.ui;
+
+import com.intellij.history.LocalHistory;
+import com.intellij.history.LocalHistoryAction;
+import com.intellij.openapi.vfs.ReadonlyStatusHandler;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchCommand;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+import com.intellij.structuralsearch.plugin.ui.UsageViewContext;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.usages.Usage;
+import com.intellij.usages.UsageInfo2UsageAdapter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 9, 2005
+ * Time: 4:37:08 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class ReplaceUsageViewContext extends UsageViewContext {
+ private HashMap<Usage,ReplacementInfo> usage2ReplacementInfo;
+ private Replacer replacer;
+
+ ReplaceUsageViewContext(final SearchContext context, final Configuration configuration) {
+ super(context,configuration);
+ }
+
+ protected SearchCommand createCommand() {
+ ReplaceCommand command = new ReplaceCommand(mySearchContext.getProject(), this);
+
+ usage2ReplacementInfo = new HashMap<Usage, ReplacementInfo>();
+ replacer = new Replacer(mySearchContext.getProject(), ((ReplaceConfiguration)myConfiguration).getOptions());
+
+ return command;
+ }
+
+ protected String _getPresentableText() {
+ return SSRBundle.message("replaceusageview.text",
+ getConfiguration().getMatchOptions().getSearchPattern(),
+ ((ReplaceConfiguration)getConfiguration()).getOptions().getReplacement()
+ );
+ }
+
+ public Replacer getReplacer() {
+ return replacer;
+ }
+
+ public void addReplaceUsage(final Usage usage, final ReplacementInfo replacementInfo) {
+ usage2ReplacementInfo.put(usage,replacementInfo);
+ }
+
+ private boolean isValid(UsageInfo2UsageAdapter info) {
+ final UsageInfo usageInfo = info.getUsageInfo();
+ return !isExcluded(info) && usageInfo.getElement() != null && usageInfo.getElement().isValid();
+ }
+
+ @Override
+ protected void configureActions() {
+ final Runnable replaceRunnable = new Runnable() {
+ public void run() {
+ LocalHistoryAction labelAction = LocalHistory.getInstance().startAction(SSRBundle.message("structural.replace.title"));
+
+ doReplace();
+ getUsageView().close();
+
+ labelAction.finish();
+ }
+ };
+
+ //noinspection HardCodedStringLiteral
+ getUsageView().addPerformOperationAction(replaceRunnable, "Replace All", null, SSRBundle.message("do.replace.all.button"));
+
+ final Runnable replaceSelected = new Runnable() {
+ public void run() {
+ final Set<Usage> infos = getUsageView().getSelectedUsages();
+ if (infos == null || infos.isEmpty()) return;
+
+ LocalHistoryAction labelAction = LocalHistory.getInstance().startAction(SSRBundle.message("structural.replace.title"));
+
+ for (final Usage info : infos) {
+ final UsageInfo2UsageAdapter usage = (UsageInfo2UsageAdapter)info;
+
+ if (isValid(usage)) {
+ replaceOne(usage, false);
+ }
+ }
+
+ labelAction.finish();
+
+ if (getUsageView().getUsagesCount() > 0) {
+ for (Usage usage : getUsageView().getSortedUsages()) {
+ if (!isExcluded(usage)) {
+ getUsageView().selectUsages(new Usage[]{usage});
+ return;
+ }
+ }
+ }
+ }
+ };
+
+ getUsageView().addButtonToLowerPane(replaceSelected, SSRBundle.message("replace.selected.button"));
+
+ final Runnable previewReplacement = new Runnable() {
+ public void run() {
+ Set<Usage> selection = getUsageView().getSelectedUsages();
+
+ if (selection != null && !selection.isEmpty()) {
+ UsageInfo2UsageAdapter usage = (UsageInfo2UsageAdapter)selection.iterator().next();
+
+ if (isValid(usage)) {
+ replaceOne(usage, true);
+ }
+ }
+ }
+ };
+
+ getUsageView().addButtonToLowerPane(previewReplacement, SSRBundle.message("preview.replacement.button"));
+
+ super.configureActions();
+ }
+
+ private static void ensureFileWritable(final UsageInfo2UsageAdapter usage) {
+ final VirtualFile file = usage.getFile();
+
+ if (file != null && !file.isWritable()) {
+ ReadonlyStatusHandler.getInstance(usage.getElement().getProject()).ensureFilesWritable(file);
+ }
+ }
+
+ private void replaceOne(UsageInfo2UsageAdapter info, boolean doConfirm) {
+ ReplacementInfo replacementInfo = usage2ReplacementInfo.get(info);
+ boolean approved;
+
+ if (doConfirm) {
+ ReplacementPreviewDialog wrapper =
+ new ReplacementPreviewDialog(mySearchContext.getProject(), info.getUsageInfo(), replacementInfo.getReplacement());
+
+ wrapper.show();
+ approved = wrapper.isOK();
+ }
+ else {
+ approved = true;
+ }
+
+ if (approved) {
+ ensureFileWritable(info);
+ getUsageView().removeUsage(info);
+ getReplacer().replace(replacementInfo);
+
+ if (getUsageView().getUsagesCount() == 0) {
+ getUsageView().close();
+ }
+ }
+ }
+
+ private void doReplace() {
+ List<Usage> infos = getUsageView().getSortedUsages();
+ List<ReplacementInfo> results = new ArrayList<ReplacementInfo>(infos.size());
+
+ for (final Usage info : infos) {
+ UsageInfo2UsageAdapter usage = (UsageInfo2UsageAdapter)info;
+
+ if (isValid(usage)) {
+ results.add(usage2ReplacementInfo.get(usage));
+ }
+ }
+
+ getReplacer().replaceAll(results);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplacementPreviewDialog.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplacementPreviewDialog.java
new file mode 100644
index 000000000000..5bec5a920b45
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplacementPreviewDialog.java
@@ -0,0 +1,132 @@
+package com.intellij.structuralsearch.plugin.replace.ui;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.HighlighterLayer;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
+import com.intellij.openapi.editor.markup.RangeHighlighter;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Segment;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.plugin.ui.UIUtil;
+import com.intellij.usageView.UsageInfo;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * Navigates through the search results
+ */
+public final class ReplacementPreviewDialog extends DialogWrapper {
+ private final FileType myFileType;
+ private Editor replacement;
+
+ private final Project project;
+ private RangeHighlighter hilighter;
+ private Editor editor;
+
+
+ public ReplacementPreviewDialog(final Project project, UsageInfo info, String replacementString) {
+ super(project,true);
+
+ setTitle(SSRBundle.message("structural.replace.preview.dialog.title"));
+ setOKButtonText(SSRBundle.message("replace.preview.oktext"));
+ this.project = project;
+ final PsiElement element = info.getElement();
+ final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element);
+ myFileType = virtualFile != null ? virtualFile.getFileType() : FileTypes.PLAIN_TEXT;
+ init();
+
+ Segment range = info.getSegment();
+ hilight(virtualFile, range.getStartOffset(), range.getEndOffset());
+ UIUtil.setContent(replacement, replacementString,0,-1,project);
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
+ if (profile != null) {
+ UIUtil.updateHighlighter(replacement, profile);
+ }
+ }
+
+ private void hilight(VirtualFile file,int start, int end) {
+ removeHilighter();
+
+ editor = FileEditorManager.getInstance(project).openTextEditor(
+ new OpenFileDescriptor(project, file),
+ false
+ );
+ hilighter = editor.getMarkupModel().addRangeHighlighter(
+ start,
+ end,
+ HighlighterLayer.SELECTION - 100,
+ EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES),
+ HighlighterTargetArea.EXACT_RANGE
+ );
+ }
+
+ private void removeHilighter() {
+ if (hilighter!=null && hilighter.isValid()) {
+ hilighter.dispose();
+ hilighter = null;
+ editor = null;
+ }
+ }
+
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.strucuturalsearch.plugin.replace.ReplacementPreviewDialog";
+ }
+
+ protected JComponent createCenterPanel() {
+ JComponent centerPanel = new JPanel( new BorderLayout() );
+
+ PsiFile file = null;
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(myFileType);
+ if (profile != null) {
+ file = profile.createCodeFragment(project, "", null);
+ }
+
+ if (file != null) {
+ final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+ replacement = UIUtil.createEditor(document, project, true, null);
+ DaemonCodeAnalyzer.getInstance(project).setHighlightingEnabled(file,false);
+ } else {
+ final EditorFactory factory = EditorFactory.getInstance();
+ final Document document = factory.createDocument("");
+ replacement = factory.createEditor(document, project, myFileType, false);
+ }
+
+ centerPanel.add(BorderLayout.NORTH,new JLabel(SSRBundle.message("replacement.code")) );
+ centerPanel.add(BorderLayout.CENTER,replacement.getComponent() );
+ centerPanel.setMaximumSize(new Dimension(640,480));
+
+ return centerPanel;
+ }
+
+ public void dispose() {
+ final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(replacement.getDocument());
+ if (file != null) {
+ DaemonCodeAnalyzer.getInstance(project).setHighlightingEnabled(file, true);
+ }
+
+ EditorFactory.getInstance().releaseEditor(replacement);
+ removeHilighter();
+
+ super.dispose();
+ }
+}
+
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/Configuration.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/Configuration.java
new file mode 100644
index 000000000000..440d33164f1d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/Configuration.java
@@ -0,0 +1,87 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.structuralsearch.MatchOptions;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 14, 2004
+ * Time: 5:29:37 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public abstract class Configuration implements JDOMExternalizable, Comparable<Configuration> {
+ public static final Configuration[] EMPTY_ARRAY = {};
+ @NonNls protected static final String NAME_ATTRIBUTE_NAME = "name";
+ private String name = "";
+ private String category = null;
+ private boolean predefined;
+
+ private static ConfigurationCreator configurationCreator;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String value) {
+ name = value;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public void readExternal(Element element) {
+ name = element.getAttributeValue(NAME_ATTRIBUTE_NAME);
+ }
+
+ public void writeExternal(Element element) {
+ element.setAttribute(NAME_ATTRIBUTE_NAME,name);
+ }
+
+ public boolean isPredefined() {
+ return predefined;
+ }
+
+ public void setPredefined(boolean predefined) {
+ this.predefined = predefined;
+ }
+
+ public abstract MatchOptions getMatchOptions();
+
+ @Override
+ public int compareTo(Configuration other) {
+ int result = StringUtil.naturalCompare(getCategory(), other.getCategory());
+ return result != 0 ? result : StringUtil.naturalCompare(getName(), other.getName());
+ }
+
+ public boolean equals(Object configuration) {
+ if (!(configuration instanceof Configuration)) return false;
+ Configuration other = (Configuration)configuration;
+ if (category != null ? !category.equals(other.category) : other.category != null) {
+ return false;
+ }
+ return name.equals(other.name);
+ }
+
+ public int hashCode() {
+ return getMatchOptions().hashCode();
+ }
+
+ public static void setActiveCreator(ConfigurationCreator creator) {
+ configurationCreator = creator;
+ }
+
+ public static ConfigurationCreator getConfigurationCreator() {
+ return configurationCreator;
+ }
+
+ @NonNls public static final String CONTEXT_VAR_NAME = "__context__";
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationCreator.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationCreator.java
new file mode 100644
index 000000000000..74332fd72e74
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationCreator.java
@@ -0,0 +1,12 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 21, 2004
+ * Time: 7:46:16 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface ConfigurationCreator {
+ Configuration createConfiguration();
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java
new file mode 100644
index 000000000000..151e78d6863f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ConfigurationManager.java
@@ -0,0 +1,179 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.NonEmptyInputValidator;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 10.02.2004
+ * Time: 14:29:45
+ * To change this template use File | Settings | File Templates.
+ */
+public class ConfigurationManager {
+ @NonNls static final String SEARCH_TAG_NAME = "searchConfiguration";
+ @NonNls static final String REPLACE_TAG_NAME = "replaceConfiguration";
+ @NonNls private static final String SAVE_HISTORY_ATTR_NAME = "history";
+
+ private List<Configuration> configurations;
+ private LinkedList<Configuration> historyConfigurations;
+
+ public void addHistoryConfigurationToFront(Configuration configuration) {
+ if (historyConfigurations == null) historyConfigurations = new LinkedList<Configuration>();
+
+ if (historyConfigurations.indexOf(configuration) == -1) {
+ historyConfigurations.addFirst(configuration);
+ }
+ }
+
+ public void removeHistoryConfiguration(Configuration configuration) {
+ if (historyConfigurations != null) {
+ historyConfigurations.remove(configuration);
+ }
+ }
+
+ public void addConfiguration(Configuration configuration) {
+ if (configurations == null) configurations = new ArrayList<Configuration>();
+
+ if (configurations.indexOf(configuration) == -1) {
+ configurations.add(configuration);
+ }
+ }
+
+ public void removeConfiguration(Configuration configuration) {
+ if (configurations != null) {
+ configurations.remove(configuration);
+ }
+ }
+
+ public void saveConfigurations(Element element) {
+ writeConfigurations(element, configurations, historyConfigurations);
+ }
+
+ public static void writeConfigurations(final Element element,
+ final Collection<Configuration> configurations,
+ final Collection<Configuration> historyConfigurations) {
+ if (configurations != null) {
+ for (final Configuration configuration : configurations) {
+ saveConfiguration(element, configuration);
+ }
+ }
+
+ if (historyConfigurations != null) {
+ for (final Configuration historyConfiguration : historyConfigurations) {
+ final Element infoElement = saveConfiguration(element, historyConfiguration);
+ infoElement.setAttribute(SAVE_HISTORY_ATTR_NAME, "1");
+ }
+ }
+ }
+
+ public static Element saveConfiguration(Element element, final Configuration config) {
+ Element infoElement = new Element(config instanceof SearchConfiguration ? SEARCH_TAG_NAME : REPLACE_TAG_NAME);
+ element.addContent(infoElement);
+ config.writeExternal(infoElement);
+
+ return infoElement;
+ }
+
+ public void loadConfigurations(Element element) {
+ if (configurations != null) return;
+ ArrayList<Configuration> configurations = new ArrayList<Configuration>();
+ ArrayList<Configuration> historyConfigurations = new ArrayList<Configuration>();
+ readConfigurations(element, configurations, historyConfigurations);
+ for (Configuration configuration : historyConfigurations) {
+ addHistoryConfigurationToFront(configuration);
+ }
+ for (Configuration configuration : configurations) {
+ addConfiguration(configuration);
+ }
+ if (this.historyConfigurations != null) {
+ Collections.reverse(this.historyConfigurations);
+ }
+ }
+
+ public static void readConfigurations(final Element element, @NotNull Collection<Configuration> configurations, @NotNull Collection<Configuration> historyConfigurations) {
+ final List<Element> patterns = element.getChildren();
+
+ if (patterns != null && patterns.size() > 0) {
+ for (final Element pattern : patterns) {
+ final Configuration config = readConfiguration(pattern);
+ if (config == null) continue;
+
+ if (pattern.getAttribute(SAVE_HISTORY_ATTR_NAME) != null) {
+ historyConfigurations.add(config);
+ }
+ else {
+ configurations.add(config);
+ }
+ }
+ }
+ }
+
+ public static Configuration readConfiguration(final Element childElement) {
+ String s = childElement.getName();
+ final Configuration config =
+ s.equals(SEARCH_TAG_NAME) ? new SearchConfiguration() : s.equals(REPLACE_TAG_NAME) ? new ReplaceConfiguration():null;
+ if (config != null) config.readExternal(childElement);
+ return config;
+ }
+
+ public Collection<Configuration> getConfigurations() {
+ return configurations;
+ }
+
+ public static Configuration findConfigurationByName(final Collection<Configuration> configurations, final String name) {
+ for(Configuration config:configurations) {
+ if (config.getName().equals(name)) return config;
+ }
+
+ return null;
+ }
+
+ public Collection<Configuration> getHistoryConfigurations() {
+ return historyConfigurations;
+ }
+
+ public static @Nullable String findAppropriateName(@NotNull final Collection<Configuration> configurations, @NotNull String _name,
+ @NotNull final Project project) {
+ Configuration config;
+ String name = _name;
+
+ while ((config = findConfigurationByName(configurations, name)) != null) {
+ int i = Messages.showYesNoDialog(
+ project,
+ SSRBundle.message("overwrite.message"),
+ SSRBundle.message("overwrite.title"),
+ AllIcons.General.QuestionDialog
+ );
+
+ if (i == Messages.YES) {
+ configurations.remove(config);
+ break;
+ }
+ name = showSaveTemplateAsDialog(name, project);
+ if (name == null) break;
+ }
+ return name;
+ }
+
+ public static @Nullable String showSaveTemplateAsDialog(@NotNull String initial, @NotNull Project project) {
+ return Messages.showInputDialog(
+ project,
+ SSRBundle.message("template.name.button"),
+ SSRBundle.message("save.template.description.button"),
+ AllIcons.General.QuestionDialog,
+ initial,
+ new NonEmptyInputValidator()
+ );
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
new file mode 100644
index 000000000000..83d93ba0d05c
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
@@ -0,0 +1,152 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.openapi.MnemonicHelper;
+import com.intellij.CommonBundle;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.InputEvent;
+import java.awt.*;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Base dialog class
+ */
+public abstract class DialogBase extends JDialog {
+ private JButton ok;
+ private JButton cancel;
+
+ private Action okAction;
+ private Action cancelAction;
+ private static Rectangle virtualBounds;
+
+ class OkAction extends AbstractAction {
+ OkAction() {
+ putValue(NAME, CommonBundle.getOkButtonText());
+ }
+ public void actionPerformed(ActionEvent e) {
+ doOKAction();
+ }
+ }
+
+ class CancelAction extends AbstractAction {
+ CancelAction() {
+ putValue(NAME,CommonBundle.getCancelButtonText());
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ doCancelAction();
+ }
+ }
+
+ protected DialogBase() {
+ this(null);
+ }
+
+ protected DialogBase(Frame frame) {
+ this(frame,true);
+ }
+
+ protected DialogBase(Frame frame,boolean modal) {
+ super(frame,modal);
+
+ new MnemonicHelper().register(getContentPane());
+
+ okAction = new OkAction();
+ cancelAction = new CancelAction();
+
+ ok = createJButtonForAction(okAction);
+ cancel = createJButtonForAction(cancelAction);
+
+ if (virtualBounds == null) {
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice[] gs = ge.getScreenDevices();
+ virtualBounds = new Rectangle();
+
+ for (int j = 0; j < gs.length; j++) {
+ GraphicsDevice gd = gs[j];
+ GraphicsConfiguration[] gc = gd.getConfigurations();
+
+ for (int i=0; i < gc.length; i++) {
+ virtualBounds = virtualBounds.union(gc[i].getBounds());
+ }
+ }
+ }
+
+ @NonNls String cancelCommandName = "close";
+ KeyStroke escKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
+ ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escKeyStroke, cancelCommandName);
+ ok.getActionMap().put(cancelCommandName, cancelAction);
+
+ @NonNls String startCommandName = "start";
+ KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,InputEvent.CTRL_MASK);
+ ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, startCommandName);
+ ok.getActionMap().put(startCommandName, okAction);
+ }
+
+ protected JButton getCancelButton() {
+ return cancel;
+ }
+
+ protected JButton getOkButton() {
+ return ok;
+ }
+
+ protected abstract JComponent createCenterPanel();
+
+ protected JComponent createSouthPanel() {
+ JPanel p = new JPanel( null );
+ p.setLayout( new BoxLayout(p,BoxLayout.X_AXIS) );
+ p.add(Box.createHorizontalGlue());
+ p.add(getOkButton());
+ p.add(getCancelButton());
+ return p;
+ }
+
+ public void init() {
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(BorderLayout.CENTER,createCenterPanel());
+ getContentPane().add(BorderLayout.SOUTH,createSouthPanel());
+ pack();
+
+ Dimension dim = getPreferredSize();
+ setLocation(
+ (int)(virtualBounds.getWidth()/2 - dim.getWidth()/2),
+ (int)(virtualBounds.getHeight()/2 - dim.getHeight()/2)
+ );
+ }
+
+ public void show() {
+ pack();
+ super.show();
+ }
+
+ protected void doCancelAction() {
+ setVisible(false);
+ }
+
+ protected void doOKAction() {
+ setVisible(false);
+ }
+
+ protected void setOKActionEnabled(boolean b) {
+ okAction.setEnabled(b);
+ }
+
+ protected void setOKButtonText(String text) {
+ okAction.putValue(Action.NAME,text);
+ }
+
+ protected void setCancelButtonText(String text) {
+ cancelAction.putValue(Action.NAME,text);
+ }
+
+ protected JButton createJButtonForAction(Action _action) {
+ JButton jb = new JButton( (String)_action.getValue(Action.NAME) );
+ jb.setAction(_action);
+
+ return jb;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
new file mode 100644
index 000000000000..368240ff50be
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
@@ -0,0 +1,635 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.codeInsight.template.impl.Variable;
+import com.intellij.find.impl.RegExHelpPopup;
+import com.intellij.ide.highlighter.HighlighterFactory;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.EditorSettings;
+import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComponentWithBrowseButton;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.structuralsearch.MatchVariableConstraint;
+import com.intellij.structuralsearch.NamedScriptableDefinition;
+import com.intellij.structuralsearch.ReplacementVariableDefinition;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import com.intellij.ui.ComboboxWithBrowseButton;
+import com.intellij.ui.EditorTextField;
+import com.intellij.ui.components.labels.LinkLabel;
+import com.intellij.ui.components.labels.LinkListener;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.text.BadLocationException;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Mar 25, 2004
+ * Time: 1:52:18 PM
+ */
+class EditVarConstraintsDialog extends DialogWrapper {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog");
+
+ private JTextField maxoccurs;
+ private JCheckBox applyWithinTypeHierarchy;
+ private JCheckBox notRegexp;
+ private EditorTextField regexp;
+ private JTextField minoccurs;
+ private JPanel mainForm;
+ private JCheckBox notWrite;
+ private JCheckBox notRead;
+ private JCheckBox write;
+ private JCheckBox read;
+ private JList parameterList;
+ private JCheckBox partOfSearchResults;
+ private JCheckBox notExprType;
+ private EditorTextField regexprForExprType;
+ private final SearchModel model;
+ private JCheckBox exprTypeWithinHierarchy;
+
+ private final List<Variable> variables;
+ private Variable current;
+ private JCheckBox wholeWordsOnly;
+ private JCheckBox formalArgTypeWithinHierarchy;
+ private JCheckBox invertFormalArgType;
+ private EditorTextField formalArgType;
+ private ComponentWithBrowseButton<EditorTextField> customScriptCode;
+ private JCheckBox maxoccursUnlimited;
+
+ private ComboboxWithBrowseButton withinCombo;
+ private JPanel containedInConstraints;
+ private JCheckBox invertWithinIn;
+ private JPanel expressionConstraints;
+ private JPanel occurencePanel;
+ private JPanel textConstraintsPanel;
+ private JLabel myRegExHelpLabel;
+
+ private static Project myProject;
+
+ EditVarConstraintsDialog(final Project project,SearchModel _model,List<Variable> _variables, boolean replaceContext, FileType fileType) {
+ super(project, false);
+
+ variables = _variables;
+ model = _model;
+
+ setTitle(SSRBundle.message("editvarcontraints.edit.variables"));
+
+ regexp.getDocument().addDocumentListener(new MyDocumentListener(notRegexp, applyWithinTypeHierarchy, wholeWordsOnly));
+ read.addChangeListener(new MyChangeListener(notRead, false));
+ write.addChangeListener(new MyChangeListener(notWrite, false));
+ regexprForExprType.getDocument().addDocumentListener(new MyDocumentListener(exprTypeWithinHierarchy, notExprType));
+ formalArgType.getDocument().addDocumentListener(new MyDocumentListener(formalArgTypeWithinHierarchy, invertFormalArgType));
+
+ partOfSearchResults.setEnabled(!replaceContext); // todo: this doesn't do anything
+ containedInConstraints.setVisible(false);
+ withinCombo.getComboBox().setEditable(true);
+
+ withinCombo.getButton().addActionListener(new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ final SelectTemplateDialog dialog = new SelectTemplateDialog(project, false, false);
+ dialog.show();
+ if (dialog.getExitCode() == OK_EXIT_CODE) {
+ final Configuration[] selectedConfigurations = dialog.getSelectedConfigurations();
+ if (selectedConfigurations.length == 1) {
+ withinCombo.getComboBox().getEditor().setItem(selectedConfigurations[0].getMatchOptions().getSearchPattern()); // TODO:
+ }
+ }
+ }
+ });
+
+ boolean hasContextVar = false;
+ for(Variable var:variables) {
+ if (Configuration.CONTEXT_VAR_NAME.equals(var.getName())) {
+ hasContextVar = true; break;
+ }
+ }
+
+ if (!hasContextVar) {
+ variables.add(new Variable(Configuration.CONTEXT_VAR_NAME, "", "", true));
+ }
+
+ if (fileType == StdFileTypes.JAVA) {
+
+ formalArgTypeWithinHierarchy.setEnabled(true);
+ invertFormalArgType.setEnabled(true);
+ formalArgType.setEnabled(true);
+
+ exprTypeWithinHierarchy.setEnabled(true);
+ notExprType.setEnabled(true);
+ regexprForExprType.setEnabled(true);
+
+ read.setEnabled(true);
+ notRead.setEnabled(false);
+ write.setEnabled(true);
+ notWrite.setEnabled(false);
+
+ applyWithinTypeHierarchy.setEnabled(true);
+ } else {
+ formalArgTypeWithinHierarchy.setEnabled(false);
+ invertFormalArgType.setEnabled(false);
+ formalArgType.setEnabled(false);
+
+ exprTypeWithinHierarchy.setEnabled(false);
+ notExprType.setEnabled(false);
+ regexprForExprType.setEnabled(false);
+
+ read.setEnabled(false);
+ notRead.setEnabled(false);
+ write.setEnabled(false);
+ notWrite.setEnabled(false);
+
+ applyWithinTypeHierarchy.setEnabled(false);
+ }
+
+ parameterList.setModel(
+ new AbstractListModel() {
+ public Object getElementAt(int index) {
+ return variables.get(index);
+ }
+
+ public int getSize() {
+ return variables.size();
+ }
+ }
+ );
+
+ parameterList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
+
+ parameterList.getSelectionModel().addListSelectionListener(
+ new ListSelectionListener() {
+ boolean rollingBackSelection;
+
+ public void valueChanged(ListSelectionEvent e) {
+ if (e.getValueIsAdjusting()) return;
+ if (rollingBackSelection) {
+ rollingBackSelection=false;
+ return;
+ }
+ final Variable var = variables.get(parameterList.getSelectedIndex());
+ if (validateParameters()) {
+ if (current!=null) copyValuesFromUI(current);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { copyValuesToUI(var); }});
+ current = var;
+ } else {
+ rollingBackSelection = true;
+ parameterList.setSelectedIndex(e.getFirstIndex()==parameterList.getSelectedIndex()?e.getLastIndex():e.getFirstIndex());
+ }
+ }
+ }
+ );
+
+ parameterList.setCellRenderer(
+ new DefaultListCellRenderer() {
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ String name = ((Variable)value).getName();
+ if (Configuration.CONTEXT_VAR_NAME.equals(name)) name = SSRBundle.message("complete.match.variable.name");
+ if (isReplacementVariable(name)) {
+ name = stripReplacementVarDecoration(name);
+ }
+ return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
+ }
+ }
+ );
+
+ maxoccursUnlimited.addChangeListener(new MyChangeListener(maxoccurs, true));
+
+ customScriptCode.getButton().addActionListener(new ActionListener() {
+ public void actionPerformed(final ActionEvent e) {
+ final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText());
+ dialog.show();
+ if (dialog.getExitCode() == OK_EXIT_CODE) {
+ customScriptCode.getChildComponent().setText(dialog.getScriptText());
+ }
+ }
+ });
+ init();
+
+ if (variables.size() > 0) parameterList.setSelectedIndex(0);
+ }
+
+ private static String stripReplacementVarDecoration(String name) {
+ name = name.substring(0, name.length() - ReplaceConfiguration.REPLACEMENT_VARIABLE_SUFFIX.length());
+ return name;
+ }
+
+ private static boolean isReplacementVariable(String name) {
+ return name.endsWith(ReplaceConfiguration.REPLACEMENT_VARIABLE_SUFFIX);
+ }
+
+ private boolean validateParameters() {
+ return validateRegExp(regexp) && validateRegExp(regexprForExprType) &&
+ validateIntOccurence(minoccurs) &&
+ validateScript(customScriptCode.getChildComponent()) &&
+ (maxoccursUnlimited.isSelected() || validateIntOccurence(maxoccurs));
+ }
+
+ protected JComponent createCenterPanel() {
+ return mainForm;
+ }
+
+ protected void doOKAction() {
+ if(validateParameters()) {
+ if (current!=null) copyValuesFromUI(current);
+ super.doOKAction();
+ }
+ }
+
+ void copyValuesFromUI(Variable var) {
+ String varName = var.getName();
+ Configuration configuration = model.getConfig();
+
+ if (isReplacementVariable(varName)) {
+ saveScriptInfo(getOrAddReplacementVariableDefinition(varName, configuration));
+ return;
+ }
+
+ MatchVariableConstraint varInfo = getOrAddVariableConstraint(varName, configuration);
+
+ varInfo.setInvertReadAccess(notRead.isSelected());
+ varInfo.setReadAccess(read.isSelected());
+ varInfo.setInvertWriteAccess(notWrite.isSelected());
+ varInfo.setWriteAccess(write.isSelected());
+ varInfo.setRegExp(regexp.getDocument().getText());
+ varInfo.setInvertRegExp(notRegexp.isSelected());
+
+ int minCount = Integer.parseInt( minoccurs.getText() );
+ varInfo.setMinCount(minCount);
+
+ int maxCount;
+ if (maxoccursUnlimited.isSelected()) maxCount = Integer.MAX_VALUE;
+ else maxCount = Integer.parseInt( maxoccurs.getText() );
+
+ varInfo.setMaxCount(maxCount);
+ varInfo.setWithinHierarchy(applyWithinTypeHierarchy.isSelected());
+ varInfo.setInvertRegExp(notRegexp.isSelected());
+
+ varInfo.setPartOfSearchResults(partOfSearchResults.isEnabled() && partOfSearchResults.isSelected());
+
+ varInfo.setInvertExprType(notExprType.isSelected());
+ varInfo.setNameOfExprType(regexprForExprType.getDocument().getText());
+ varInfo.setExprTypeWithinHierarchy(exprTypeWithinHierarchy.isSelected());
+ varInfo.setWholeWordsOnly(wholeWordsOnly.isSelected());
+ varInfo.setInvertFormalType(invertFormalArgType.isSelected());
+ varInfo.setFormalArgTypeWithinHierarchy(formalArgTypeWithinHierarchy.isSelected());
+ varInfo.setNameOfFormalArgType(formalArgType.getDocument().getText());
+ saveScriptInfo(varInfo);
+
+ final String withinConstraint = (String)withinCombo.getComboBox().getEditor().getItem();
+ varInfo.setWithinConstraint(withinConstraint.length() > 0 ? "\"" + withinConstraint +"\"":"");
+ varInfo.setInvertWithinConstraint(invertWithinIn.isSelected());
+ }
+
+ private static MatchVariableConstraint getOrAddVariableConstraint(String varName, Configuration configuration) {
+ MatchVariableConstraint varInfo = configuration.getMatchOptions().getVariableConstraint(varName);
+
+ if (varInfo == null) {
+ varInfo = new MatchVariableConstraint();
+ varInfo.setName(varName);
+ configuration.getMatchOptions().addVariableConstraint(varInfo);
+ }
+ return varInfo;
+ }
+
+ private static ReplacementVariableDefinition getOrAddReplacementVariableDefinition(String varName, Configuration configuration) {
+ ReplaceOptions replaceOptions = ((ReplaceConfiguration)configuration).getOptions();
+ String realVariableName = stripReplacementVarDecoration(varName);
+ ReplacementVariableDefinition variableDefinition = replaceOptions.getVariableDefinition(realVariableName);
+
+ if (variableDefinition == null) {
+ variableDefinition = new ReplacementVariableDefinition();
+ variableDefinition.setName(realVariableName);
+ replaceOptions.addVariableDefinition(variableDefinition);
+ }
+ return variableDefinition;
+ }
+
+ private void saveScriptInfo(NamedScriptableDefinition varInfo) {
+ varInfo.setScriptCodeConstraint("\"" + customScriptCode.getChildComponent().getText() + "\"");
+ }
+
+ private void copyValuesToUI(Variable var) {
+ Configuration configuration = model.getConfig();
+ String varName = var.getName();
+
+ if (isReplacementVariable(varName)) {
+ ReplacementVariableDefinition definition = ((ReplaceConfiguration)configuration).getOptions().getVariableDefinition(
+ stripReplacementVarDecoration(varName)
+ );
+
+ restoreScriptCode(definition);
+ setSearchConstraintsVisible(false);
+ return;
+ } else {
+ setSearchConstraintsVisible(true);
+ }
+
+ MatchVariableConstraint varInfo = configuration.getMatchOptions().getVariableConstraint(varName);
+
+ if (varInfo == null) {
+ notRead.setSelected(false);
+ notRegexp.setSelected(false);
+ read.setSelected(false);
+ notWrite.setSelected(false);
+ write.setSelected(false);
+ regexp.getDocument().setText("");
+
+ minoccurs.setText("1");
+ maxoccurs.setText("1");
+ maxoccursUnlimited.setSelected(false);
+ applyWithinTypeHierarchy.setSelected(false);
+ partOfSearchResults.setSelected(false);
+
+ regexprForExprType.getDocument().setText("");
+ notExprType.setSelected(false);
+ exprTypeWithinHierarchy.setSelected(false);
+ wholeWordsOnly.setSelected(false);
+
+ invertFormalArgType.setSelected(false);
+ formalArgTypeWithinHierarchy.setSelected(false);
+ formalArgType.getDocument().setText("");
+ customScriptCode.getChildComponent().setText("");
+
+ withinCombo.getComboBox().getEditor().setItem("");
+ invertWithinIn.setSelected(false);
+ } else {
+ notRead.setSelected(varInfo.isInvertReadAccess());
+ read.setSelected(varInfo.isReadAccess());
+ notWrite.setSelected(varInfo.isInvertWriteAccess());
+ write.setSelected(varInfo.isWriteAccess());
+
+ applyWithinTypeHierarchy.setSelected(varInfo.isWithinHierarchy());
+ regexp.getDocument().setText(varInfo.getRegExp());
+ //doProcessing(applyWithinTypeHierarchy,regexp);
+
+ notRegexp.setSelected(varInfo.isInvertRegExp());
+ minoccurs.setText(Integer.toString(varInfo.getMinCount()));
+
+ if(varInfo.getMaxCount() == Integer.MAX_VALUE) {
+ maxoccursUnlimited.setSelected(true);
+ maxoccurs.setText("");
+ } else {
+ maxoccursUnlimited.setSelected(false);
+ maxoccurs.setText(Integer.toString(varInfo.getMaxCount()));
+ }
+
+ partOfSearchResults.setSelected( partOfSearchResults.isEnabled() && varInfo.isPartOfSearchResults() );
+
+ exprTypeWithinHierarchy.setSelected(varInfo.isExprTypeWithinHierarchy());
+ regexprForExprType.getDocument().setText(varInfo.getNameOfExprType());
+
+ notExprType.setSelected( varInfo.isInvertExprType() );
+ wholeWordsOnly.setSelected( varInfo.isWholeWordsOnly() );
+
+ invertFormalArgType.setSelected( varInfo.isInvertFormalType() );
+ formalArgTypeWithinHierarchy.setSelected(varInfo.isFormalArgTypeWithinHierarchy());
+ formalArgType.getDocument().setText(varInfo.getNameOfFormalArgType());
+ restoreScriptCode(varInfo);
+
+ withinCombo.getComboBox().getEditor().setItem(StringUtil.stripQuotesAroundValue(varInfo.getWithinConstraint()));
+ invertWithinIn.setSelected(varInfo.isInvertWithinConstraint());
+ }
+
+ boolean isExprContext = true;
+ final boolean contextVar = Configuration.CONTEXT_VAR_NAME.equals(var.getName());
+ if (contextVar) isExprContext = false;
+ containedInConstraints.setVisible(contextVar);
+ expressionConstraints.setVisible(isExprContext);
+ partOfSearchResults.setEnabled(!contextVar); //?
+
+ occurencePanel.setVisible(!contextVar);
+ }
+
+ private void setSearchConstraintsVisible(boolean b) {
+ textConstraintsPanel.setVisible(b);
+ occurencePanel.setVisible(b);
+ expressionConstraints.setVisible(b);
+ partOfSearchResults.setVisible(b);
+ containedInConstraints.setVisible(b);
+ pack();
+ }
+
+ private void restoreScriptCode(NamedScriptableDefinition varInfo) {
+ customScriptCode.getChildComponent().setText(
+ varInfo != null ? StringUtil.stripQuotesAroundValue(varInfo.getScriptCodeConstraint()) : "");
+ }
+
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog";
+ }
+
+ private static boolean validateRegExp(EditorTextField field) {
+ try {
+ final String s = field.getDocument().getText();
+ if (s.length() > 0) {
+ Pattern.compile(s);
+ }
+ } catch(PatternSyntaxException ex) {
+ Messages.showErrorDialog(SSRBundle.message("invalid.regular.expression"), SSRBundle.message("invalid.regular.expression"));
+ field.requestFocus();
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean validateScript(EditorTextField field) {
+ final String text = field.getText();
+
+ if (text.length() > 0) {
+ final String message = ScriptSupport.checkValidScript(text);
+
+ if (message != null) {
+ Messages.showErrorDialog(message, SSRBundle.message("invalid.groovy.script"));
+ field.requestFocus();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean validateIntOccurence(JTextField field) {
+ try {
+ int a = Integer.parseInt(field.getText());
+ if (a==-1) throw new NumberFormatException();
+ } catch(NumberFormatException ex) {
+ Messages.showErrorDialog(SSRBundle.message("invalid.occurence.count"), SSRBundle.message("invalid.occurence.count"));
+ field.requestFocus();
+ return false;
+ }
+ return true;
+ }
+
+ @NotNull
+ protected Action[] createActions() {
+ return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
+ }
+
+ protected void doHelpAction() {
+ HelpManager.getInstance().invokeHelp("reference.dialogs.search.replace.structural.editvariable");
+ }
+
+ private void createUIComponents() {
+ regexp = createRegexComponent();
+ regexprForExprType = createRegexComponent();
+ formalArgType = createRegexComponent();
+ customScriptCode = new ComponentWithBrowseButton<EditorTextField>(createScriptComponent(), null);
+
+ myRegExHelpLabel = new LinkLabel(SSRBundle.message("regular.expression.help.label"), null, new LinkListener() {
+ public void linkSelected(LinkLabel aSource, Object aLinkData) {
+ try {
+ final JBPopup helpPopup = RegExHelpPopup.createRegExHelpPopup();
+ helpPopup.showInCenterOf(mainForm);
+ }
+ catch (BadLocationException e) {
+ LOG.info(e);
+ }
+ }
+ });
+
+ myRegExHelpLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
+ }
+
+ private static EditorTextField createRegexComponent() {
+ @NonNls final String fileName = "1.regexp";
+ final FileType fileType = getFileType(fileName);
+ final Document doc = createDocument(fileName, fileType, "");
+ return new EditorTextField(doc, myProject, fileType);
+ }
+
+ private static EditorTextField createScriptComponent() {
+ @NonNls final String fileName = "1.groovy";
+ final FileType fileType = getFileType(fileName);
+ final Document doc = createDocument(fileName, fileType, "");
+ return new EditorTextField(doc, myProject, fileType);
+ }
+
+ private static Document createDocument(final String fileName, final FileType fileType, String text) {
+ final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, text, -1, true);
+
+ return PsiDocumentManager.getInstance(myProject).getDocument(file);
+ }
+
+ private static FileType getFileType(final String fileName) {
+ FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
+ if (fileType == FileTypes.UNKNOWN) fileType = FileTypes.PLAIN_TEXT;
+ return fileType;
+ }
+
+ public static void setProject(final Project project) {
+ myProject = project;
+ }
+
+ private static class MyChangeListener implements ChangeListener {
+ private final JComponent component;
+ private final boolean inverted;
+
+ MyChangeListener(JComponent _component, boolean _inverted) {
+ component = _component;
+ inverted = _inverted;
+ }
+
+ public void stateChanged(ChangeEvent e) {
+ final JCheckBox jCheckBox = (JCheckBox)e.getSource();
+ component.setEnabled(inverted ^ jCheckBox.isSelected());
+ }
+ }
+
+ private static class MyDocumentListener extends DocumentAdapter {
+ private final JComponent[] components;
+
+ private MyDocumentListener(JComponent... _components) {
+ components = _components;
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent e) {
+ final boolean enable = e.getDocument().getTextLength() > 0;
+ for (JComponent component : components) {
+ component.setEnabled(enable);
+ }
+ }
+ }
+
+ private static Editor createEditor(final Project project, final String text, final String fileName) {
+ final FileType fileType = getFileType(fileName);
+ final Document doc = createDocument(fileName, fileType, text);
+ final Editor editor = EditorFactory.getInstance().createEditor(doc, project);
+
+ ((EditorEx)editor).setEmbeddedIntoDialogWrapper(true);
+ final EditorSettings settings = editor.getSettings();
+ settings.setLineNumbersShown(false);
+ settings.setFoldingOutlineShown(false);
+ settings.setRightMarginShown(false);
+ settings.setLineMarkerAreaShown(false);
+ settings.setIndentGuidesShown(false);
+ ((EditorEx)editor).setHighlighter(HighlighterFactory.createHighlighter(fileType, DefaultColorSchemesManager.getInstance().getAllSchemes()[0], project));
+
+ return editor;
+ }
+
+ private static class EditScriptDialog extends DialogWrapper {
+ private final Editor editor;
+
+ public EditScriptDialog(final Project project, String text) {
+ super(project, true);
+ setTitle(SSRBundle.message("edit.groovy.script.constraint.title"));
+ editor = createEditor(project, text, "1.groovy");
+ init();
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return getClass().getName();
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return editor.getContentComponent();
+ }
+
+ protected JComponent createCenterPanel() {
+ return editor.getComponent();
+ }
+
+ String getScriptText() {
+ return editor.getDocument().getText();
+ }
+
+ @Override
+ protected void dispose() {
+ EditorFactory.getInstance().releaseEditor(editor);
+ super.dispose();
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java
new file mode 100644
index 000000000000..3dd79e16175c
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/ExistingTemplatesComponent.java
@@ -0,0 +1,333 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.tree.TreeUtil;
+
+import javax.swing.*;
+import javax.swing.tree.*;
+import java.awt.*;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 2, 2004
+ * Time: 1:27:54 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ExistingTemplatesComponent {
+ private final Tree patternTree;
+ private final DefaultTreeModel patternTreeModel;
+ private final DefaultMutableTreeNode userTemplatesNode;
+ private final JComponent panel;
+ private final DefaultListModel historyModel;
+ private final JList historyList;
+ private final JComponent historyPanel;
+ private DialogWrapper owner;
+ private final Project project;
+
+ private ExistingTemplatesComponent(Project project) {
+
+ this.project = project;
+ final DefaultMutableTreeNode root;
+ patternTreeModel = new DefaultTreeModel(
+ root = new DefaultMutableTreeNode(null)
+ );
+
+ DefaultMutableTreeNode parent = null;
+ String lastCategory = null;
+ LinkedList<Object> nodesToExpand = new LinkedList<Object>();
+
+ final List<Configuration> predefined = StructuralSearchUtil.getPredefinedTemplates();
+ for (final Configuration info : predefined) {
+ final DefaultMutableTreeNode node = new DefaultMutableTreeNode(info);
+
+ if (lastCategory == null || !lastCategory.equals(info.getCategory())) {
+ if (info.getCategory().length() > 0) {
+ root.add(parent = new DefaultMutableTreeNode(info.getCategory()));
+ nodesToExpand.add(parent);
+ lastCategory = info.getCategory();
+ }
+ else {
+ root.add(node);
+ continue;
+ }
+ }
+
+ parent.add(node);
+ }
+
+ parent = new DefaultMutableTreeNode(SSRBundle.message("user.defined.category"));
+ userTemplatesNode = parent;
+ root.add(parent);
+ nodesToExpand.add(parent);
+
+ final ConfigurationManager configurationManager = StructuralSearchPlugin.getInstance(this.project).getConfigurationManager();
+ if (configurationManager.getConfigurations() != null) {
+ for (final Configuration config : configurationManager.getConfigurations()) {
+ parent.add(new DefaultMutableTreeNode(config));
+ }
+ }
+
+ patternTree = createTree(patternTreeModel);
+
+ for (final Object aNodesToExpand : nodesToExpand) {
+ patternTree.expandPath(
+ new TreePath(new Object[]{root, aNodesToExpand})
+ );
+ }
+
+ panel = ToolbarDecorator.createDecorator(patternTree)
+ .setAddAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ addSelectedTreeNodeAndClose();
+ }
+ }).setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ Object selection = patternTree.getLastSelectedPathComponent();
+
+ if (selection instanceof DefaultMutableTreeNode) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)selection;
+
+ if (node.getUserObject() instanceof Configuration) {
+ Configuration configuration = (Configuration)node.getUserObject();
+ patternTreeModel.removeNodeFromParent(node);
+ configurationManager.removeConfiguration(configuration);
+ }
+ }
+ }
+ }).createPanel();
+
+ new JPanel(new BorderLayout());
+
+ configureSelectTemplateAction(patternTree);
+
+ historyModel = new DefaultListModel();
+ historyPanel = new JPanel(new BorderLayout());
+ historyPanel.add(
+ BorderLayout.NORTH,
+ new JLabel(SSRBundle.message("used.templates"))
+ );
+ Component view = historyList = new JBList(historyModel);
+ historyPanel.add(
+ BorderLayout.CENTER,
+ ScrollPaneFactory.createScrollPane(view)
+ );
+
+ historyList.setCellRenderer(
+ new ListCellRenderer()
+ );
+
+ historyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ new ListSpeedSearch(historyList);
+
+ if (configurationManager.getHistoryConfigurations() != null) {
+ for (final Configuration configuration : configurationManager.getHistoryConfigurations()) {
+ historyModel.addElement(configuration);
+ }
+
+ historyList.setSelectedIndex(0);
+ }
+
+ configureSelectTemplateAction(historyList);
+ }
+
+ private void configureSelectTemplateAction(JComponent component) {
+ component.addKeyListener(
+ new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+ owner.close(DialogWrapper.OK_EXIT_CODE);
+ }
+ }
+ }
+ );
+
+ new DoubleClickListener() {
+ @Override
+ protected boolean onDoubleClick(MouseEvent event) {
+ owner.close(DialogWrapper.OK_EXIT_CODE);
+ return true;
+ }
+ }.installOn(component);
+ }
+
+ private void addSelectedTreeNodeAndClose() {
+ addConfigurationToUserTemplates(
+ Configuration.getConfigurationCreator().createConfiguration()
+ );
+ owner.close(DialogWrapper.OK_EXIT_CODE);
+ }
+
+ private static Tree createTree(TreeModel treeModel) {
+ final Tree tree = new Tree(treeModel);
+
+ tree.setRootVisible(false);
+ tree.setShowsRootHandles(true);
+ tree.setDragEnabled(false);
+ tree.setEditable(false);
+ tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+
+ tree.setCellRenderer(new TreeCellRenderer());
+
+ new TreeSpeedSearch(
+ tree,
+ new Convertor<TreePath, String>() {
+ public String convert(TreePath object) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)object.getLastPathComponent();
+ Object displayValue = node.getUserObject();
+
+ if (displayValue instanceof Configuration) {
+ displayValue = ((Configuration)displayValue).getName();
+ }
+ else {
+ displayValue = "";
+ }
+ return displayValue.toString();
+ }
+ }
+ );
+
+ return tree;
+ }
+
+ public JTree getPatternTree() {
+ return patternTree;
+ }
+
+ public JComponent getTemplatesPanel() {
+ return panel;
+ }
+
+ public static ExistingTemplatesComponent getInstance(Project project) {
+ StructuralSearchPlugin plugin = StructuralSearchPlugin.getInstance(project);
+
+ if (plugin.getExistingTemplatesComponent() == null) {
+ plugin.setExistingTemplatesComponent(new ExistingTemplatesComponent(project));
+ }
+
+ return plugin.getExistingTemplatesComponent();
+ }
+
+ static class ListCellRenderer extends DefaultListCellRenderer {
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ if (value instanceof Configuration) {
+ value = ((Configuration)value).getName();
+ }
+
+ Component comp = super.getListCellRendererComponent(
+ list,
+ value,
+ index,
+ isSelected,
+ cellHasFocus
+ );
+
+ return comp;
+ }
+ }
+
+ static class TreeCellRenderer extends DefaultTreeCellRenderer {
+ TreeCellRenderer() {
+ setOpenIcon(null);
+ setLeafIcon(null);
+ setClosedIcon(null);
+ }
+
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value,
+ boolean sel,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
+ DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)value;
+ Object displayValue = treeNode.getUserObject();
+
+ if (displayValue instanceof Configuration) {
+ displayValue = ((Configuration)displayValue).getName();
+ }
+
+ Component comp = super.getTreeCellRendererComponent(
+ tree,
+ displayValue,
+ sel,
+ expanded,
+ leaf,
+ row,
+ hasFocus
+ );
+
+ return comp;
+ }
+ }
+
+ void addConfigurationToHistory(Configuration configuration) {
+ //configuration.setName( configuration.getName() +" "+new Date());
+ historyModel.insertElementAt(configuration, 0);
+ ConfigurationManager configurationManager = StructuralSearchPlugin.getInstance(project).getConfigurationManager();
+ configurationManager.addHistoryConfigurationToFront(configuration);
+ historyList.setSelectedIndex(0);
+
+ if (historyModel.getSize() > 25) {
+ configurationManager.removeHistoryConfiguration(
+ (Configuration)historyModel.getElementAt(25)
+ );
+ // we add by one!
+ historyModel.removeElementAt(25);
+ }
+ }
+
+ private void insertNode(Configuration configuration, DefaultMutableTreeNode parent, int index) {
+ DefaultMutableTreeNode node;
+ patternTreeModel.insertNodeInto(
+ node = new DefaultMutableTreeNode(
+ configuration
+ ),
+ parent,
+ index
+ );
+
+ TreeUtil.selectPath(
+ patternTree,
+ new TreePath(new Object[]{patternTreeModel.getRoot(), parent, node})
+ );
+ }
+
+ void addConfigurationToUserTemplates(Configuration configuration) {
+ insertNode(configuration, userTemplatesNode, userTemplatesNode.getChildCount());
+ ConfigurationManager configurationManager = StructuralSearchPlugin.getInstance(project).getConfigurationManager();
+ configurationManager.addConfiguration(configuration);
+ }
+
+ boolean isConfigurationFromHistory(Configuration config) {
+ return historyModel.indexOf(config) != -1;
+ }
+
+ public JList getHistoryList() {
+ return historyList;
+ }
+
+ public JComponent getHistoryPanel() {
+ return historyPanel;
+ }
+
+ public void setOwner(DialogWrapper owner) {
+ this.owner = owner;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
new file mode 100644
index 000000000000..7c51fa85af3b
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
@@ -0,0 +1,145 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.notification.NotificationGroup;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNameIdentifierOwner;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.impl.matcher.MatchResultImpl;
+import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
+import com.intellij.structuralsearch.plugin.ui.actions.DoSearchAction;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.usages.Usage;
+import com.intellij.usages.UsageInfo2UsageAdapter;
+import com.intellij.util.Alarm;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.Processor;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 15, 2004
+ * Time: 4:49:07 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SearchCommand {
+ protected UsageViewContext context;
+ private MatchingProcess process;
+ protected Project project;
+
+ public SearchCommand(Project _project, UsageViewContext _context) {
+ project = _project;
+ context = _context;
+ }
+
+ public void findUsages(final Processor<Usage> processor) {
+ final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
+
+ try {
+ DoSearchAction.execute(
+ project,
+ new MatchResultSink() {
+ int count;
+
+ public void setMatchingProcess(MatchingProcess _process) {
+ process = _process;
+ findStarted();
+ }
+
+ public void processFile(PsiFile element) {
+ final VirtualFile virtualFile = element.getVirtualFile();
+ if (virtualFile != null)
+ progress.setText(SSRBundle.message("looking.in.progress.message", virtualFile.getPresentableName()));
+ }
+
+ public void matchingFinished() {
+ findEnded();
+ progress.setText(SSRBundle.message("found.progress.message", count));
+ }
+
+ public ProgressIndicator getProgressIndicator() {
+ return progress;
+ }
+
+ public void newMatch(MatchResult result) {
+ UsageInfo info;
+
+ if (MatchResult.MULTI_LINE_MATCH.equals(result.getName())) {
+ int start = -1;
+ int end = -1;
+ PsiElement parent = result.getMatchRef().getElement().getParent();
+
+ for (final MatchResult matchResult : ((MatchResultImpl)result).getMatches()) {
+ PsiElement el = matchResult.getMatchRef().getElement();
+ final int elementStart = el.getTextRange().getStartOffset();
+
+ if (start == -1 || start > elementStart) {
+ start = elementStart;
+ }
+ final int newend = elementStart + el.getTextLength();
+
+ if (newend > end) {
+ end = newend;
+ }
+ }
+
+ final int parentStart = parent.getTextRange().getStartOffset();
+ int startOffset = start - parentStart;
+ info = new UsageInfo(parent, startOffset, end - parentStart);
+ }
+ else {
+ PsiElement element = result.getMatch();
+ if (element instanceof PsiNameIdentifierOwner) {
+ element = ObjectUtils.notNull(((PsiNameIdentifierOwner)element).getNameIdentifier(), element);
+ }
+ info = new UsageInfo(element, result.getStart(), result.getEnd() == -1 ? element.getTextLength() : result.getEnd());
+ }
+
+ Usage usage = new UsageInfo2UsageAdapter(info);
+ processor.process(usage);
+ foundUsage(result, usage);
+ ++count;
+ }
+ },
+ context.getConfiguration()
+ );
+ }
+ catch (final StructuralSearchException e) {
+ final Alarm alarm = new Alarm();
+ alarm.addRequest(
+ new Runnable() {
+ @Override
+ public void run() {
+ NotificationGroup.toolWindowGroup("Structural Search", ToolWindowId.FIND, true)
+ .createNotification(SSRBundle.message("problem", e.getMessage()), MessageType.ERROR).notify(project);
+ }
+ },
+ 100, ModalityState.NON_MODAL
+ );
+ }
+ }
+
+ public void stopAsyncSearch() {
+ if (process!=null) process.stop();
+ }
+
+ protected void findStarted() {
+ StructuralSearchPlugin.getInstance(project).setSearchInProgress(true);
+ }
+
+ protected void findEnded() {
+ if (!project.isDisposed()) {
+ StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
+ }
+ }
+
+ protected void foundUsage(MatchResult result, Usage usage) {
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchConfiguration.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchConfiguration.java
new file mode 100644
index 000000000000..afb2f9451bbe
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchConfiguration.java
@@ -0,0 +1,39 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.openapi.actionSystem.AnAction;
+import org.jdom.Element;
+import org.jdom.Attribute;
+import org.jdom.DataConversionException;
+
+/**
+ * Configuration of the search
+ */
+public class SearchConfiguration extends Configuration {
+ private MatchOptions matchOptions;
+
+ public SearchConfiguration() {
+ matchOptions = new MatchOptions();
+ }
+
+ public MatchOptions getMatchOptions() {
+ return matchOptions;
+ }
+
+ public void setMatchOptions(MatchOptions matchOptions) {
+ this.matchOptions = matchOptions;
+ }
+
+ public void readExternal(Element element) {
+ super.readExternal(element);
+
+ matchOptions.readExternal(element);
+ }
+
+ public void writeExternal(Element element) {
+ super.writeExternal(element);
+
+ matchOptions.writeExternal(element);
+ }
+
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
new file mode 100644
index 000000000000..62371e7e29d1
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
@@ -0,0 +1,59 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.structuralsearch.impl.matcher.DataProvider;
+
+/**
+ * Context of the search to be done
+ */
+public final class SearchContext implements DataProvider, Cloneable {
+ private final PsiFile file;
+ private final Project project;
+
+ private SearchContext(Project project, PsiFile file) {
+ this.project = project;
+ this.file = file;
+ }
+
+ public PsiFile getFile() {
+ return file;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ public static SearchContext buildFromDataContext(DataContext context) {
+ Project project = CommonDataKeys.PROJECT.getData(context);
+ if (project == null) {
+ project = ProjectManager.getInstance().getDefaultProject();
+ }
+
+ PsiFile file = CommonDataKeys.PSI_FILE.getData(context);
+ final VirtualFile vFile = CommonDataKeys.VIRTUAL_FILE.getData(context);
+ if (vFile != null && (file == null || !vFile.equals(file.getContainingFile().getVirtualFile()))) {
+ file = PsiManager.getInstance(project).findFile(vFile);
+ }
+ return new SearchContext(project, file);
+ }
+
+ public Editor getEditor() {
+ return FileEditorManager.getInstance(project).getSelectedTextEditor();
+ }
+
+ protected Object clone() {
+ try {
+ return super.clone();
+ } catch(CloneNotSupportedException ex) {
+ return null;
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
new file mode 100644
index 000000000000..5255472d4ce6
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
@@ -0,0 +1,1000 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.codeInsight.template.impl.Variable;
+import com.intellij.find.FindBundle;
+import com.intellij.find.FindProgressIndicator;
+import com.intellij.find.FindSettings;
+import com.intellij.ide.IdeBundle;
+import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageUtil;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.impl.FileTypeRenderer;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Factory;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
+import com.intellij.structuralsearch.plugin.StructuralSearchPlugin;
+import com.intellij.ui.ComboboxSpeedSearch;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.ui.TitledSeparator;
+import com.intellij.usages.*;
+import com.intellij.util.Alarm;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.*;
+import java.util.List;
+
+/**
+ * Class to show the user the request for search
+ */
+@SuppressWarnings({"RefusedBequest", "AssignmentToStaticFieldFromInstanceMethod"})
+public class SearchDialog extends DialogWrapper implements ConfigurationCreator {
+ protected SearchContext searchContext;
+
+ // text for search
+ protected Editor searchCriteriaEdit;
+
+ // options of search scope
+ private ScopeChooserCombo myScopeChooserCombo;
+
+ private JCheckBox recursiveMatching;
+ private JCheckBox caseSensitiveMatch;
+
+ private JComboBox fileTypes;
+ private JComboBox contexts;
+ private JComboBox dialects;
+ private JLabel status;
+ private JLabel statusText;
+
+ protected SearchModel model;
+ private JCheckBox openInNewTab;
+ private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
+
+ public static final String USER_DEFINED = SSRBundle.message("new.template.defaultname");
+ protected final ExistingTemplatesComponent existingTemplatesComponent;
+
+ private boolean useLastConfiguration;
+
+ private static boolean ourOpenInNewTab;
+
+ @NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType();
+ private static Language ourDialect = null;
+ private static String ourContext = null;
+
+ private final boolean myShowScopePanel;
+ private final boolean myRunFindActionOnClose;
+ private boolean myDoingOkAction;
+
+ private String mySavedEditorText;
+ private JPanel myContentPanel;
+ private JComponent myEditorPanel;
+
+ public SearchDialog(SearchContext searchContext) {
+ this(searchContext, true, true);
+ }
+
+ public SearchDialog(SearchContext searchContext, boolean showScope, boolean runFindActionOnClose) {
+ super(searchContext.getProject(), true);
+
+ if (showScope) setModal(false);
+ myShowScopePanel = showScope;
+ myRunFindActionOnClose = runFindActionOnClose;
+ this.searchContext = (SearchContext)searchContext.clone();
+ setTitle(getDefaultTitle());
+
+ if (runFindActionOnClose) {
+ setOKButtonText(FindBundle.message("find.dialog.find.button"));
+ }
+
+ existingTemplatesComponent = ExistingTemplatesComponent.getInstance(this.searchContext.getProject());
+ model = new SearchModel(createConfiguration());
+
+ init();
+ }
+
+ protected UsageViewContext createUsageViewContext(Configuration configuration) {
+ return new UsageViewContext(searchContext, configuration);
+ }
+
+ public void setUseLastConfiguration(boolean useLastConfiguration) {
+ this.useLastConfiguration = useLastConfiguration;
+ }
+
+ protected boolean isChanged(Configuration configuration) {
+ return configuration.getMatchOptions().getSearchPattern() != null &&
+ !searchCriteriaEdit.getDocument().getText().equals(configuration.getMatchOptions().getSearchPattern());
+ }
+
+ public void setSearchPattern(final Configuration config) {
+ model.setShadowConfig(config);
+ setValuesFromConfig(config);
+ initiateValidation();
+ }
+
+ protected Editor createEditor(final SearchContext searchContext, String text) {
+ Editor editor = null;
+
+ if (fileTypes != null) {
+ final FileType fileType = (FileType)fileTypes.getSelectedItem();
+ final Language dialect = (Language)dialects.getSelectedItem();
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
+ if (profile != null) {
+ editor = profile.createEditor(searchContext, fileType, dialect, text, useLastConfiguration);
+ }
+ }
+
+ if (editor == null) {
+ final EditorFactory factory = EditorFactory.getInstance();
+ final Document document = factory.createDocument("");
+ editor = factory.createEditor(document, searchContext.getProject());
+ editor.getSettings().setFoldingOutlineShown(false);
+ }
+
+ editor.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void beforeDocumentChange(final DocumentEvent event) {
+ }
+
+ @Override
+ public void documentChanged(final DocumentEvent event) {
+ initiateValidation();
+ }
+ });
+
+ return editor;
+ }
+
+ private void initiateValidation() {
+ myAlarm.cancelAllRequests();
+ myAlarm.addRequest(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ new WriteAction(){
+ @Override
+ protected void run(Result result) throws Throwable {
+ if (!isValid()) {
+ getOKAction().setEnabled(false);
+ }
+ else {
+ getOKAction().setEnabled(true);
+ reportMessage(null, null);
+ }
+ }
+ }.execute();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }, 500);
+ }
+
+ protected void buildOptions(JPanel searchOptions) {
+ recursiveMatching = new JCheckBox(SSRBundle.message("recursive.matching.checkbox"), true);
+ if (isRecursiveSearchEnabled()) {
+ searchOptions.add(UIUtil.createOptionLine(recursiveMatching));
+ }
+
+ caseSensitiveMatch = new JCheckBox(FindBundle.message("find.options.case.sensitive"), true);
+ searchOptions.add(UIUtil.createOptionLine(caseSensitiveMatch));
+
+ final List<FileType> types = new ArrayList<FileType>();
+
+ for (FileType fileType : StructuralSearchUtil.getSuitableFileTypes()) {
+ if (StructuralSearchUtil.getProfileByFileType(fileType) != null) {
+ types.add(fileType);
+ }
+ }
+ Collections.sort(types, new Comparator<FileType>() {
+ @Override
+ public int compare(FileType o1, FileType o2) {
+ return o1.getName().compareToIgnoreCase(o2.getName());
+ }
+ });
+
+ final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(types.toArray(new FileType[types.size()]));
+ comboBoxModel.setSelectedItem(ourFtSearchVariant);
+ fileTypes = new ComboBox(comboBoxModel);
+ fileTypes.setRenderer(new FileTypeRenderer());
+ new ComboboxSpeedSearch(fileTypes) {
+ @Override
+ protected String getElementText(Object element) {
+ return ((FileType)element).getName();
+ }
+ };
+ fileTypes.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateDialectsAndContexts();
+ updateEditor();
+ }
+ });
+
+ contexts = new JComboBox(new DefaultComboBoxModel());
+ contexts.setPreferredSize(new Dimension(60, -1));
+
+ dialects = new JComboBox(new DefaultComboBoxModel());
+ dialects.setRenderer(new ListCellRendererWrapper() {
+ @Override
+ public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+ if (value == null) {
+ setText("None");
+ }
+ else if (value instanceof Language) {
+ setText(((Language)value).getDisplayName());
+ }
+ }
+ });
+ dialects.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ updateEditor();
+ }
+ });
+ new ComboboxSpeedSearch(dialects);
+ dialects.setPreferredSize(new Dimension(120, -1));
+
+ final JLabel jLabel = new JLabel(SSRBundle.message("search.dialog.file.type.label"));
+ final JLabel jLabel2 = new JLabel(SSRBundle.message("search.dialog.context.label"));
+ final JLabel jLabel3 = new JLabel(SSRBundle.message("search.dialog.file.dialect.label"));
+ searchOptions.add(
+ UIUtil.createOptionLine(
+ new JComponent[]{
+ jLabel,
+ fileTypes,
+ (JComponent)Box.createHorizontalStrut(8),
+ jLabel2,
+ contexts,
+ (JComponent)Box.createHorizontalStrut(8),
+ jLabel3,
+ dialects,
+ }
+ )
+ );
+
+ jLabel.setLabelFor(fileTypes);
+ jLabel2.setLabelFor(contexts);
+ jLabel3.setLabelFor(dialects);
+
+ detectFileTypeAndDialect();
+
+ fileTypes.setSelectedItem(ourFtSearchVariant);
+ fileTypes.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) initiateValidation();
+ }
+ });
+
+ dialects.setSelectedItem(ourDialect);
+ contexts.setSelectedItem(ourContext);
+
+ updateDialectsAndContexts();
+ }
+
+ private void updateEditor() {
+ if (myContentPanel != null) {
+ if (myEditorPanel != null) {
+ myContentPanel.remove(myEditorPanel);
+ }
+ disposeEditorContent();
+ myEditorPanel = createEditorContent();
+ myContentPanel.add(myEditorPanel, BorderLayout.CENTER);
+ myContentPanel.revalidate();
+ }
+ }
+
+ private void updateDialectsAndContexts() {
+ final FileType fileType = (FileType)fileTypes.getSelectedItem();
+ if (fileType instanceof LanguageFileType) {
+ Language language = ((LanguageFileType)fileType).getLanguage();
+ Language[] languageDialects = LanguageUtil.getLanguageDialects(language);
+ Arrays.sort(languageDialects, new Comparator<Language>() {
+ @Override
+ public int compare(Language o1, Language o2) {
+ return o1.getDisplayName().compareTo(o2.getDisplayName());
+ }
+ });
+ Language[] variants = new Language[languageDialects.length + 1];
+ variants[0] = null;
+ System.arraycopy(languageDialects, 0, variants, 1, languageDialects.length);
+ dialects.setModel(new DefaultComboBoxModel(variants));
+ dialects.setEnabled(variants.length > 1);
+ }
+
+ final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(fileType);
+
+ if (profile instanceof StructuralSearchProfileBase) {
+ final String[] contextNames = ((StructuralSearchProfileBase)profile).getContextNames();
+ if (contextNames.length > 0) {
+ contexts.setModel(new DefaultComboBoxModel(contextNames));
+ contexts.setSelectedItem(contextNames[0]);
+ contexts.setEnabled(true);
+ return;
+ }
+ }
+ contexts.setSelectedItem(null);
+ contexts.setEnabled(false);
+ }
+
+ private void detectFileTypeAndDialect() {
+ final PsiFile file = searchContext.getFile();
+ if (file != null) {
+ PsiElement context = null;
+
+ if (searchContext.getEditor() != null) {
+ context = file.findElementAt(searchContext.getEditor().getCaretModel().getOffset());
+ if (context != null) {
+ context = context.getParent();
+ }
+ }
+ if (context == null) {
+ context = file;
+ }
+
+ FileType detectedFileType = null;
+
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(context);
+ if (profile != null) {
+ FileType fileType = profile.detectFileType(context);
+ if (fileType != null) {
+ detectedFileType = fileType;
+ }
+ }
+
+ if (detectedFileType == null) {
+ for (FileType fileType : StructuralSearchUtil.getSuitableFileTypes()) {
+ if (fileType instanceof LanguageFileType && ((LanguageFileType)fileType).getLanguage().equals(context.getLanguage())) {
+ detectedFileType = fileType;
+ break;
+ }
+ }
+ }
+
+ ourFtSearchVariant = detectedFileType != null ?
+ detectedFileType :
+ StructuralSearchUtil.getDefaultFileType();
+
+ // todo: detect dialect
+
+ /*if (file.getLanguage() == StdLanguages.HTML ||
+ (file.getFileType() == StdFileTypes.JSP &&
+ contextLanguage == StdLanguages.HTML
+ )
+ ) {
+ ourFileType = "html";
+ }
+ else if (file.getLanguage() == StdLanguages.XHTML ||
+ (file.getFileType() == StdFileTypes.JSPX &&
+ contextLanguage == StdLanguages.HTML
+ )) {
+ ourFileType = "xml";
+ }
+ else {
+ ourFileType = DEFAULT_TYPE_NAME;
+ }*/
+ }
+ }
+
+ protected boolean isRecursiveSearchEnabled() {
+ return true;
+ }
+
+ public void setValuesFromConfig(Configuration configuration) {
+ //searchCriteriaEdit.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, configuration);
+
+ setDialogTitle(configuration);
+ final MatchOptions matchOptions = configuration.getMatchOptions();
+
+ UIUtil.setContent(
+ searchCriteriaEdit,
+ matchOptions.getSearchPattern(),
+ 0,
+ searchCriteriaEdit.getDocument().getTextLength(),
+ searchContext.getProject()
+ );
+
+ model.getConfig().getMatchOptions().setSearchPattern(
+ matchOptions.getSearchPattern()
+ );
+
+ recursiveMatching.setSelected(
+ isRecursiveSearchEnabled() && matchOptions.isRecursiveSearch()
+ );
+
+ caseSensitiveMatch.setSelected(
+ matchOptions.isCaseSensitiveMatch()
+ );
+
+ model.getConfig().getMatchOptions().clearVariableConstraints();
+ if (matchOptions.hasVariableConstraints()) {
+ for (Iterator<String> i = matchOptions.getVariableConstraintNames(); i.hasNext(); ) {
+ final MatchVariableConstraint constraint = (MatchVariableConstraint)matchOptions.getVariableConstraint(i.next()).clone();
+ model.getConfig().getMatchOptions().addVariableConstraint(constraint);
+ }
+ }
+
+ MatchOptions options = configuration.getMatchOptions();
+ StructuralSearchProfile profile = StructuralSearchUtil.getProfileByFileType(options.getFileType());
+ assert profile != null;
+ fileTypes.setSelectedItem(options.getFileType());
+ dialects.setSelectedItem(options.getDialect());
+ if (options.getPatternContext() != null) {
+ contexts.setSelectedItem(options.getPatternContext());
+ }
+ }
+
+ private void setDialogTitle(final Configuration configuration) {
+ setTitle(getDefaultTitle() + " - " + configuration.getName());
+ }
+
+ @Override
+ public Configuration createConfiguration() {
+ SearchConfiguration configuration = new SearchConfiguration();
+ configuration.setName(USER_DEFINED);
+ return configuration;
+ }
+
+ protected void addOrReplaceSelection(final String selection) {
+ addOrReplaceSelectionForEditor(selection, searchCriteriaEdit);
+ }
+
+ protected final void addOrReplaceSelectionForEditor(final String selection, Editor editor) {
+ final Project project = searchContext.getProject();
+ UIUtil.setContent(editor, selection, 0, -1, project);
+ final Document document = editor.getDocument();
+ editor.getSelectionModel().setSelection(0, document.getTextLength());
+ final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
+ documentManager.commitDocument(document);
+ final PsiFile file = documentManager.getPsiFile(document);
+ if (file == null) return;
+
+ new WriteCommandAction(project, file) {
+ @Override protected void run(@NotNull Result result) throws Throwable {
+ CodeStyleManager.getInstance(project).adjustLineIndent(file, new TextRange(0, document.getTextLength()));
+ }
+ }.execute();
+ }
+
+ protected void runAction(final Configuration config, final SearchContext searchContext) {
+ createUsageView(searchContext, config);
+ }
+
+ protected void createUsageView(final SearchContext searchContext, final Configuration config) {
+ UsageViewManager manager = UsageViewManager.getInstance(searchContext.getProject());
+
+ final UsageViewContext context = createUsageViewContext(config);
+ final UsageViewPresentation presentation = new UsageViewPresentation();
+ presentation.setOpenInNewTab(openInNewTab.isSelected());
+ presentation.setScopeText(config.getMatchOptions().getScope().getDisplayName());
+ context.configure(presentation);
+
+ final FindUsagesProcessPresentation processPresentation = new FindUsagesProcessPresentation(presentation);
+ processPresentation.setShowNotFoundMessage(true);
+ processPresentation.setShowPanelIfOnlyOneUsage(true);
+
+ processPresentation.setProgressIndicatorFactory(
+ new Factory<ProgressIndicator>() {
+ @Override
+ public ProgressIndicator create() {
+ return new FindProgressIndicator(searchContext.getProject(), presentation.getScopeText()) {
+ @Override
+ public void cancel() {
+ context.getCommand().stopAsyncSearch();
+ super.cancel();
+ }
+ };
+ }
+ }
+ );
+
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
+ manager.searchAndShowUsages(
+ new UsageTarget[]{
+ context.getTarget()
+ },
+ new Factory<UsageSearcher>() {
+ @Override
+ public UsageSearcher create() {
+ return new UsageSearcher() {
+ @Override
+ public void generate(@NotNull final Processor<Usage> processor) {
+ context.getCommand().findUsages(processor);
+ }
+ };
+ }
+ },
+ processPresentation,
+ presentation,
+ new UsageViewManager.UsageViewStateListener() {
+ @Override
+ public void usageViewCreated(@NotNull UsageView usageView) {
+ context.setUsageView(usageView);
+ context.configureActions();
+ }
+
+ @Override
+ public void findingUsagesFinished(final UsageView usageView) {
+ }
+ }
+ );
+ }
+
+ protected String getDefaultTitle() {
+ return SSRBundle.message("structural.search.title");
+ }
+
+ protected JComponent createEditorContent() {
+ JPanel result = new JPanel(new BorderLayout());
+
+ result.add(BorderLayout.NORTH, new JLabel(SSRBundle.message("search.template")));
+ searchCriteriaEdit = createEditor(searchContext, mySavedEditorText != null ? mySavedEditorText : "");
+ result.add(BorderLayout.CENTER, searchCriteriaEdit.getComponent());
+ result.setMinimumSize(new Dimension(150, 100));
+
+ return result;
+ }
+
+ protected int getRowsCount() {
+ return 4;
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ myContentPanel = new JPanel(new BorderLayout());
+ myEditorPanel = createEditorContent();
+ myContentPanel.add(BorderLayout.CENTER, myEditorPanel);
+ myContentPanel.add(BorderLayout.SOUTH, Box.createVerticalStrut(8));
+ JComponent centerPanel = new JPanel(new BorderLayout());
+ {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(BorderLayout.CENTER, myContentPanel);
+ panel.add(BorderLayout.SOUTH, createTemplateManagementButtons());
+ centerPanel.add(BorderLayout.CENTER, panel);
+ }
+
+ JPanel optionsContent = new JPanel(new BorderLayout());
+ centerPanel.add(BorderLayout.SOUTH, optionsContent);
+
+ JPanel searchOptions = new JPanel();
+ searchOptions.setLayout(new GridLayout(getRowsCount(), 1, 0, 0));
+ searchOptions.setBorder(IdeBorderFactory.createTitledBorder(SSRBundle.message("ssdialog.options.group.border"),
+ true));
+
+ myScopeChooserCombo = new ScopeChooserCombo(
+ searchContext.getProject(),
+ true,
+ false,
+ FindSettings.getInstance().getDefaultScopeName()
+ );
+ Disposer.register(myDisposable, myScopeChooserCombo);
+ JPanel allOptions = new JPanel(new BorderLayout());
+ if (myShowScopePanel) {
+ JPanel scopePanel = new JPanel(new GridBagLayout());
+
+ TitledSeparator separator = new TitledSeparator(SSRBundle.message("search.dialog.scope.label"), myScopeChooserCombo.getComboBox());
+ scopePanel.add(separator, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(5, 0, 0, 0), 0, 0));
+
+ scopePanel.add(myScopeChooserCombo, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 10, 0, 0), 0, 0));
+
+ allOptions.add(
+ scopePanel,
+ BorderLayout.SOUTH
+ );
+
+ myScopeChooserCombo.getComboBox().addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ initiateValidation();
+ }
+ });
+ }
+
+ buildOptions(searchOptions);
+
+ allOptions.add(searchOptions, BorderLayout.CENTER);
+ optionsContent.add(allOptions, BorderLayout.CENTER);
+
+ if (myRunFindActionOnClose) {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
+ openInNewTab = new JCheckBox(FindBundle.message("find.open.in.new.tab.checkbox"));
+ openInNewTab.setSelected(ourOpenInNewTab);
+ ToolWindow findWindow = ToolWindowManager.getInstance(searchContext.getProject()).getToolWindow(ToolWindowId.FIND);
+ openInNewTab.setEnabled(findWindow != null && findWindow.isAvailable());
+ panel.add(openInNewTab, BorderLayout.EAST);
+
+ optionsContent.add(BorderLayout.SOUTH, panel);
+ }
+
+ updateEditor();
+ return centerPanel;
+ }
+
+
+ @Override
+ protected JComponent createSouthPanel() {
+ final JPanel statusPanel = new JPanel(new BorderLayout(5, 0));
+ statusPanel.add(super.createSouthPanel(), BorderLayout.NORTH);
+ statusPanel.add(statusText = new JLabel(SSRBundle.message("status.message")), BorderLayout.WEST);
+ statusPanel.add(status = new JLabel(), BorderLayout.CENTER);
+ return statusPanel;
+ }
+
+ private JPanel createTemplateManagementButtons() {
+ JPanel panel = new JPanel(null);
+ panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+ panel.add(Box.createHorizontalGlue());
+
+ panel.add(
+ createJButtonForAction(new AbstractAction() {
+ {
+ putValue(NAME, SSRBundle.message("save.template.text.button"));
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String name = showSaveTemplateAsDialog();
+
+ if (name != null) {
+ final Project project = searchContext.getProject();
+ final ConfigurationManager configurationManager = StructuralSearchPlugin.getInstance(project).getConfigurationManager();
+ final Collection<Configuration> configurations = configurationManager.getConfigurations();
+
+ if (configurations != null) {
+ name = ConfigurationManager.findAppropriateName(configurations, name, project);
+ if (name == null) return;
+ }
+
+ model.getConfig().setName(name);
+ setValuesToConfig(model.getConfig());
+ setDialogTitle(model.getConfig());
+
+ if (model.getShadowConfig() == null ||
+ model.getShadowConfig().isPredefined()) {
+ existingTemplatesComponent.addConfigurationToUserTemplates(model.getConfig());
+ }
+ else { // ???
+ setValuesToConfig(model.getShadowConfig());
+ model.getShadowConfig().setName(name);
+ }
+ }
+ }
+ })
+ );
+
+ panel.add(
+ Box.createHorizontalStrut(8)
+ );
+
+ panel.add(
+ createJButtonForAction(
+ new AbstractAction() {
+ {
+ putValue(NAME, SSRBundle.message("edit.variables.button"));
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ EditVarConstraintsDialog.setProject(searchContext.getProject());
+ new EditVarConstraintsDialog(
+ searchContext.getProject(),
+ model, getVariablesFromListeners(),
+ isReplaceDialog(),
+ (FileType)fileTypes.getSelectedItem()
+ ).show();
+ initiateValidation();
+ EditVarConstraintsDialog.setProject(null);
+ }
+ }
+ )
+ );
+
+ panel.add(
+ Box.createHorizontalStrut(8)
+ );
+
+ panel.add(
+ createJButtonForAction(
+ new AbstractAction() {
+ {
+ putValue(NAME, SSRBundle.message("history.button"));
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SelectTemplateDialog dialog = new SelectTemplateDialog(searchContext.getProject(), true, isReplaceDialog());
+ dialog.show();
+
+ if (!dialog.isOK()) {
+ return;
+ }
+ Configuration[] configurations = dialog.getSelectedConfigurations();
+ if (configurations.length == 1) {
+ setSearchPattern(configurations[0]);
+ }
+ }
+ }
+ )
+ );
+
+ panel.add(
+ Box.createHorizontalStrut(8)
+ );
+
+ panel.add(
+ createJButtonForAction(
+ new AbstractAction() {
+ {
+ putValue(NAME, SSRBundle.message("copy.existing.template.button"));
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SelectTemplateDialog dialog = new SelectTemplateDialog(searchContext.getProject(), false, isReplaceDialog());
+ dialog.show();
+
+ if (!dialog.isOK()) {
+ return;
+ }
+ Configuration[] configurations = dialog.getSelectedConfigurations();
+ if (configurations.length == 1) {
+ setSearchPattern(configurations[0]);
+ }
+ }
+ }
+ )
+ );
+
+ return panel;
+ }
+
+ protected List<Variable> getVariablesFromListeners() {
+ return getVarsFrom(searchCriteriaEdit);
+ }
+
+ protected static ArrayList<Variable> getVarsFrom(Editor searchCriteriaEdit) {
+ SubstitutionShortInfoHandler handler = searchCriteriaEdit.getUserData(UIUtil.LISTENER_KEY);
+ return new ArrayList<Variable>(handler.getVariables());
+ }
+
+ public final Project getProject() {
+ return searchContext.getProject();
+ }
+
+ public String showSaveTemplateAsDialog() {
+ return ConfigurationManager.showSaveTemplateAsDialog(
+ model.getShadowConfig() != null ? model.getShadowConfig().getName() : SSRBundle.message("user.defined.category"),
+ searchContext.getProject()
+ );
+ }
+
+ protected boolean isReplaceDialog() {
+ return false;
+ }
+
+ @Override
+ public void show() {
+ StructuralSearchPlugin.getInstance(getProject()).setDialogVisible(true);
+ Configuration.setActiveCreator(this);
+ searchCriteriaEdit.putUserData(
+ SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY,
+ model.getConfig()
+ );
+
+ if (!useLastConfiguration) {
+ final Editor editor = FileEditorManager.getInstance(searchContext.getProject()).getSelectedTextEditor();
+ boolean setSomeText = false;
+
+ if (editor != null) {
+ final SelectionModel selectionModel = editor.getSelectionModel();
+
+ if (selectionModel.hasSelection()) {
+ addOrReplaceSelection(selectionModel.getSelectedText());
+ existingTemplatesComponent.getPatternTree().setSelectionPath(null);
+ existingTemplatesComponent.getHistoryList().setSelectedIndex(-1);
+ setSomeText = true;
+ }
+ }
+
+ if (!setSomeText) {
+ int selection = existingTemplatesComponent.getHistoryList().getSelectedIndex();
+ if (selection != -1) {
+ setValuesFromConfig(
+ (Configuration)existingTemplatesComponent.getHistoryList().getSelectedValue()
+ );
+ }
+ }
+ }
+
+ initiateValidation();
+
+ super.show();
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return searchCriteriaEdit.getContentComponent();
+ }
+
+ // Performs ok action
+ @Override
+ protected void doOKAction() {
+ SearchScope selectedScope = getSelectedScope();
+ if (selectedScope == null) return;
+
+ myDoingOkAction = true;
+ boolean result = isValid();
+ myDoingOkAction = false;
+ if (!result) return;
+
+ myAlarm.cancelAllRequests();
+ super.doOKAction();
+ if (!myRunFindActionOnClose) return;
+
+ FindSettings.getInstance().setDefaultScopeName(selectedScope.getDisplayName());
+ ourOpenInNewTab = openInNewTab.isSelected();
+
+ try {
+ if (model.getShadowConfig() != null) {
+ if (model.getShadowConfig().isPredefined()) {
+ model.getConfig().setName(
+ model.getShadowConfig().getName()
+ );
+ } //else {
+ // // user template, save it
+ // setValuesToConfig(model.getShadowConfig());
+ //}
+ }
+ existingTemplatesComponent.addConfigurationToHistory(model.getConfig());
+
+ runAction(model.getConfig(), searchContext);
+ }
+ catch (MalformedPatternException ex) {
+ reportMessage("this.pattern.is.malformed.message", searchCriteriaEdit, ex.getMessage());
+ }
+ }
+
+ public Configuration getConfiguration() {
+ return model.getConfig();
+ }
+
+ private SearchScope getSelectedScope() {
+ return myScopeChooserCombo.getSelectedScope();
+ }
+
+ protected boolean isValid() {
+ setValuesToConfig(model.getConfig());
+ boolean result = true;
+
+ try {
+ MatcherImpl.validate(searchContext.getProject(), model.getConfig().getMatchOptions());
+ }
+ catch (MalformedPatternException ex) {
+ if (myRunFindActionOnClose) {
+ reportMessage(
+ "this.pattern.is.malformed.message",
+ searchCriteriaEdit,
+ ex.getMessage() != null ? ex.getMessage() : ""
+ );
+ result = false;
+ }
+ }
+ catch (UnsupportedPatternException ex) {
+ reportMessage("this.pattern.is.unsupported.message", searchCriteriaEdit, ex.getMessage());
+ result = false;
+ }
+
+ //getOKAction().setEnabled(result);
+ return result;
+ }
+
+ protected void reportMessage(@NonNls String messageId, Editor editor, Object... params) {
+ final String message = messageId != null ? SSRBundle.message(messageId, params) : "";
+ status.setText(message);
+ status.setToolTipText(message);
+ status.revalidate();
+ statusText.setLabelFor(editor != null ? editor.getContentComponent() : null);
+ }
+
+ protected void setValuesToConfig(Configuration config) {
+
+ MatchOptions options = config.getMatchOptions();
+
+ boolean searchWithinHierarchy = IdeBundle.message("scope.class.hierarchy").equals(myScopeChooserCombo.getSelectedScopeName());
+ // We need to reset search within hierarchy scope during online validation since the scope works with user participation
+ options.setScope(
+ searchWithinHierarchy && !myDoingOkAction ? GlobalSearchScope.projectScope(getProject()) : myScopeChooserCombo.getSelectedScope());
+ options.setLooseMatching(true);
+ options.setRecursiveSearch(isRecursiveSearchEnabled() && recursiveMatching.isSelected());
+
+ ourFtSearchVariant = (FileType)fileTypes.getSelectedItem();
+ ourDialect = (Language)dialects.getSelectedItem();
+ ourContext = (String)contexts.getSelectedItem();
+ FileType fileType = ourFtSearchVariant;
+ options.setFileType(fileType);
+ options.setDialect(ourDialect);
+ options.setPatternContext(ourContext);
+
+ options.setSearchPattern(searchCriteriaEdit.getDocument().getText());
+ options.setCaseSensitiveMatch(caseSensitiveMatch.isSelected());
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.structuralsearch.plugin.ui.SearchDialog";
+ }
+
+ @Override
+ public void dispose() {
+ Configuration.setActiveCreator(null);
+ disposeEditorContent();
+
+ myAlarm.cancelAllRequests();
+
+ super.dispose();
+ StructuralSearchPlugin.getInstance(getProject()).setDialogVisible(false);
+ }
+
+ protected void disposeEditorContent() {
+ mySavedEditorText = searchCriteriaEdit.getDocument().getText();
+
+ // this will remove from myExcludedSet
+ final PsiFile file = PsiDocumentManager.getInstance(searchContext.getProject()).getPsiFile(searchCriteriaEdit.getDocument());
+ if (file != null) {
+ DaemonCodeAnalyzer.getInstance(searchContext.getProject()).setHighlightingEnabled(file, true);
+ }
+
+ EditorFactory.getInstance().releaseEditor(searchCriteriaEdit);
+ }
+
+ @Override
+ protected String getHelpId() {
+ return "find.structuredSearch";
+ }
+
+ public SearchContext getSearchContext() {
+ return searchContext;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchModel.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchModel.java
new file mode 100644
index 000000000000..812ca6b0dc9b
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchModel.java
@@ -0,0 +1,29 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 25, 2004
+ * Time: 1:33:10 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SearchModel {
+ private final Configuration config;
+ private Configuration shadowConfig;
+
+ public SearchModel(Configuration config) {
+ this.config = config;
+ }
+
+ public Configuration getConfig() {
+ return config;
+ }
+
+ public void setShadowConfig(Configuration shadowConfig) {
+ this.shadowConfig = shadowConfig;
+ }
+
+ public Configuration getShadowConfig() {
+ return shadowConfig;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java
new file mode 100644
index 000000000000..b74715ecf07a
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SelectTemplateDialog.java
@@ -0,0 +1,294 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Splitter;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 23, 2004
+ * Time: 5:03:52 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SelectTemplateDialog extends DialogWrapper {
+ private final boolean showHistory;
+ private Editor searchPatternEditor;
+ private Editor replacePatternEditor;
+ private final boolean replace;
+ private final Project project;
+ private final ExistingTemplatesComponent existingTemplatesComponent;
+
+ private MySelectionListener selectionListener;
+ private CardLayout myCardLayout;
+ private JPanel myPreviewPanel;
+ @NonNls private static final String PREVIEW_CARD = "Preview";
+ @NonNls private static final String SELECT_TEMPLATE_CARD = "SelectCard";
+
+ public SelectTemplateDialog(Project project, boolean showHistory, boolean replace) {
+ super(project, false);
+
+ this.project = project;
+ this.showHistory = showHistory;
+ this.replace = replace;
+ existingTemplatesComponent = ExistingTemplatesComponent.getInstance(this.project);
+
+ setTitle(SSRBundle.message(this.showHistory ? "used.templates.history.dialog.title" : "existing.templates.dialog.title"));
+ init();
+
+ if (this.showHistory) {
+ final int selection = existingTemplatesComponent.getHistoryList().getSelectedIndex();
+ if (selection != -1) {
+ setPatternFromList(selection);
+ }
+ }
+ else {
+ final TreePath selection = existingTemplatesComponent.getPatternTree().getSelectionPath();
+ if (selection != null) {
+ setPatternFromNode((DefaultMutableTreeNode)selection.getLastPathComponent());
+ }
+ else {
+ showPatternPreviewFromConfiguration(null);
+ }
+ }
+
+ setupListeners();
+ }
+
+ class MySelectionListener implements TreeSelectionListener, ListSelectionListener {
+ public void valueChanged(TreeSelectionEvent e) {
+ if (e.getNewLeadSelectionPath() != null) {
+ setPatternFromNode(
+ (DefaultMutableTreeNode)e.getNewLeadSelectionPath().getLastPathComponent()
+ );
+ }
+ }
+
+ public void valueChanged(ListSelectionEvent e) {
+ if (e.getValueIsAdjusting() || e.getLastIndex() == -1) return;
+ int selectionIndex = existingTemplatesComponent.getHistoryList().getSelectedIndex();
+ if (selectionIndex != -1) {
+ setPatternFromList(selectionIndex);
+ }
+ }
+ }
+
+ private void setPatternFromList(int index) {
+ showPatternPreviewFromConfiguration(
+ (Configuration)existingTemplatesComponent.getHistoryList().getModel().getElementAt(index)
+ );
+ }
+
+ protected JComponent createCenterPanel() {
+ final JPanel centerPanel = new JPanel(new BorderLayout());
+ Splitter splitter;
+
+ centerPanel.add(BorderLayout.CENTER, splitter = new Splitter(false, 0.3f));
+ centerPanel.add(splitter);
+
+ splitter.setFirstComponent(
+ showHistory ?
+ existingTemplatesComponent.getHistoryPanel() :
+ existingTemplatesComponent.getTemplatesPanel()
+ );
+ final JPanel panel;
+ splitter.setSecondComponent(
+ panel = new JPanel(new BorderLayout())
+ );
+
+ searchPatternEditor = UIUtil.createEditor(
+ EditorFactory.getInstance().createDocument(""),
+ project,
+ false,
+ true,
+ ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), TemplateContextType.class)
+ );
+
+ JComponent centerComponent;
+
+ if (replace) {
+ replacePatternEditor = UIUtil.createEditor(
+ EditorFactory.getInstance().createDocument(""),
+ project,
+ false,
+ true,
+ ContainerUtil.findInstance(TemplateContextType.EP_NAME.getExtensions(), TemplateContextType.class)
+ );
+ centerComponent = new Splitter(true);
+ ((Splitter)centerComponent).setFirstComponent(searchPatternEditor.getComponent());
+ ((Splitter)centerComponent).setSecondComponent(replacePatternEditor.getComponent());
+ }
+ else {
+ centerComponent = searchPatternEditor.getComponent();
+ }
+
+ myCardLayout = new CardLayout();
+ myPreviewPanel = new JPanel(myCardLayout);
+ myPreviewPanel.add(centerComponent, PREVIEW_CARD);
+ JPanel selectPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gb = new GridBagConstraints(0,0,0,0,0,0,GridBagConstraints.CENTER,GridBagConstraints.NONE, new Insets(0,0,0,0),0,0);
+ selectPanel.add(new JLabel(SSRBundle.message("selecttemplate.template.label.please.select.template")), gb);
+ myPreviewPanel.add(selectPanel, SELECT_TEMPLATE_CARD);
+
+ panel.add(BorderLayout.CENTER, myPreviewPanel);
+
+ panel.add(BorderLayout.NORTH, new JLabel(SSRBundle.message("selecttemplate.template.preview")));
+ return centerPanel;
+ }
+
+ public void dispose() {
+ EditorFactory.getInstance().releaseEditor(searchPatternEditor);
+ if (replacePatternEditor != null) EditorFactory.getInstance().releaseEditor(replacePatternEditor);
+ removeListeners();
+ super.dispose();
+ }
+
+ public JComponent getPreferredFocusedComponent() {
+ return showHistory ?
+ existingTemplatesComponent.getHistoryList() :
+ existingTemplatesComponent.getPatternTree();
+ }
+
+ protected String getDimensionServiceKey() {
+ return "#com.intellij.structuralsearch.plugin.ui.SelectTemplateDialog";
+ }
+
+ private void setupListeners() {
+ existingTemplatesComponent.setOwner(this);
+ selectionListener = new MySelectionListener();
+
+ if (showHistory) {
+ existingTemplatesComponent.getHistoryList().getSelectionModel().addListSelectionListener(
+ selectionListener
+ );
+ }
+ else {
+ existingTemplatesComponent.getPatternTree().getSelectionModel().addTreeSelectionListener(
+ selectionListener
+ );
+ }
+ }
+
+ private void removeListeners() {
+ existingTemplatesComponent.setOwner(null);
+ if (showHistory) {
+ existingTemplatesComponent.getHistoryList().getSelectionModel().removeListSelectionListener(
+ selectionListener
+ );
+ }
+ else {
+ existingTemplatesComponent.getPatternTree().getSelectionModel().removeTreeSelectionListener(selectionListener);
+ }
+ }
+
+ private void setPatternFromNode(DefaultMutableTreeNode node) {
+ if (node == null) return;
+ final Object userObject = node.getUserObject();
+ final Configuration configuration;
+
+ // root could be without search template
+ if (userObject instanceof Configuration) {
+ configuration = (Configuration)userObject;
+ }
+ else {
+ configuration = null;
+ }
+
+ showPatternPreviewFromConfiguration(configuration);
+ }
+
+ private void showPatternPreviewFromConfiguration(@Nullable final Configuration configuration) {
+ if (configuration == null) {
+ myCardLayout.show(myPreviewPanel, SELECT_TEMPLATE_CARD);
+ return;
+ }
+ else {
+ myCardLayout.show(myPreviewPanel, PREVIEW_CARD);
+ }
+ final MatchOptions matchOptions = configuration.getMatchOptions();
+
+ UIUtil.setContent(
+ searchPatternEditor,
+ matchOptions.getSearchPattern(),
+ 0,
+ searchPatternEditor.getDocument().getTextLength(),
+ project
+ );
+
+ searchPatternEditor.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, configuration);
+
+ if (replace) {
+ String replacement;
+
+ if (configuration instanceof ReplaceConfiguration) {
+ replacement = ((ReplaceConfiguration)configuration).getOptions().getReplacement();
+ }
+ else {
+ replacement = configuration.getMatchOptions().getSearchPattern();
+ }
+
+ UIUtil.setContent(
+ replacePatternEditor,
+ replacement,
+ 0,
+ replacePatternEditor.getDocument().getTextLength(),
+ project
+ );
+
+ replacePatternEditor.putUserData(SubstitutionShortInfoHandler.CURRENT_CONFIGURATION_KEY, configuration);
+ }
+ }
+
+ @NotNull public Configuration[] getSelectedConfigurations() {
+ if (showHistory) {
+ Object[] selectedValues = existingTemplatesComponent.getHistoryList().getSelectedValues();
+ if (selectedValues == null) {
+ return new Configuration[0];
+ }
+ Collection<Configuration> configurations = new ArrayList<Configuration>();
+ for (Object selectedValue : selectedValues) {
+ if (selectedValue instanceof Configuration) {
+ configurations.add((Configuration)selectedValue);
+ }
+ }
+ return configurations.toArray(new Configuration[configurations.size()]);
+ }
+ else {
+ TreePath[] paths = existingTemplatesComponent.getPatternTree().getSelectionModel().getSelectionPaths();
+ if (paths == null) {
+ return new Configuration[0];
+ }
+ Collection<Configuration> configurations = new ArrayList<Configuration>();
+ for (TreePath path : paths) {
+
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
+ final Object userObject = node.getUserObject();
+ if (userObject instanceof Configuration) {
+ configurations.add((Configuration)userObject);
+ }
+ }
+ return configurations.toArray(new Configuration[configurations.size()]);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java
new file mode 100644
index 000000000000..32f1302336f3
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java
@@ -0,0 +1,114 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.codeInsight.hint.TooltipGroup;
+import com.intellij.codeInsight.template.impl.TemplateImplUtil;
+import com.intellij.codeInsight.template.impl.Variable;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.LogicalPosition;
+import com.intellij.openapi.editor.event.*;
+import com.intellij.openapi.util.Key;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 23, 2004
+ * Time: 5:20:56 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SubstitutionShortInfoHandler implements DocumentListener, EditorMouseMotionListener, CaretListener {
+ private static final TooltipGroup SS_INFO_TOOLTIP_GROUP = new TooltipGroup("SS_INFO_TOOLTIP_GROUP", 0);
+
+ private long modificationTimeStamp;
+ private final ArrayList<Variable> variables = new ArrayList<Variable>();
+ private final Editor editor;
+ public static final Key<Configuration> CURRENT_CONFIGURATION_KEY = Key.create("SS.CurrentConfiguration");
+
+ SubstitutionShortInfoHandler(@NotNull Editor _editor) {
+ editor = _editor;
+ }
+
+ public void beforeDocumentChange(DocumentEvent event) {
+ }
+
+ public void documentChanged(DocumentEvent event) {
+ }
+
+ public void mouseMoved(EditorMouseEvent e) {
+ LogicalPosition position = editor.xyToLogicalPosition( e.getMouseEvent().getPoint() );
+
+ handleInputFocusMovement(position);
+ }
+
+ private void handleInputFocusMovement(LogicalPosition position) {
+ checkModelValidity();
+ String text = "";
+ final int offset = editor.logicalPositionToOffset(position);
+ final int length = editor.getDocument().getTextLength();
+ final CharSequence elements = editor.getDocument().getCharsSequence();
+
+ int start = offset-1;
+ int end = -1;
+ while(start >=0 && Character.isJavaIdentifierPart(elements.charAt(start)) && elements.charAt(start)!='$') start--;
+
+ if (start >=0 && elements.charAt(start)=='$') {
+ end = offset;
+
+ while(end < length && Character.isJavaIdentifierPart(elements.charAt(end)) && elements.charAt(end)!='$') end++;
+ if (end < length && elements.charAt(end)=='$') {
+ String varname = elements.subSequence(start + 1, end).toString();
+ Variable foundVar = null;
+
+ for(Iterator<Variable> i=variables.iterator();i.hasNext();) {
+ final Variable var = i.next();
+
+ if (var.getName().equals(varname)) {
+ foundVar = var;
+ break;
+ }
+ }
+
+ if (foundVar!=null) {
+ text = UIUtil.getShortParamString(editor.getUserData(CURRENT_CONFIGURATION_KEY),varname);
+ }
+ }
+ }
+
+ if (text.length() > 0) {
+ UIUtil.showTooltip(editor, start, end, text, SS_INFO_TOOLTIP_GROUP);
+ }
+ }
+
+ private void checkModelValidity() {
+ Document document = editor.getDocument();
+ if (modificationTimeStamp != document.getModificationStamp()) {
+ variables.clear();
+ variables.addAll(TemplateImplUtil.parseVariables(document.getCharsSequence()).values());
+ modificationTimeStamp = document.getModificationStamp();
+ }
+ }
+
+ public void mouseDragged(EditorMouseEvent e) {
+ }
+
+ public void caretPositionChanged(CaretEvent e) {
+ handleInputFocusMovement(e.getNewPosition());
+ }
+
+ @Override
+ public void caretAdded(CaretEvent e) {
+ }
+
+ @Override
+ public void caretRemoved(CaretEvent e) {
+ }
+
+ public ArrayList<Variable> getVariables() {
+ checkModelValidity();
+ return variables;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
new file mode 100644
index 000000000000..aa3ca82725b0
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
@@ -0,0 +1,241 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.codeInsight.hint.TooltipController;
+import com.intellij.codeInsight.hint.TooltipGroup;
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.codeInsight.template.impl.TemplateContext;
+import com.intellij.codeInsight.template.impl.TemplateEditorUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.EditorSettings;
+import com.intellij.openapi.editor.colors.EditorColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.*;
+import com.intellij.structuralsearch.plugin.StructuralReplaceAction;
+import com.intellij.structuralsearch.plugin.StructuralSearchAction;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
+import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Maxim.Mossienko
+ * Date: Apr 21, 2004
+ * Time: 7:50:48 PM
+ */
+public class UIUtil {
+ static Key<SubstitutionShortInfoHandler> LISTENER_KEY = Key.create("sslistener.key");
+ private static final String MODIFY_EDITOR_CONTENT = SSRBundle.message("modify.editor.content.command.name");
+ @NonNls private static final String SS_GROUP = "structuralsearchgroup";
+
+ @NotNull
+ public static Editor createEditor(Document doc, final Project project, boolean editable, @Nullable TemplateContextType contextType) {
+ return createEditor(doc, project, editable, false, contextType);
+ }
+
+ @NotNull
+ public static Editor createEditor(@NotNull Document doc,
+ final Project project,
+ boolean editable,
+ boolean addToolTipForVariableHandler,
+ @Nullable TemplateContextType contextType) {
+ final Editor editor =
+ editable ? EditorFactory.getInstance().createEditor(doc, project) : EditorFactory.getInstance().createViewer(doc, project);
+
+ EditorSettings editorSettings = editor.getSettings();
+ editorSettings.setVirtualSpace(false);
+ editorSettings.setLineMarkerAreaShown(false);
+ editorSettings.setIndentGuidesShown(false);
+ editorSettings.setLineNumbersShown(false);
+ editorSettings.setFoldingOutlineShown(false);
+
+ EditorColorsScheme scheme = editor.getColorsScheme();
+ scheme.setColor(EditorColors.CARET_ROW_COLOR, null);
+ if (!editable) {
+ final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
+ Color c = globalScheme.getColor(EditorColors.READONLY_BACKGROUND_COLOR);
+
+ if (c == null) {
+ c = globalScheme.getDefaultBackground();
+ }
+
+ ((EditorEx)editor).setBackgroundColor(c);
+ }
+ else {
+ ((EditorEx)editor).setEmbeddedIntoDialogWrapper(true);
+ }
+
+ if (contextType != null) {
+ TemplateContext context = new TemplateContext();
+ context.setEnabled(contextType, true);
+ TemplateEditorUtil.setHighlighter(editor, context);
+ }
+
+ if (addToolTipForVariableHandler) {
+ SubstitutionShortInfoHandler handler = new SubstitutionShortInfoHandler(editor);
+ editor.addEditorMouseMotionListener(handler);
+ editor.getDocument().addDocumentListener(handler);
+ editor.getCaretModel().addCaretListener(handler);
+ editor.putUserData(LISTENER_KEY, handler);
+ }
+
+ return editor;
+ }
+
+ public static JComponent createOptionLine(JComponent[] options) {
+ JPanel tmp = new JPanel();
+
+ tmp.setLayout(new BoxLayout(tmp, BoxLayout.X_AXIS));
+ for (int i = 0; i < options.length; i++) {
+ if (i != 0) {
+ tmp.add(Box.createHorizontalStrut(com.intellij.util.ui.UIUtil.DEFAULT_HGAP));
+ }
+ tmp.add(options[i]);
+ }
+ tmp.add(Box.createHorizontalGlue());
+
+ return tmp;
+ }
+
+ public static JComponent createOptionLine(JComponent option) {
+ return createOptionLine(new JComponent[]{option});
+ }
+
+ public static void setContent(final Editor editor, String val, final int from, final int end, final Project project) {
+ final String value = val != null ? val : "";
+
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ editor.getDocument().replaceString(from, (end == -1) ? editor.getDocument().getTextLength() : end, value);
+ }
+ });
+ }
+ }, MODIFY_EDITOR_CONTENT, SS_GROUP);
+ }
+
+ static String getShortParamString(Configuration config, String varname) {
+ if (config == null) return "";
+ final MatchOptions options = config.getMatchOptions();
+
+
+ final MatchVariableConstraint constraint = options == null ? null : options.getVariableConstraint(varname);
+ NamedScriptableDefinition namedScriptableDefinition = constraint;
+
+ final ReplacementVariableDefinition replacementVariableDefinition =
+ config instanceof ReplaceConfiguration ? ((ReplaceConfiguration)config).getOptions().getVariableDefinition(varname) : null;
+ if (replacementVariableDefinition != null) namedScriptableDefinition = replacementVariableDefinition;
+
+ if (constraint == null && replacementVariableDefinition == null) {
+ return SSRBundle.message("no.constraints.specified.tooltip.message");
+ }
+
+ final StringBuilder buf = new StringBuilder();
+
+ if (constraint != null) {
+ if (constraint.isPartOfSearchResults()) {
+ append(buf, SSRBundle.message("target.tooltip.message"));
+ }
+ if (constraint.getRegExp() != null && constraint.getRegExp().length() > 0) {
+ append(buf, SSRBundle.message("text.tooltip.message", constraint.isInvertRegExp() ? SSRBundle.message("not.tooltip.message") : "",
+ constraint.getRegExp(),
+ constraint.isWithinHierarchy() || constraint.isStrictlyWithinHierarchy() ?
+ SSRBundle.message("within.hierarchy.tooltip.message") : ""));
+ }
+
+ if (constraint.getNameOfExprType() != null && constraint.getNameOfExprType().length() > 0) {
+ append(buf, SSRBundle.message("exprtype.tooltip.message",
+ constraint.isInvertExprType() ? SSRBundle.message("not.tooltip.message") : "",
+ constraint.getNameOfExprType(),
+ constraint.isExprTypeWithinHierarchy() ? SSRBundle.message("within.hierarchy.tooltip.message") : ""));
+ }
+
+ if (constraint.getMinCount() == constraint.getMaxCount()) {
+ append(buf, SSRBundle.message("occurs.tooltip.message", constraint.getMinCount()));
+ }
+ else {
+ append(buf, SSRBundle.message("min.occurs.tooltip.message", constraint.getMinCount(),
+ constraint.getMaxCount() == Integer.MAX_VALUE ?
+ StringUtil.decapitalize(SSRBundle.message("editvarcontraints.unlimited")) :
+ constraint.getMaxCount()));
+ }
+ }
+
+ final String script = namedScriptableDefinition.getScriptCodeConstraint();
+ if (script != null && script.length() > 2) {
+ final String str = SSRBundle.message("script.tooltip.message", StringUtil.stripQuotesAroundValue(script));
+ append(buf, str);
+ }
+
+ return buf.toString();
+ }
+
+ private static void append(final StringBuilder buf, final String str) {
+ if (buf.length() > 0) buf.append(", ");
+ buf.append(str);
+ }
+
+ public static void navigate(PsiElement result) {
+ FileEditorManager.getInstance(result.getProject()).openTextEditor(
+ new OpenFileDescriptor(result.getProject(), result.getContainingFile().getVirtualFile(), result.getTextOffset()), true);
+ }
+
+ public static void navigate(MatchResult result) {
+ final SmartPsiPointer ref = result.getMatchRef();
+
+ FileEditorManager.getInstance(ref.getProject())
+ .openTextEditor(new OpenFileDescriptor(ref.getProject(), ref.getFile(), ref.getOffset()), true);
+ }
+
+ public static void invokeAction(Configuration config, SearchContext context) {
+ if (config instanceof SearchConfiguration) {
+ StructuralSearchAction.triggerAction(config, context);
+ }
+ else {
+ StructuralReplaceAction.triggerAction(config, context);
+ }
+ }
+
+ static void showTooltip(@NotNull Editor editor, final int start, int end, @NotNull String text, @NotNull TooltipGroup group) {
+ Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
+ Point top = editor.logicalPositionToXY(editor.offsetToLogicalPosition(start));
+ final int documentLength = editor.getDocument().getTextLength();
+ if (end >= documentLength) end = documentLength;
+ Point bottom = editor.logicalPositionToXY(editor.offsetToLogicalPosition(end));
+
+ Point bestPoint = new Point(top.x, bottom.y + editor.getLineHeight());
+
+ if (!visibleArea.contains(bestPoint)) {
+ int defaultOffset = editor.logicalPositionToOffset(editor.xyToLogicalPosition(new Point(0, 0)));
+ bestPoint = editor.logicalPositionToXY(editor.offsetToLogicalPosition(defaultOffset));
+ }
+
+ Point p = SwingUtilities.convertPoint(editor.getContentComponent(), bestPoint, editor.getComponent().getRootPane().getLayeredPane());
+ TooltipController.getInstance().showTooltip(editor, p, text, false, group);
+ }
+
+ public static void updateHighlighter(Editor editor, StructuralSearchProfile profile) {
+ final TemplateContextType contextType = profile.getTemplateContextType();
+ if (contextType != null) {
+ TemplateContext context = new TemplateContext();
+ context.setEnabled(contextType, true);
+ TemplateEditorUtil.setHighlighter(editor, context);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
new file mode 100644
index 000000000000..a55a16d4c379
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
@@ -0,0 +1,183 @@
+package com.intellij.structuralsearch.plugin.ui;
+
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.plugin.replace.ui.ReplaceCommand;
+import com.intellij.usages.*;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.Set;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 9, 2005
+ * Time: 2:47:49 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class UsageViewContext {
+ protected final SearchContext mySearchContext;
+ private UsageView myUsageView;
+ protected final Configuration myConfiguration;
+ private Set<Usage> myExcludedSet;
+ private SearchCommand myCommand;
+
+ protected UsageViewContext(SearchContext _searchContext,Configuration _configuration) {
+ myConfiguration = _configuration;
+ mySearchContext = _searchContext;
+ }
+
+ public boolean isExcluded(Usage usage) {
+ if (myExcludedSet == null) myExcludedSet = myUsageView.getExcludedUsages();
+ return myExcludedSet.contains(usage);
+ }
+
+ public UsageView getUsageView() {
+ return myUsageView;
+ }
+
+ public void setUsageView(final UsageView usageView) {
+ myUsageView = usageView;
+ }
+
+ public Configuration getConfiguration() {
+ return myConfiguration;
+ }
+
+ public SearchCommand getCommand() {
+ if (myCommand == null) myCommand = createCommand();
+ return myCommand;
+ }
+
+ protected SearchCommand createCommand() {
+ return new SearchCommand(mySearchContext.getProject(), this);
+ }
+
+ protected String _getPresentableText() {
+ return myConfiguration.getMatchOptions().getSearchPattern();
+ }
+
+ public UsageTarget getTarget() {
+ return new MyUsageTarget(_getPresentableText());
+ }
+
+ public void configure(@NotNull UsageViewPresentation presentation) {
+ String s = _getPresentableText();
+ if (s.length() > 15) s = s.substring(0,15) + "...";
+ final String usagesString = SSRBundle.message("occurrences.of", s);
+ presentation.setUsagesString(usagesString);
+ presentation.setTabText(StringUtil.capitalize(usagesString));
+ presentation.setUsagesWord(SSRBundle.message("occurrence"));
+ presentation.setCodeUsagesString(SSRBundle.message("found.occurrences"));
+ }
+
+ protected void configureActions() {}
+
+ private class MyUsageTarget implements ConfigurableUsageTarget,ItemPresentation {
+ private final String myPresentableText;
+
+ MyUsageTarget(String str) {
+ myPresentableText = str;
+ }
+
+ @Override
+ public String getPresentableText() {
+ return myPresentableText;
+ }
+
+ @Override
+ public String getLocationString() {
+ //noinspection HardCodedStringLiteral
+ return "Do Not Know Where";
+ }
+
+ @Override
+ public Icon getIcon(boolean open) {
+ return null;
+ }
+
+ @Override
+ public void findUsages() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void findUsagesInEditor(@NotNull FileEditor editor) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void highlightUsages(@NotNull PsiFile file, @NotNull Editor editor, boolean clearHighlights) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ @Override
+ public VirtualFile[] getFiles() {
+ return null;
+ }
+
+ @Override
+ public void update() {
+ }
+
+ @Override
+ public String getName() {
+ //noinspection HardCodedStringLiteral
+ return "my name";
+ }
+
+ @Override
+ public ItemPresentation getPresentation() {
+ return this;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return false;
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return false;
+ }
+
+ @Override
+ public void showSettings() {
+ UIUtil.invokeAction(myConfiguration, mySearchContext);
+ }
+
+ @Override
+ public KeyboardShortcut getShortcut() {
+ return ActionManager.getInstance().getKeyboardShortcut(getCommand() instanceof ReplaceCommand ? "StructuralSearchPlugin.StructuralReplaceAction":"StructuralSearchPlugin.StructuralSearchAction");
+ }
+
+ @NotNull
+ @Override
+ public String getLongDescriptiveName() {
+ return _getPresentableText();
+ }
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/VarConstraints.form b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/VarConstraints.form
new file mode 100644
index 000000000000..20094b213e64
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/VarConstraints.form
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.structuralsearch.plugin.ui.EditVarConstraintsDialog">
+ <grid id="53af4" binding="mainForm" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="24" y="82" width="889" height="681"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="33d30" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="8" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
+ </clientProperties>
+ <border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.variables.border"/>
+ <children>
+ <grid id="d6a7" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="e85ba" class="com.intellij.ui.components.JBList" binding="parameterList">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="2" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="50"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ <grid id="4cae8" binding="textConstraintsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.text.constraints.border"/>
+ <children>
+ <component id="cc210" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression"/>
+ </properties>
+ </component>
+ <component id="3b03c" class="com.intellij.ui.EditorTextField" binding="regexp" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="f7d70" class="javax.swing.JCheckBox" binding="applyWithinTypeHierarchy">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.apply.constraint.within.type.hierarchy"/>
+ </properties>
+ </component>
+ <component id="b766f" class="javax.swing.JCheckBox" binding="notRegexp">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ <component id="51cbf" class="javax.swing.JCheckBox" binding="wholeWordsOnly">
+ <constraints>
+ <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.whole.words.only"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <grid id="bb81f" binding="expressionConstraints" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.expression.constraints.border"/>
+ <children>
+ <component id="2bdb4" class="javax.swing.JCheckBox" binding="read">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.value.is.read"/>
+ </properties>
+ </component>
+ <component id="aba7e" class="javax.swing.JCheckBox" binding="write">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.value.is.written"/>
+ </properties>
+ </component>
+ <component id="5698c" class="javax.swing.JCheckBox" binding="notRead">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ <component id="79e72" class="javax.swing.JCheckBox" binding="notWrite">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ <component id="e9391" class="com.intellij.ui.EditorTextField" binding="regexprForExprType" custom-create="true">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="59512" class="javax.swing.JCheckBox" binding="exprTypeWithinHierarchy">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.apply.constraint.within.type.hierarchy"/>
+ </properties>
+ </component>
+ <component id="17342" class="javax.swing.JCheckBox" binding="notExprType">
+ <constraints>
+ <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ <component id="4d6d0" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression.for.java.expression.type"/>
+ </properties>
+ </component>
+ <component id="a97fa" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method"/>
+ </properties>
+ </component>
+ <component id="d02c2" class="com.intellij.ui.EditorTextField" binding="formalArgType" custom-create="true">
+ <constraints>
+ <grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="bc6d0" class="javax.swing.JCheckBox" binding="invertFormalArgType">
+ <constraints>
+ <grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ <component id="2b0ea" class="javax.swing.JCheckBox" binding="formalArgTypeWithinHierarchy">
+ <constraints>
+ <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.apply.constraint.within.type.hierarchy"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <component id="9a3a8" class="javax.swing.JCheckBox" binding="partOfSearchResults">
+ <constraints>
+ <grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.this.variable.is.target.of.the.search"/>
+ </properties>
+ </component>
+ <vspacer id="d06dd">
+ <constraints>
+ <grid row="7" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <grid id="2a918" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="5" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <grid id="964fd" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.script.constraints.border"/>
+ <children>
+ <component id="cdf9" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="script.option.text"/>
+ </properties>
+ </component>
+ <component id="e7633" class="com.intellij.openapi.ui.ComponentWithBrowseButton" binding="customScriptCode" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+ </children>
+ </grid>
+ <grid id="d8664" binding="occurencePanel" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title-resource-bundle="messages/SSRBundle" title-key="var.constraints.occurrences.count.border"/>
+ <children>
+ <component id="e4b4a" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.minimum.count"/>
+ </properties>
+ </component>
+ <component id="f6a1a" class="javax.swing.JTextField" binding="minoccurs">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="50" height="-1"/>
+ <maximum-size width="50" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <text value="1"/>
+ </properties>
+ </component>
+ <component id="881e7" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.maximum.count"/>
+ </properties>
+ </component>
+ <component id="42" class="javax.swing.JTextField" binding="maxoccurs">
+ <constraints>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="50" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <columns value="0"/>
+ <text value="1"/>
+ </properties>
+ </component>
+ <component id="7c33b" class="javax.swing.JCheckBox" binding="maxoccursUnlimited">
+ <constraints>
+ <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.unlimited"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <grid id="463bd" binding="containedInConstraints" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="none" title="Contained in constraints"/>
+ <children>
+ <component id="7003f" class="com.intellij.ui.ComboboxWithBrowseButton" binding="withinCombo">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="896c2" class="javax.swing.JCheckBox" binding="invertWithinIn">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/SSRBundle" key="editvarcontraints.invert.condition"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+ <component id="ce461" class="javax.swing.JLabel" binding="myRegExHelpLabel" custom-create="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/actions/DoSearchAction.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/actions/DoSearchAction.java
new file mode 100644
index 000000000000..ed0da3a3f391
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/actions/DoSearchAction.java
@@ -0,0 +1,24 @@
+package com.intellij.structuralsearch.plugin.ui.actions;
+
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.*;
+import com.intellij.openapi.project.Project;
+
+/**
+ * Does the search action
+ */
+public class DoSearchAction {
+ public static void execute(final Project project, MatchResultSink sink,
+ final Configuration configuration) {
+ final MatchOptions options = configuration.getMatchOptions();
+
+ final Matcher matcher = new Matcher(project);
+ try {
+ matcher.findMatches(sink, options);
+ }
+ finally {
+ sink.matchingFinished();
+ }
+ }
+
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/CollectingMatchResultSink.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/CollectingMatchResultSink.java
new file mode 100644
index 000000000000..4caff77bdc06
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/CollectingMatchResultSink.java
@@ -0,0 +1,40 @@
+package com.intellij.structuralsearch.plugin.util;
+
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.psi.PsiFile;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.MatchResultSink;
+import com.intellij.structuralsearch.MatchingProcess;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class CollectingMatchResultSink implements MatchResultSink {
+ private final List<MatchResult> matches = new LinkedList<MatchResult>();
+
+ public void newMatch(MatchResult result) {
+ matches.add(result);
+ }
+
+ /* Notifies sink about starting the matching for given element
+ * @param element the current file
+ */
+ public void processFile(PsiFile element) {
+ }
+
+ public void matchingFinished() {
+ }
+
+ public ProgressIndicator getProgressIndicator() {
+ return null;
+ }
+
+ public void setMatchingProcess(MatchingProcess process) {
+ }
+
+ @NotNull
+ public List<MatchResult> getMatches() {
+ return matches;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/SmartPsiPointer.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/SmartPsiPointer.java
new file mode 100644
index 000000000000..0fee846c77b0
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/plugin/util/SmartPsiPointer.java
@@ -0,0 +1,56 @@
+package com.intellij.structuralsearch.plugin.util;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.SmartPointerManager;
+import com.intellij.psi.SmartPsiElementPointer;
+
+/**
+ * Reference to element have been matched
+ */
+public class SmartPsiPointer {
+ private SmartPsiElementPointer pointer;
+
+ public SmartPsiPointer(PsiElement element) {
+ pointer = element != null ? SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element):null;
+ }
+
+ public VirtualFile getFile() {
+ return pointer != null ? pointer.getVirtualFile():null;
+ }
+
+ public int getOffset() {
+ return pointer != null ? pointer.getElement().getTextRange().getStartOffset():-1;
+ }
+
+ public int getLength() {
+ return pointer != null ? pointer.getElement().getTextRange().getEndOffset():0;
+ }
+
+ public PsiElement getElement() {
+ return pointer != null ? pointer.getElement():null;
+ }
+
+ public void clear() {
+ pointer = null;
+ }
+
+ public Project getProject() {
+ return pointer != null ? pointer.getElement().getProject():null;
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof SmartPsiPointer) {
+ final SmartPsiPointer ref = ((SmartPsiPointer)o);
+ return ref.getFile().equals(getFile()) &&
+ ref.getOffset() == getOffset() &&
+ ref.getLength() == getLength();
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return pointer != null ? getElement().hashCode():0;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/AnonymToken.java b/plugins/structuralsearch/source/com/intellij/tokenindex/AnonymToken.java
new file mode 100644
index 000000000000..c364ccc3f9c5
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/AnonymToken.java
@@ -0,0 +1,34 @@
+package com.intellij.tokenindex;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AnonymToken extends Token {
+ private final byte myType;
+
+ public AnonymToken(byte type, int start, int end) {
+ super(start, end);
+ myType = type;
+ }
+
+ public byte getType() {
+ return myType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AnonymToken that = (AnonymToken)o;
+
+ if (myType != that.myType) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myType;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/IndentToken.java b/plugins/structuralsearch/source/com/intellij/tokenindex/IndentToken.java
new file mode 100644
index 000000000000..9409d185c808
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/IndentToken.java
@@ -0,0 +1,20 @@
+package com.intellij.tokenindex;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class IndentToken extends Token {
+ public IndentToken(int start, int end) {
+ super(start, end);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof IndentToken;
+ }
+
+ @Override
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/LanguageTokenizer.java b/plugins/structuralsearch/source/com/intellij/tokenindex/LanguageTokenizer.java
new file mode 100644
index 000000000000..7e8986b25ada
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/LanguageTokenizer.java
@@ -0,0 +1,14 @@
+package com.intellij.tokenindex;
+
+import com.intellij.lang.LanguageExtension;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class LanguageTokenizer extends LanguageExtension<Tokenizer> {
+ public static final LanguageTokenizer INSTANCE = new LanguageTokenizer();
+
+ private LanguageTokenizer() {
+ super("com.intellij.tokenindex.tokenizer", null);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/PathMarkerToken.java b/plugins/structuralsearch/source/com/intellij/tokenindex/PathMarkerToken.java
new file mode 100644
index 000000000000..f74590f46bb1
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/PathMarkerToken.java
@@ -0,0 +1,41 @@
+package com.intellij.tokenindex;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class PathMarkerToken extends Token {
+ private final String myPath;
+
+ public PathMarkerToken(@NotNull String path) {
+ super(-1, -1);
+ myPath = path;
+ }
+
+ public String getPath() {
+ return myPath;
+ }
+
+ @Override
+ public String toString() {
+ return myPath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PathMarkerToken that = (PathMarkerToken)o;
+
+ if (!myPath.equals(that.myPath)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myPath.hashCode();
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/PsiMarkerToken.java b/plugins/structuralsearch/source/com/intellij/tokenindex/PsiMarkerToken.java
new file mode 100644
index 000000000000..c2e7c8b3cf89
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/PsiMarkerToken.java
@@ -0,0 +1,19 @@
+package com.intellij.tokenindex;
+
+import com.intellij.psi.PsiFile;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class PsiMarkerToken extends Token {
+ private final PsiFile myFile;
+
+ public PsiMarkerToken(PsiFile file) {
+ super(-1, -1);
+ myFile = file;
+ }
+
+ public PsiFile getFile() {
+ return myFile;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/RecursiveTokenizingVisitor.java b/plugins/structuralsearch/source/com/intellij/tokenindex/RecursiveTokenizingVisitor.java
new file mode 100644
index 000000000000..013f804a8225
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/RecursiveTokenizingVisitor.java
@@ -0,0 +1,86 @@
+package com.intellij.tokenindex;
+
+import com.intellij.lang.Language;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
+import com.intellij.structuralsearch.StructuralSearchProfile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.util.containers.HashSet;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class RecursiveTokenizingVisitor extends PsiRecursiveElementWalkingVisitor {
+ private final int myBaseOffset;
+ private final List<Token> myTokens;
+ private final Set<String> myLanguages = new HashSet<String>();
+ private final Set<Language> myAcceptableLanguages;
+
+ private Language myLastLanguage;
+ private StructuralSearchProfile myLastProfile;
+
+ public RecursiveTokenizingVisitor(List<Token> tokens, Set<Language> acceptableLanguages, int baseOffset) {
+ super(true);
+ myTokens = tokens;
+ myAcceptableLanguages = acceptableLanguages;
+ myBaseOffset = baseOffset;
+ }
+
+ public RecursiveTokenizingVisitor(List<Token> tokens, Set<Language> acceptableLanguages) {
+ this(tokens, acceptableLanguages, 0);
+ }
+
+ public RecursiveTokenizingVisitor() {
+ this(new ArrayList<Token>(), null);
+ }
+
+ public List<Token> getTokens() {
+ return myTokens;
+ }
+
+ public void addToken(Token token) {
+ myTokens.add(token);
+ }
+
+ public Set<String> getLanguages() {
+ return myLanguages;
+ }
+
+ @Override
+ public void visitElement(PsiElement element) {
+ Language language = element.getLanguage();
+ if (language != myLastLanguage) {
+ myLastLanguage = language;
+ myLastProfile = StructuralSearchUtil.getProfileByPsiElement(element);
+ }
+ if (myLastProfile != null) {
+ language = myLastProfile.getLanguage(element);
+ }
+ if (myAcceptableLanguages == null || myAcceptableLanguages.contains(language)) {
+ Tokenizer tokenizer = StructuralSearchUtil.getTokenizerForLanguage(language);
+ if (tokenizer != null) {
+ myLanguages.add(language.getID());
+ if (!tokenizer.visit(element, this)) {
+ return;
+ }
+ }
+ }
+ super.visitElement(element);
+ }
+
+ @Override
+ protected void elementFinished(PsiElement element) {
+ Tokenizer tokenizer = StructuralSearchUtil.getTokenizerForLanguage(element.getLanguage());
+ if (tokenizer != null) {
+ tokenizer.elementFinished(element, this);
+ }
+ }
+
+ public int getBaseOffset() {
+ return myBaseOffset;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/TextToken.java b/plugins/structuralsearch/source/com/intellij/tokenindex/TextToken.java
new file mode 100644
index 000000000000..729491935cfe
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/TextToken.java
@@ -0,0 +1,39 @@
+package com.intellij.tokenindex;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class TextToken extends Token {
+ private final int myHash;
+
+ public TextToken(int hash, int start, int end) {
+ super(start, end);
+ myHash = hash;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TextToken textToken = (TextToken)o;
+
+ if (myHash != textToken.myHash) return false;
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(myHash);
+ }
+
+ @Override
+ public int hashCode() {
+ return myHash;
+ }
+
+ public int getHash() {
+ return myHash;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/Token.java b/plugins/structuralsearch/source/com/intellij/tokenindex/Token.java
new file mode 100644
index 000000000000..2b5428d31826
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/Token.java
@@ -0,0 +1,22 @@
+package com.intellij.tokenindex;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public abstract class Token {
+ private final int myStart;
+ private final int myEnd;
+
+ public Token(int start, int end) {
+ myStart = start;
+ myEnd = end;
+ }
+
+ public int getStart() {
+ return myStart;
+ }
+
+ public int getEnd() {
+ return myEnd;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndex.java b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndex.java
new file mode 100644
index 000000000000..4547092eb58f
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndex.java
@@ -0,0 +1,187 @@
+package com.intellij.tokenindex;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.indexing.*;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class TokenIndex extends FileBasedIndexExtension<TokenIndexKey, List<Token>> {
+ private static final int FILE_BLOCK_SIZE = 100;
+
+ public static final ID<TokenIndexKey, List<Token>> INDEX_ID = ID.create("token.index");
+
+ private static final int VERSION = 3;
+
+ private final KeyDescriptor<TokenIndexKey> myKeyDescriptor = new TokenIndexKeyDescriptor();
+
+ private static final int ANONYM_TOKEN_ID = 0;
+ private static final int TEXT_TOKEN_ID = 1;
+ private static final int MARKER_TOKEN_ID = 2;
+ private static final int INDENT_TOKEN_ID = 3;
+
+ private final DataExternalizer<List<Token>> myDataExternalizer = new DataExternalizer<List<Token>>() {
+ @Override
+ public void save(@NotNull DataOutput out, List<Token> value) throws IOException {
+ out.writeInt(value.size());
+ for (Token token : value) {
+ if (token instanceof AnonymToken) {
+ out.writeByte(ANONYM_TOKEN_ID);
+ out.writeInt(token.getStart());
+ out.writeInt(token.getEnd());
+ out.writeByte(((AnonymToken)token).getType());
+ }
+ else if (token instanceof TextToken) {
+ out.writeByte(TEXT_TOKEN_ID);
+ out.writeInt(token.getStart());
+ out.writeInt(token.getEnd());
+ out.writeInt(((TextToken)token).getHash());
+ }
+ else if (token instanceof PathMarkerToken) {
+ out.writeByte(MARKER_TOKEN_ID);
+ out.writeUTF(((PathMarkerToken)token).getPath());
+ }
+ else if (token instanceof IndentToken) {
+ out.writeByte(INDENT_TOKEN_ID);
+ out.writeInt(token.getStart());
+ out.writeInt(token.getEnd());
+ }
+ else {
+ assert false : "Unsupported token type " + token.getClass();
+ }
+ }
+ }
+
+ @Override
+ public List<Token> read(@NotNull DataInput in) throws IOException {
+ List<Token> result = new ArrayList<Token>();
+ int n = in.readInt();
+ for (int i = 0; i < n; i++) {
+ byte tokenTypeId = in.readByte();
+ switch (tokenTypeId) {
+ case ANONYM_TOKEN_ID: {
+ int start = in.readInt();
+ int end = in.readInt();
+ byte anonymTokenTypeValue = in.readByte();
+ result.add(new AnonymToken(anonymTokenTypeValue, start, end));
+ break;
+ }
+ case TEXT_TOKEN_ID: {
+ int start = in.readInt();
+ int end = in.readInt();
+ int hash = in.readInt();
+ result.add(new TextToken(hash, start, end));
+ break;
+ }
+ case MARKER_TOKEN_ID: {
+ String path = in.readUTF();
+ result.add(new PathMarkerToken(path));
+ break;
+ }
+ case INDENT_TOKEN_ID:
+ int start = in.readInt();
+ int end = in.readInt();
+ result.add(new IndentToken(start, end));
+ break;
+ }
+ }
+ return result;
+ }
+ };
+
+ @NotNull
+ @Override
+ public ID<TokenIndexKey, List<Token>> getName() {
+ return INDEX_ID;
+ }
+
+ private static int getBlockId(String filePath) {
+ int h = filePath.hashCode();
+ if (h < 0) {
+ h = -h;
+ }
+ return h % FILE_BLOCK_SIZE;
+ }
+
+ @NotNull
+ @Override
+ public DataIndexer<TokenIndexKey, List<Token>, FileContent> getIndexer() {
+ return new DataIndexer<TokenIndexKey, List<Token>, FileContent>() {
+ @Override
+ @NotNull
+ public Map<TokenIndexKey, List<Token>> map(@NotNull FileContent inputData) {
+ if (true) return Collections.EMPTY_MAP; // TODO: Eugene index is VERY unefficient and leads to OME
+ Map<TokenIndexKey, List<Token>> result = new HashMap<TokenIndexKey, List<Token>>(1);
+ RecursiveTokenizingVisitor visitor = new RecursiveTokenizingVisitor();
+ inputData.getPsiFile().accept(visitor);
+ List<Token> tokens = visitor.getTokens();
+ if (tokens.size() > 0) {
+ String path = inputData.getFile().getPath();
+ tokens.add(new PathMarkerToken(path));
+ TokenIndexKey key = new TokenIndexKey(visitor.getLanguages(), getBlockId(path));
+ result.put(key, tokens);
+ }
+ return result;
+ }
+ };
+ }
+
+ @NotNull
+ @Override
+ public KeyDescriptor<TokenIndexKey> getKeyDescriptor() {
+ return myKeyDescriptor;
+ }
+
+ @NotNull
+ @Override
+ public DataExternalizer<List<Token>> getValueExternalizer() {
+ return myDataExternalizer;
+ }
+
+ @NotNull
+ @Override
+ public FileBasedIndex.InputFilter getInputFilter() {
+ return new FileBasedIndex.InputFilter() {
+ @Override
+ public boolean acceptInput(@NotNull VirtualFile file) {
+ if (file.getFileSystem() instanceof JarFileSystem) return false;
+ return file.getFileType() instanceof LanguageFileType;
+ }
+ };
+ }
+
+ @Override
+ public boolean dependsOnFileContent() {
+ return true;
+ }
+
+ @Override
+ public int getVersion() {
+ return VERSION;
+ }
+
+ @Override
+ public int getCacheSize() {
+ return 1;
+ }
+
+ public static boolean supports(Language language) {
+ return StructuralSearchUtil.getTokenizerForLanguage(language) != null;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKey.java b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKey.java
new file mode 100644
index 000000000000..8c6ec1d93875
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKey.java
@@ -0,0 +1,60 @@
+package com.intellij.tokenindex;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class TokenIndexKey {
+ private final Set<String> myLanguages;
+ private final int myBlockId;
+
+ public TokenIndexKey(@NotNull Set<String> languages, int blockId) {
+ myLanguages = languages;
+ myBlockId = blockId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TokenIndexKey that = (TokenIndexKey)o;
+
+ if (myBlockId != that.myBlockId) return false;
+ if (!myLanguages.equals(that.myLanguages)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myLanguages.hashCode();
+ result = 31 * result + myBlockId;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return myLanguages + ": " + myBlockId;
+ }
+
+ public Set<String> getLanguages() {
+ return myLanguages;
+ }
+
+ public boolean containsLanguage(String languageId) {
+ for (String language : myLanguages) {
+ if (language.contains(languageId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public int getBlockId() {
+ return myBlockId;
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKeyDescriptor.java b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKeyDescriptor.java
new file mode 100644
index 000000000000..901508ce371d
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/TokenIndexKeyDescriptor.java
@@ -0,0 +1,43 @@
+package com.intellij.tokenindex;
+
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.io.KeyDescriptor;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class TokenIndexKeyDescriptor implements KeyDescriptor<TokenIndexKey> {
+ public int getHashCode(TokenIndexKey value) {
+ return value.hashCode();
+ }
+
+ public boolean isEqual(TokenIndexKey val1, TokenIndexKey val2) {
+ return val1.equals(val2);
+ }
+
+ public void save(@NotNull DataOutput out, TokenIndexKey value) throws IOException {
+ Set<String> languages = value.getLanguages();
+ out.writeInt(languages.size());
+ for (String language : languages) {
+ out.writeUTF(language);
+ }
+ out.writeInt(value.getBlockId());
+ }
+
+ public TokenIndexKey read(@NotNull DataInput in) throws IOException {
+ int languagesCount = in.readInt();
+ Set<String> languages = new HashSet<String>();
+ for (int i = 0; i < languagesCount; i++) {
+ String languageId = in.readUTF();
+ languages.add(languageId);
+ }
+ int blockId = in.readInt();
+ return new TokenIndexKey(languages, blockId);
+ }
+}
diff --git a/plugins/structuralsearch/source/com/intellij/tokenindex/Tokenizer.java b/plugins/structuralsearch/source/com/intellij/tokenindex/Tokenizer.java
new file mode 100644
index 000000000000..c1ce0c70e264
--- /dev/null
+++ b/plugins/structuralsearch/source/com/intellij/tokenindex/Tokenizer.java
@@ -0,0 +1,13 @@
+package com.intellij.tokenindex;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public interface Tokenizer {
+ boolean visit(@NotNull PsiElement element, RecursiveTokenizingVisitor globalVisitor);
+
+ void elementFinished(@NotNull PsiElement element, RecursiveTokenizingVisitor globalVisitor);
+}
diff --git a/plugins/structuralsearch/source/inspectionDescriptions/SSBasedInspection.html b/plugins/structuralsearch/source/inspectionDescriptions/SSBasedInspection.html
new file mode 100644
index 000000000000..b013f6beba4b
--- /dev/null
+++ b/plugins/structuralsearch/source/inspectionDescriptions/SSBasedInspection.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+<p>This inspection allows to configure number of <b>Structural Search/Structural Replace</b> templates to be applied to the file you are editing.
+</p>
+<p>All matches are highlighted with the template name you have configured.
+If you configured <b>Structural Replace</b> pattern, corresponding replace would appear as a quick fix.
+</p>
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/structuralsearch/source/messages/SSRBundle.properties b/plugins/structuralsearch/source/messages/SSRBundle.properties
new file mode 100644
index 000000000000..488c96e84435
--- /dev/null
+++ b/plugins/structuralsearch/source/messages/SSRBundle.properties
@@ -0,0 +1,240 @@
+search.produced.too.many.results.message=Search produced too many results, stopping the search process
+
+structuralreplace.action=StructuralReplaceAction
+structuralsearch.action=StructuralSearchAction
+
+#replacement dialog preview
+structural.replace.preview.dialog.title=Structural Replace Preview
+replace.preview.oktext=&Replace
+replacement.code=Replacement code
+
+# Search Dialog specific titles/options
+structural.search.title=Structural Search
+search.template=Search template:
+template.name.button=Template name
+
+save.template.description.button=Save Template
+save.template.text.button=S&ave template...
+ssdialog.options.group.border=Options
+new.template.defaultname=user defined
+
+recursive.matching.checkbox=&Recursive matching
+
+edit.variables.button=E&dit variables...
+history.button=&History...
+copy.existing.template.button=Co&py existing template...
+
+open.in.new.tab.checkbox=Open in new &tab
+
+search.dialog.scope.label=&Scope
+search.dialog.file.type.label=File t&ype:
+search.dialog.context.label=C&ontext:
+search.dialog.file.dialect.label=D&ialect:
+
+#search usage view specific
+looking.in.progress.message=Looking in {0}
+found.progress.message=Found {0} occurrences
+occurrences.of=occurrences of {0}
+occurrence=occurrence
+found.occurrences=Found occurrence
+
+# search dialog messages
+this.pattern.is.malformed.message=This pattern is malformed\n {0}
+this.pattern.is.unsupported.message=This pattern is unsupported
+incorrect.pattern.message=Incorrect pattern
+
+used.templates.history.dialog.title=Used Templates History
+existing.templates.dialog.title=Existing Templates
+selecttemplate.template.preview=Template preview:
+selecttemplate.template.label.please.select.template=<html><body><center>Please select template in the tree on the left.</center></body></html>
+
+# Replace Dialog specific titles/options
+structural.replace.title=Structural Replace
+shorten.fully.qualified.names.checkbox=Sh&orten fully qualified names
+format.according.to.style.checkbox=Fo&rmat according to style
+replacement.template.label=Replacement template:
+
+# Replace validation messages
+unsupported.replacement.pattern.message=Unsupported Replacement Pattern {0}
+malformed.replacement.pattern.message=Malformed Replacement Pattern {0}
+
+#replacement usage view specific
+preview.replacement.button=&Preview Replacement
+do.replace.all.button=Replace &All
+replace.selected.button=&Replace Selected
+replaceusageview.text={0} by {1}
+
+# predefined configuration categories
+expressions.category=expressions
+user.defined.category=user defined
+xml_html.category=xml/html
+generics.category=generics
+misc.category=miscellaneous
+metadata.category=comments, javadoc and metadata
+class.category=class-based
+operators.category=operators
+j2ee.category=j2ee
+interesting.category=interesting
+used.templates=Used templates:
+
+# predefined configuration names
+
+predefined.configuration.method.calls=method calls
+predefined.configuration.struts.1.1.actions=Struts 1.1 actions
+predefined.configuration.ejb.interface=ejb interface
+predefined.configuration.servlets=servlets
+predefined.configuration.unboxing.in.method.calls=unboxing in method calls
+predefined.configuration.boxing.in.method.calls=boxing in method calls
+predefined.configuration.unboxing.in.declarations=unboxing in declarations
+predefined.configuration.boxing.in.declarations=boxing in declarations
+predefined.configuration.filters=filters
+predefined.configuration.session.ejb=session ejb
+predefined.configuration.fields.variables.read=fields/variables read
+predefined.configuration.symbol=symbol
+predefined.configuration.inner.classes=inner classes
+predefined.configuration.]junit.test.cases=junit test cases
+predefined.configuration.ifs=if's
+predefined.configuration.anonymous.classes=anonymous classes
+predefined.configuration.javadoc.tags=javadoc tags
+predefined.configuration.all.methods.of.the.class.within.hierarchy=all methods of the class (within hierarchy)
+predefined.configuration.similar.methods.structure=similar methods structure
+predefined.configuration.class.implements.two.interfaces=class implementing two interfaces
+predefined.configuration.bean.info.classes=Bean info classes
+predefined.configuration.all.expressions.of.some.type=all expressions of some type
+predefined.configuration.variables.of.generic.types=variables of generic types
+predefined.configuration.comments=comments
+predefined.configuration.fields_variables.with.given.name.pattern.updated=fields/variables with given name pattern updated
+predefined.configuration.trys=try's
+predefined.configuration.block.dcls=block dcls
+predefined.configuration.methods.of.the.class=methods of the class
+predefined.configuration.instanceof=instanceof
+predefined.configuration.implementors.of.interface.within.hierarchy=implementors of interface (within hierarchy)
+predefined.configuration.generic.casts=generic casts
+predefined.configuration.field.selections=field selections
+predefined.configuration.fields.of.the.class=fields of the class
+predefined.configuration.array.access=array access
+predefined.configuration.usage.of.derived.type.in.cast=usage of derived type in cast
+predefined.configuration.annotated.methods=annotated methods
+predefined.configuration.not.annotated.methods=not annotated methods
+predefined.configuration.annotation.declarations=annotation declarations
+predefined.configuration.annotated.class=annotated class
+predefined.configuration.entity.ejb=entity ejb
+predefined.configuration.generic.methods=generic methods
+predefined.configuration.cloneable.implementations=Cloneable implementations
+predefined.configuration.xdoclet.metadata=XDoclet metadata
+predefined.configuration.type.var.substitutions.in.intanceof.with.generic.types=type var substitutions in intanceof with generic types
+predefined.configuration.singletons=singletons
+predefined.configuration.switches=switches
+predefined.configuration.foreaches=foreach loops
+predefined.configuration.interfaces=interfaces
+predefined.configuration.string.literals=string literals
+predefined.configuration.all.inner.classes.within.hierarchy=all inner classes (within hierarchy)
+predefined.configuration.direct.subclasses=direct subclasses
+predefined.configuration.javadoc.annotated.methods=javadoc annotated methods
+predefined.configuration.javadoc.annotated.fields=javadoc annotated fields
+predefined.configuration.assignments=assignments
+predefined.configuration.casts=casts
+predefined.configuration.serializable.classes.and.their.serialization.implementation=Serializable classes and their serialization implementation
+predefined.configuration.annotated.fields=annotated fields
+predefined.configuration.generic.classes=generic classes
+predefined.configuration.javadoc.annotated.class=javadoc annotated class
+predefined.configuration.constructors.of.the.class=constructors of the class
+predefined.configuration.typed.symbol=typed symbol
+predefined.configuration.all.fields.of.the.class=all fields of the class
+predefined.configuration.instance.fields.of.the.class=instance fields of the class
+predefined.configuration.packagelocal.fields.of.the.class=package local fields of the class
+predefined.configuration.classes=classes
+predefined.configuration.new.expressions=new expressions
+predefined.configuration.lambdas=lambdas
+
+# edit variable constraint dialog options
+invalid.regular.expression=Invalid regular expression
+invalid.occurence.count=Invalid occurrence count
+editvarcontraints.this.variable.is.target.of.the.search=This variable is target of the search
+editvarcontraints.unlimited=Unlimited
+editvarcontraints.maximum.count=Maximum count\:
+editvarcontraints.minimum.count=Minimum count\:
+editvarcontraints.apply.constraint.within.type.hierarchy=Apply constraint within type hierarchy
+editvarcontraints.invert.condition=Invert condition
+editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method=Text/regexp for formal argument type of the method\:
+editvarcontraints.text.regular.expression.for.java.expression.type=Text/regexp for java expression type\:
+editvarcontraints.value.is.written=Value is written
+editvarcontraints.value.is.read=Value is read
+editvarcontraints.whole.words.only=Whole words only
+editvarcontraints.text.regular.expression=Text/regexp\:
+editvarcontraints.edit.variables=Edit Variables
+
+# tooltip message fragment on ss variables
+no.constraints.specified.tooltip.message=no constraints specified
+script.option.text=Script text\:
+occurs.tooltip.message=occurs: {0}
+min.occurs.tooltip.message=min occurs: {0}, max occurs: {1}
+target.tooltip.message=target
+text.tooltip.message={0} like: {1}{2}
+exprtype.tooltip.message={0} like: {1}{2}
+not.tooltip.message=not
+within.hierarchy.tooltip.message=\ within hierarchy
+script.tooltip.message=script: {0}
+replacement.variable.is.not.defined.message=Replacement variable {0} is not defined.
+replacement.variable.is.not.valid=Replacement variable {0} has script code problem {1}
+replacement.template.is.not.expression.error.message=The search template is a well formed expression, but the replacement template is not an expression.
+replacement.template.expression.not.supported=Replacement of expression is not supported for {0}
+replacement.not.supported.for.filetype=Replacement is not supported for {0} file type
+search.template.is.not.expression.error.message=The search template is not an expression, but the replacement template is a well formed expression.
+create.template.action.name=Create Template
+remove.template.action.name=Remove Template
+
+modify.editor.content.command.name=modify editor content
+var.constraints.variables.border=Variables
+var.constraints.occurrences.count.border=Occurrences count
+var.constraints.script.constraints.border=Script constraints
+var.constraints.expression.constraints.border=Expression constraints
+var.constraints.text.constraints.border=Text constraints
+different.strategies.for.top.level.nodes.error.message=Different strategies for top level nodes
+option.is.not.recognized.error.message={0} condition is not recognized
+reg.exp.should.be.delimited.with.spaces.error.message=Reg exp should be delimited with spaces
+reg.exp.in.expr.type.should.be.delimited.with.spaces.error.message=Reg exp in expr type should be delimited with spaces
+reg.exp.in.formal.arg.type.should.be.delimited.with.spaces.error.message=Reg exp in formal arg type should be delimited with spaces
+no.reg.exp.specified.error.message=Missing regular expression
+script.should.be.delimited.with.spaces.error.message=Script should be delimited with spaces
+
+error.two.different.type.constraints=Two different type constraints
+error.incorrect.regexp.constraint=Incorrect reg exp constraint:{0} for {1}
+error.expected.character=Character expected after single quote
+error.overflow=Value overflow
+error.expected.brace1="Digit, '}' or ',' expected"
+error.expected.brace2="Digit or '}' expected"
+error.expected.condition=Condition expected after ''{0}''
+error.expected.condition.or.bracket=Condition or ']' expected
+invalid.modifier.type=Invalid modifier type {0}
+
+SSRInspection.replace.with=Replace with ''{0}''
+SSRInspection.family.name=Replace Structurally
+SSRInspection.display.name=Structural Search Inspection
+SSRInspection.add.search.template.button=Add Search template...
+SSRInspection.add.replace.template.button=Add Replace template...
+SSRInspection.selected.templates=Selected templates:
+status.message=Status:
+overwrite.message=Confirm overwrite configuration with the same name
+overwrite.title=Confirm Overwrite Saved Configuration
+ssr.will.not.find.anything=It does not match anything in selected scope
+predefined.configuration.class.static.blocks=static blocks in class
+predefined.configuration.class.instance.initialization.blocks=instance initialization blocks
+predefined.configuration.class.any.initialization.blocks=any class initialization block
+predefined.configuration.logging.without.if=logging without if
+predefined.configuration.class.with.parameterless.constructors=classes with parameterless constructors
+predefined.configuration.static.fields.without.final=static fields that are not final
+invalid.groovy.script=Invalid Groovy Script
+groovy.script.error=Groovy Script execution error: {0}
+template.problem=Structural Search Inspection problem in template ''{0}''
+problem=Structural Search problem: {0}
+complete.match.variable.name=Complete Match
+predefined.configuration.sample.method.invokation.with.constant.argument=sample method invocation with constant parameter
+predefined.configuration.interfaces.having.no.descendants=interface that is not implemented or extended
+action.StructuralSearchPlugin.StructuralSearchAction.text=Search S_tructurally...
+action.StructuralSearchPlugin.StructuralSearchAction.description=Structural Search
+action.StructuralSearchPlugin.StructuralReplaceAction.text=Repla_ce Structurally...
+action.StructuralSearchPlugin.StructuralReplaceAction.description=Structural Replace
+predefined.configuration.enums=enums
+regular.expression.help.label=Regular Expressions Help
+edit.groovy.script.constraint.title=Edit Groovy Script Constraint
diff --git a/plugins/structuralsearch/structuralsearch-java/src/META-INF/java.xml b/plugins/structuralsearch/structuralsearch-java/src/META-INF/java.xml
new file mode 100644
index 000000000000..56c3329f4867
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/META-INF/java.xml
@@ -0,0 +1,6 @@
+<idea-plugin url="http://www.jetbrains.com/idea">
+ <extensions defaultExtensionNs="com.intellij">
+ <structuralsearch.profile implementation="com.intellij.structuralsearch.JavaStructuralSearchProfile"/>
+ <structuralsearch.matchPredicateProvider implementation="com.intellij.structuralsearch.impl.matcher.JavaMatchPredicateProvider"/>
+ </extensions>
+</idea-plugin>
diff --git a/plugins/structuralsearch/structuralsearch-java/src/META-INF/plugin.xml b/plugins/structuralsearch/structuralsearch-java/src/META-INF/plugin.xml
new file mode 100644
index 000000000000..c95376c06f13
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/META-INF/plugin.xml
@@ -0,0 +1,48 @@
+<idea-plugin>
+ <name>Structural Search</name>
+ <description>Searching / replacing source code in terms of syntax (query / replace code by example :-).
+ </description>
+ <version>9.0</version>
+ <vendor>JetBrains</vendor>
+ <depends>com.intellij.modules.lang</depends>
+ <depends optional="true" config-file="java.xml">com.intellij.java-i18n</depends>
+
+ <extensionPoints>
+ <extensionPoint qualifiedName="com.intellij.structuralsearch.profile"
+ interface="com.intellij.structuralsearch.StructuralSearchProfile"/>
+ <extensionPoint qualifiedName="com.intellij.tokenindex.tokenizer" beanClass="com.intellij.lang.LanguageExtensionPoint"/>
+ <extensionPoint qualifiedName="com.intellij.structuralsearch.matchPredicateProvider"
+ interface="com.intellij.structuralsearch.impl.matcher.MatchPredicateProvider"/>
+ </extensionPoints>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+ <localInspection shortName="SSBasedInspection" bundle="messages.SSRBundle" key="SSRInspection.display.name" groupName="General"
+ enabledByDefault="false" level="WARNING"
+ implementationClass="com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspection"/>
+ <postStartupActivity
+ implementation="com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspectionCompiledPatternsCache"/>
+ <!--<fileBasedIndex implementation="com.intellij.tokenindex.TokenIndex"/>-->
+ <structuralsearch.profile implementation="com.intellij.structuralsearch.XmlStructuralSearchProfile"/>
+ </extensions>
+
+ <resource-bundle>messages.SSRBundle</resource-bundle>
+ <project-components>
+ <component>
+ <implementation-class>com.intellij.structuralsearch.plugin.StructuralSearchPlugin</implementation-class>
+ <option name="workspace" value="true"/>
+ </component>
+ </project-components>
+
+ <actions>
+ <group id="StructuralSearchActions">
+ <action id="StructuralSearchPlugin.StructuralSearchAction" class="com.intellij.structuralsearch.plugin.StructuralSearchAction">
+ <add-to-group group-id="FindMenuGroup" anchor="after" relative-to-action="ReplaceInPath"/>
+ </action>
+
+ <action id="StructuralSearchPlugin.StructuralReplaceAction" class="com.intellij.structuralsearch.plugin.StructuralReplaceAction">
+ <add-to-group group-id="FindMenuGroup" anchor="after" relative-to-action="StructuralSearchPlugin.StructuralSearchAction"/>
+ </action>
+ </group>
+ </actions>
+</idea-plugin>
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaPredefinedConfigurations.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaPredefinedConfigurations.java
new file mode 100644
index 000000000000..a82c941c0fa2
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaPredefinedConfigurations.java
@@ -0,0 +1,296 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+
+import static com.intellij.structuralsearch.PredefinedConfigurationUtil.createSearchTemplateInfo;
+import static com.intellij.structuralsearch.PredefinedConfigurationUtil.createSearchTemplateInfoSimple;
+
+/**
+* @author Bas Leijdekkers
+*/
+class JavaPredefinedConfigurations {
+
+ private static final String EXPRESSION_TYPE = SSRBundle.message("expressions.category");
+ private static final String INTERESTING_TYPE = SSRBundle.message("interesting.category");
+ private static final String J2EE_TYPE = SSRBundle.message("j2ee.category");
+ private static final String OPERATOR_TYPE = SSRBundle.message("operators.category");
+ private static final String CLASS_TYPE = SSRBundle.message("class.category");
+ private static final String METADATA_TYPE = SSRBundle.message("metadata.category");
+ private static final String MISC_TYPE = SSRBundle.message("misc.category");
+ private static final String GENERICS_TYPE = SSRBundle.message("generics.category");
+
+ public static Configuration[] createPredefinedTemplates() {
+ return new Configuration[] {
+ // Expression patterns
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.method.calls"), "'_Instance?.'MethodCall('_Parameter*)", EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.new.expressions"), "new 'Constructor('_Argument*)", EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.lambdas"), "('_Parameter) -> ", EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.field.selections"),"'_Instance?.'Field",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.array.access"),"'_Field['_Index]",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.assignments"),"'_Inst = '_Expr",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.casts"),"('_Type)'_Expr",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.instanceof"),"'_Expr instanceof '_Type",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.string.literals"),"\"'_String\"",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.all.expressions.of.some.type"),"'_Expression:[exprtype( SomeType )]",EXPRESSION_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.sample.method.invokation.with.constant.argument"),"Integer.parseInt('_a:[script( \"com.intellij.psi.util.PsiUtil.isConstantExpression(__context__)\" )])",EXPRESSION_TYPE),
+
+ // Operators
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.block.dcls"),"{\n '_Type+ 'Var+ = '_Init*;\n '_BlockStatements*;\n}",OPERATOR_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.trys"),"try {\n '_TryStatement+;\n} catch('_ExceptionType '_ExceptionDcl) {\n '_CatchStatement*;\n}",OPERATOR_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.ifs"),"if ('_Condition) {\n '_ThenStatement*;\n} else {\n '_ElseStatement*;\n}",OPERATOR_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.switches"),"switch('_Condition) {\n '_Statement*;\n}",OPERATOR_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.foreaches"), "for ('_Type '_Variable : '_Expression) {\n '_Statement*;\n}", OPERATOR_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.logging.without.if"),"LOG.debug('_params*:[!within( \"if('_a) { '_st*; }\" )]);",OPERATOR_TYPE),
+
+ // Class based
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.methods.of.the.class"),
+ "class '_Class { \n '_ReturnType+ 'MethodName+('_ParameterType* '_Parameter*);\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.fields.of.the.class"),
+ "class '_Class { \n '_FieldType+ 'FieldName+ = '_Init*;\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.all.methods.of.the.class.within.hierarchy"),
+ "class '_ { \n '_ReturnType+ 'MethodName+:* ('_ParameterType* '_Parameter*);\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.all.fields.of.the.class"),
+ "class '_Class { \n '_FieldType+ 'FieldName+:* = '_Init*;\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.instance.fields.of.the.class"),
+ "class '_Class { \n @Modifier(\"Instance\") '_FieldType+ 'FieldName+ = '_Init*;\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.packagelocal.fields.of.the.class"),
+ "class '_Class { \n @Modifier(\"packageLocal\") '_FieldType+ 'FieldName+ = '_Init*;\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.constructors.of.the.class"),
+ "class 'Class {\n 'Class+('_ParameterType* '_ParameterName*) {\n '_Statement*;\n }\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.classes"),
+ "class 'Class {}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.direct.subclasses"),
+ "class 'Class extends '_Parent {}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.implementors.of.interface.within.hierarchy"),
+ "class 'Class implements 'Interface:* {}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.interfaces"),
+ "interface 'Interface {}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.inner.classes"),
+ "class '_ {\n class 'InnerClass+ {}\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.all.inner.classes.within.hierarchy"),
+ "class '_Class {\n class 'InnerClass+:* {}\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.anonymous.classes"),
+ "new 'AnonymousClass() {}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.class.implements.two.interfaces"),
+ "class 'A implements '_Interface1:[regex( *java\\.lang\\.Cloneable )], '_Interface2:*java\\.io\\.Serializable {\n" +"}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.class.static.blocks"),
+ "class '_A {\n static {\n 'Statement*;\n }\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.class.instance.initialization.blocks"),
+ "class '_A {\n @Modifier(\"Instance\") {\n 'Statement*;\n }\n}",
+ CLASS_TYPE
+ ),
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.class.any.initialization.blocks"),
+ "class '_A {\n {\n 'Statement*;\n }\n}",
+ CLASS_TYPE
+ ),
+
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.enums"),
+ "enum 'Enum {}",
+ CLASS_TYPE
+ ),
+
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.class.with.parameterless.constructors"),
+ "class 'Class {\n '_Method{0,0}:[ script( \"__context__.constructor\" ) ]('_ParamType+ '_ParameterName+);\n}",
+ CLASS_TYPE
+ ),
+
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.static.fields.without.final"),
+ "class '_Class {\n static '_Type 'Variable+:[ script( \"!__context__.hasModifierProperty(\"final\")\" ) ] = '_Init?;\n}",
+ CLASS_TYPE
+ ),
+
+ createSearchTemplateInfo(
+ SSRBundle.message("predefined.configuration.interfaces.having.no.descendants"),
+ "interface 'A:[script( \"com.intellij.psi.search.searches.ClassInheritorsSearch.search(__context__).findFirst() == null\" )] {}",
+ CLASS_TYPE
+ ),
+
+ // Generics
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.classes"),"class 'GenericClass<'_TypeParameter+> {} ", GENERICS_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.methods"),"class '_Class {\n <'_TypeParameter+> '_Type+ 'Method+('_ParameterType* '_ParameterDcl*);\n}", GENERICS_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.typed.symbol"),"'Symbol <'_GenericArgument+>", GENERICS_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.casts"),"( '_Type <'_GenericArgument+> ) '_Expr", GENERICS_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.type.var.substitutions.in.intanceof.with.generic.types"),"'_Expr instanceof '_Type <'Substitutions+> ", GENERICS_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.variables.of.generic.types"),"'_Type <'_GenericArgument+> 'Var = 'Init?;", GENERICS_TYPE),
+
+ // Add comments and metadata
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.comments"),"/* 'CommentContent */", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.javadoc.annotated.class"),"/** @'_Tag+ '_TagValue* */\nclass '_Class {\n}", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.javadoc.annotated.methods"),"class '_Class {\n /** @'_Tag+ '_TagValue* */\n '_Type+ 'Method+('_ParameterType* '_ParameterDcl*);\n}", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.javadoc.annotated.fields"),"class '_Class {\n /** @'_Tag+ '_TagValue* */\n '_Type+ 'Field+ = '_Init*;\n}", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.javadoc.tags"),"/** @'Tag+ '_TagValue* */", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.xdoclet.metadata"),"/** @'Tag \n '_Property+\n*/", METADATA_TYPE),
+
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.annotated.class"),
+ "@'_Annotation( )\n" +
+ "class 'Class {}", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.annotated.fields"),
+ "class '_Class {\n" +
+ " @'_Annotation+( )\n" +
+ " '_FieldType+ 'FieldName+ = '_FieldInitial*;\n" +
+ "}", METADATA_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.annotated.methods"),
+ "class '_Class {\n" +
+ " @'_Annotation+( )\n" +
+ " '_MethodType+ 'MethodName+('_ParameterType* '_ParameterName*);\n" +
+ "}", METADATA_TYPE),
+
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.not.annotated.methods"),
+ "class '_Class {\n" +
+ " @'_Annotation{0,0}\n" +
+ " '_MethodType+ 'MethodName+('_ParameterType* '_ParameterName*);\n" +
+ "}", METADATA_TYPE),
+
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.annotation.declarations"),
+ "@interface 'Interface {}", METADATA_TYPE),
+
+ // J2EE templates
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.struts.1.1.actions"),"public class 'StrutsActionClass extends '_ParentClass*:Action {\n" +
+ " public ActionForward 'AnActionMethod:*execute (ActionMapping '_action,\n" +
+ " ActionForm '_form,\n" +
+ " HttpServletRequest '_request,\n" +
+ " HttpServletResponse '_response);\n" +
+ "}",J2EE_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.entity.ejb"),"class 'EntityBean implements EntityBean {\n" +
+ " EntityContext '_Context?;\n\n" +
+ " public void setEntityContext(EntityContext '_Context2);\n\n" +
+ " public '_RetType ejbCreate('_CreateType* '_CreateDcl*);\n" +
+ " public void ejbActivate();\n\n" +
+ " public void ejbLoad();\n\n" +
+ " public void ejbPassivate();\n\n" +
+ " public void ejbRemove();\n\n" +
+ " public void ejbStore();\n" +
+ "}", J2EE_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.session.ejb"),"class 'SessionBean implements SessionBean {\n" +
+ " SessionContext '_Context?;\n\n" +
+ " public void '_setSessionContext(SessionContext '_Context2);\n\n" +
+ " public '_RetType ejbCreate('_CreateParameterType* '_CreateParameterDcl*);\n" +
+ " public void ejbActivate();\n\n" +
+ " public void ejbPassivate();\n\n" +
+ " public void ejbRemove();\n" +
+ "}", J2EE_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.ejb.interface"),"interface 'EjbInterface extends EJBObject {\n" +
+ " 'Type+ 'Method+('ParamType* 'ParamName*);\n" +
+ "}", J2EE_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.servlets"),"public class 'Servlet extends '_ParentClass:*HttpServlet {\n" +
+ " public void '_InitServletMethod?:init ();\n" +
+ " public void '_DestroyServletMethod?:destroy ();\n" +
+ " void '_ServiceMethod?:*service (HttpServletRequest '_request, HttpServletResponse '_response);\n" +
+ " void '_SpecificServiceMethod*:do.* (HttpServletRequest '_request2, HttpServletResponse '_response2); \n" +
+ "}", J2EE_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.filters"),"public class 'Filter implements Filter {\n" +
+ " public void '_DestroyFilterMethod?:*destroy ();\n" +
+ " public void '_InitFilterMethod?:*init ();\n" +
+ " public void '_FilteringMethod:*doFilter (ServletRequest '_request,\n" +
+ " ServletResponse '_response,FilterChain '_chain);\n" +
+ "}", J2EE_TYPE),
+
+ // Misc types
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.serializable.classes.and.their.serialization.implementation"),
+ "class '_Class implements '_Serializable:*Serializable {\n" +
+ " static final long 'VersionField?:serialVersionUID = '_VersionFieldInit?;\n" +
+ " private static final ObjectStreamField[] '_persistentFields?:serialPersistentFields = '_persistentFieldInitial?; \n" +
+ " private void 'SerializationWriteHandler?:writeObject (ObjectOutputStream '_stream) throws IOException;\n" +
+ " private void 'SerializationReadHandler?:readObject (ObjectInputStream '_stream2) throws IOException, ClassNotFoundException;\n" +
+ " Object 'SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;\n" +
+ " Object 'SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;\n" +
+ "}",MISC_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.cloneable.implementations"),
+ "class '_Class implements '_Interface:*Cloneable {\n" +
+ " Object 'CloningMethod:*clone ();\n" +
+ "}",MISC_TYPE),
+ createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.]junit.test.cases"),"public class 'TestCase extends 'TestCaseClazz:*TestCase {\n" +
+ " public void '_testMethod+:test.* ();\n" +
+ "}", MISC_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.singletons"),"class 'Class {\n" +
+ " private 'Class('_ParameterType* '_ParameterDcl*) {\n" +
+ " '_ConstructorStatement*;\n" +
+ " }\n"+
+ " private static '_Class:* '_Instance;\n" +
+ " static '_Class:* '_GetInstance() {\n" +
+ " '_SomeStatement*;\n" +
+ " return '_Instance;\n" +
+ " }\n"+
+ "}",MISC_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.similar.methods.structure"),"class '_Class {\n" +
+ " '_RetType 'Method+('_ParameterType* '_Parameter) throws 'ExceptionType {\n" +
+ " try {\n" +
+ " '_OtherStatements+;\n" +
+ " } catch('_SomeException '_ExceptionDcl) {\n" +
+ " '_CatchStatement*;\n" +
+ " throw new 'ExceptionType('_ExceptionConstructorArgs*);\n" +
+ " }\n" +
+ " }\n" +
+ "}",MISC_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.bean.info.classes"),"class 'A implements '_:*java\\.beans\\.BeanInfo {\n" +
+ "}",MISC_TYPE),
+
+ // interesting types
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.symbol"),"'Symbol",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields.variables.read"),"'Symbol:[read]",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields_variables.with.given.name.pattern.updated"),"'Symbol:[regex( name ) && write]",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.usage.of.derived.type.in.cast"),"('CastType:*Base ) 'Expr",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[formal( int|boolean|long|char|short|byte )]",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[formal( Integer|Boolean|Long|Character|Short|Byte )]",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.method.calls"),"'_Instance?.'Call('_BeforeParam*,'_Param:[ exprtype( int|boolean|long|char|short|byte ) && formal( Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
+ createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.method.calls"), "'_Instance?.'Call('_BeforeParam*,'_Param:[ formal( int|boolean|long|char|short|byte ) && exprtype( Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
+ //createSearchTemplateInfo("methods called","'_?.'_:[ref('Method)] ('_*)", INTERESTING_TYPE),
+ //createSearchTemplateInfo("fields selected","'_?.'_:[ref('Field)] ", INTERESTING_TYPE),
+ //createSearchTemplateInfo("symbols used","'_:[ref('Symbol)] ", INTERESTING_TYPE),
+ //createSearchTemplateInfo("types used","'_:[ref('Type)] '_;", INTERESTING_TYPE),
+ };
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java
new file mode 100644
index 000000000000..36b8fff26afb
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java
@@ -0,0 +1,500 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.xml.XmlText;
+import com.intellij.structuralsearch.impl.matcher.JavaMatchingVisitor;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import com.intellij.structuralsearch.impl.matcher.PatternTreeContext;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplacementInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacerUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class JavaReplaceHandler extends StructuralReplaceHandler {
+ private final ReplacementContext myContext;
+ private PsiCodeBlock codeBlock;
+
+ public JavaReplaceHandler(ReplacementContext context) {
+ this.myContext = context;
+ }
+
+ private PsiCodeBlock getCodeBlock() throws IncorrectOperationException {
+ if (codeBlock == null) {
+ PsiCodeBlock search;
+ search = (PsiCodeBlock)MatcherImplUtil.createTreeFromText(
+ myContext.getOptions().getMatchOptions().getSearchPattern(),
+ PatternTreeContext.Block,
+ myContext.getOptions().getMatchOptions().getFileType(),
+ myContext.getProject()
+ )[0].getParent();
+
+ codeBlock = search;
+ }
+ return codeBlock;
+ }
+
+ private static PsiElement findRealSubstitutionElement(PsiElement el) {
+ if (el instanceof PsiIdentifier) {
+ // matches are tokens, identifiers, etc
+ el = el.getParent();
+ }
+
+ if (el instanceof PsiReferenceExpression &&
+ el.getParent() instanceof PsiMethodCallExpression
+ ) {
+ // method
+ el = el.getParent();
+ }
+
+ if (el instanceof PsiDeclarationStatement && ((PsiDeclarationStatement)el).getDeclaredElements()[0] instanceof PsiClass) {
+ el = ((PsiDeclarationStatement)el).getDeclaredElements()[0];
+ }
+ return el;
+ }
+
+ private static boolean isListContext(PsiElement el) {
+ boolean listContext = false;
+ final PsiElement parent = el.getParent();
+
+ if (parent instanceof PsiParameterList ||
+ parent instanceof PsiExpressionList ||
+ parent instanceof PsiCodeBlock ||
+ parent instanceof PsiClass ||
+ parent instanceof XmlText ||
+ (parent instanceof PsiIfStatement &&
+ (((PsiIfStatement)parent).getThenBranch() == el ||
+ ((PsiIfStatement)parent).getElseBranch() == el
+ )
+ ) ||
+ (parent instanceof PsiLoopStatement &&
+ ((PsiLoopStatement)parent).getBody() == el
+ )
+ ) {
+ listContext = true;
+ }
+
+ return listContext;
+ }
+
+ @Nullable
+ private PsiNamedElement getSymbolReplacementTarget(final PsiElement el)
+ throws IncorrectOperationException {
+ if (myContext.getOptions().getMatchOptions().getFileType() != StdFileTypes.JAVA) return null; //?
+ final PsiStatement[] searchStatements = getCodeBlock().getStatements();
+ if (searchStatements.length > 0 &&
+ searchStatements[0] instanceof PsiExpressionStatement) {
+ final PsiExpression expression = ((PsiExpressionStatement)searchStatements[0]).getExpression();
+
+ if (expression instanceof PsiReferenceExpression &&
+ ((PsiReferenceExpression)expression).getQualifierExpression() == null
+ ) {
+ // looks like symbol replacements, namely replace AAA by BBB, so lets do the best
+ if (el instanceof PsiNamedElement) {
+ return (PsiNamedElement)el;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static PsiElement getMatchExpr(PsiElement replacement, PsiElement elementToReplace) {
+ if (replacement instanceof PsiExpressionStatement &&
+ !(replacement.getLastChild() instanceof PsiJavaToken) &&
+ !(replacement.getLastChild() instanceof PsiComment)
+ ) {
+ // replacement is expression (and pattern should be so)
+ // assert ...
+ replacement = ((PsiExpressionStatement)replacement).getExpression();
+ }
+ else if (replacement instanceof PsiDeclarationStatement &&
+ ((PsiDeclarationStatement)replacement).getDeclaredElements().length == 1
+ ) {
+ return ((PsiDeclarationStatement)replacement).getDeclaredElements()[0];
+ }
+ else if (replacement instanceof PsiBlockStatement &&
+ elementToReplace instanceof PsiCodeBlock
+ ) {
+ return ((PsiBlockStatement)replacement).getCodeBlock();
+ }
+
+ return replacement;
+ }
+
+ private boolean isSymbolReplacement(final PsiElement el) throws IncorrectOperationException {
+ return getSymbolReplacementTarget(el) != null;
+ }
+
+ @SuppressWarnings({"unchecked", "ConstantConditions"})
+ private void handleModifierList(final PsiElement el, final PsiElement replacement) throws IncorrectOperationException {
+ // We want to copy all comments, including doc comments and modifier lists
+ // that are present in matched nodes but not present in search/replace
+
+ Map<String, String> newNameToSearchPatternNameMap = myContext.getNewName2PatternNameMap();
+
+ ModifierListOwnerCollector collector = new ModifierListOwnerCollector();
+ el.accept(collector);
+ Map<String, PsiNamedElement> originalNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
+ collector.namedElements.clear();
+
+ replacement.accept(collector);
+ Map<String, PsiNamedElement> replacedNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
+ collector.namedElements.clear();
+
+ if (originalNamedElements.size() == 0 && replacedNamedElements.size() == 0) {
+ Replacer.handleComments(el, replacement, myContext);
+ return;
+ }
+
+ final PsiStatement[] statements = getCodeBlock().getStatements();
+ if (statements.length > 0) {
+ statements[0].getParent().accept(collector);
+ }
+
+ Map<String, PsiNamedElement> searchedNamedElements = (Map<String, PsiNamedElement>)collector.namedElements.clone();
+ collector.namedElements.clear();
+
+ for (String name : originalNamedElements.keySet()) {
+ PsiNamedElement originalNamedElement = originalNamedElements.get(name);
+ PsiNamedElement replacementNamedElement = replacedNamedElements.get(name);
+ String key = newNameToSearchPatternNameMap.get(name);
+ if (key == null) key = name;
+ PsiNamedElement searchNamedElement = searchedNamedElements.get(key);
+
+ if (replacementNamedElement == null && originalNamedElements.size() == 1 && replacedNamedElements.size() == 1) {
+ replacementNamedElement = replacedNamedElements.entrySet().iterator().next().getValue();
+ }
+
+ PsiElement comment = null;
+
+ if (originalNamedElement instanceof PsiDocCommentOwner) {
+ comment = ((PsiDocCommentOwner)originalNamedElement).getDocComment();
+ if (comment == null) {
+ PsiElement prevElement = originalNamedElement.getPrevSibling();
+ if (prevElement instanceof PsiWhiteSpace) {
+ prevElement = prevElement.getPrevSibling();
+ }
+ if (prevElement instanceof PsiComment) {
+ comment = prevElement;
+ }
+ }
+ }
+
+ if (replacementNamedElement != null && searchNamedElement != null) {
+ Replacer.handleComments(originalNamedElement, replacementNamedElement, myContext);
+ }
+
+ if (comment != null && replacementNamedElement instanceof PsiDocCommentOwner &&
+ !(replacementNamedElement.getFirstChild() instanceof PsiDocComment)
+ ) {
+ final PsiElement nextSibling = comment.getNextSibling();
+ PsiElement prevSibling = comment.getPrevSibling();
+ replacementNamedElement.addRangeBefore(
+ prevSibling instanceof PsiWhiteSpace ? prevSibling : comment,
+ nextSibling instanceof PsiWhiteSpace ? nextSibling : comment,
+ replacementNamedElement.getFirstChild()
+ );
+ }
+
+ if (originalNamedElement instanceof PsiModifierListOwner &&
+ replacementNamedElement instanceof PsiModifierListOwner
+ ) {
+ PsiModifierList modifierList = ((PsiModifierListOwner)originalNamedElements.get(name)).getModifierList();
+
+ if (searchNamedElement instanceof PsiModifierListOwner) {
+ PsiModifierList modifierListOfSearchedElement = ((PsiModifierListOwner)searchNamedElement).getModifierList();
+ final PsiModifierListOwner modifierListOwner = ((PsiModifierListOwner)replacementNamedElement);
+ PsiModifierList modifierListOfReplacement = modifierListOwner.getModifierList();
+
+ if (modifierListOfSearchedElement.getTextLength() == 0 &&
+ modifierListOfReplacement.getTextLength() == 0 &&
+ modifierList.getTextLength() > 0
+ ) {
+ PsiElement space = modifierList.getNextSibling();
+ if (!(space instanceof PsiWhiteSpace)) {
+ space = createWhiteSpace(space);
+ }
+
+ modifierListOfReplacement.replace(modifierList);
+ // copy space after modifier list
+ if (space instanceof PsiWhiteSpace) {
+ modifierListOwner.addRangeAfter(space, space, modifierListOwner.getModifierList());
+ }
+ } else if (modifierListOfSearchedElement.getTextLength() == 0 && modifierList.getTextLength() > 0) {
+ modifierListOfReplacement.addRange(modifierList.getFirstChild(), modifierList.getLastChild());
+ }
+ }
+ }
+ }
+ }
+
+ private PsiElement handleSymbolReplacemenent(PsiElement replacement, final PsiElement el) throws IncorrectOperationException {
+ PsiNamedElement nameElement = getSymbolReplacementTarget(el);
+ if (nameElement != null) {
+ PsiElement oldReplacement = replacement;
+ replacement = el.copy();
+ ((PsiNamedElement)replacement).setName(oldReplacement.getText());
+ }
+
+ return replacement;
+ }
+
+ public void replace(final ReplacementInfo info, ReplaceOptions options) {
+ PsiElement elementToReplace = info.getMatch(0);
+ PsiElement elementParent = elementToReplace.getParent();
+ String replacementToMake = info.getReplacement();
+ Project project = myContext.getProject();
+ PsiElement el = findRealSubstitutionElement(elementToReplace);
+ boolean listContext = isListContext(el);
+
+ if (el instanceof PsiAnnotation && !StringUtil.startsWithChar(replacementToMake, '@')) {
+ replacementToMake = "@" + replacementToMake;
+ }
+
+ PsiElement[] statements = ReplacerUtil
+ .createTreeForReplacement(replacementToMake, el instanceof PsiMember && !isSymbolReplacement(el) ?
+ PatternTreeContext.Class :
+ PatternTreeContext.Block, myContext);
+
+ if (listContext) {
+ if (statements.length > 1) {
+ elementParent.addRangeBefore(statements[0], statements[statements.length - 1], elementToReplace);
+ }
+ else if (statements.length == 1) {
+ PsiElement replacement = getMatchExpr(statements[0], elementToReplace);
+
+ handleModifierList(el, replacement);
+ replacement = handleSymbolReplacemenent(replacement, el);
+
+ if (replacement instanceof PsiTryStatement) {
+ final List<PsiCatchSection> unmatchedCatchSections = el.getUserData(JavaMatchingVisitor.UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY);
+ final PsiCatchSection[] catches = ((PsiTryStatement)replacement).getCatchSections();
+
+ if (unmatchedCatchSections != null) {
+ for (int i = unmatchedCatchSections.size() - 1; i >= 0; --i) {
+ final PsiParameter parameter = unmatchedCatchSections.get(i).getParameter();
+ final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
+ final PsiCatchSection catchSection = elementFactory.createCatchSection(parameter.getType(), parameter.getName(), null);
+
+ catchSection.getCatchBlock().replace(
+ unmatchedCatchSections.get(i).getCatchBlock()
+ );
+ replacement.addAfter(
+ catchSection, catches[catches.length - 1]
+ );
+ replacement.addBefore(createWhiteSpace(replacement), replacement.getLastChild());
+ }
+ }
+ }
+
+ try {
+ final PsiElement inserted = elementParent.addBefore(replacement, elementToReplace);
+
+ if (replacement instanceof PsiComment &&
+ (elementParent instanceof PsiIfStatement ||
+ elementParent instanceof PsiLoopStatement
+ )
+ ) {
+ elementParent.addAfter(createSemicolon(replacement), inserted);
+ }
+ }
+ catch (IncorrectOperationException e) {
+ elementToReplace.replace(replacement);
+ }
+ }
+ }
+ else if (statements.length > 0) {
+ PsiElement replacement = ReplacerUtil.copySpacesAndCommentsBefore(elementToReplace, statements, replacementToMake, elementParent);
+
+ replacement = getMatchExpr(replacement, elementToReplace);
+
+ if (replacement instanceof PsiStatement &&
+ !(replacement.getLastChild() instanceof PsiJavaToken) &&
+ !(replacement.getLastChild() instanceof PsiComment)
+ ) {
+ // assert w/o ;
+ final PsiElement prevLastChildInParent = replacement.getLastChild().getPrevSibling();
+
+ if (prevLastChildInParent != null) {
+ elementParent.addRangeBefore(replacement.getFirstChild(), prevLastChildInParent, el);
+ }
+ else {
+ elementParent.addBefore(replacement.getFirstChild(), el);
+ }
+
+ el.getNode().getTreeParent().removeChild(el.getNode());
+ }
+ else {
+ // preserve comments
+ handleModifierList(el, replacement);
+
+ if (replacement instanceof PsiClass) {
+ // modifier list
+ final PsiStatement[] searchStatements = getCodeBlock().getStatements();
+ if (searchStatements.length > 0 &&
+ searchStatements[0] instanceof PsiDeclarationStatement &&
+ ((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0] instanceof PsiClass
+ ) {
+ final PsiClass replaceClazz = (PsiClass)replacement;
+ final PsiClass queryClazz = (PsiClass)((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0];
+ final PsiClass clazz = (PsiClass)el;
+
+ if (replaceClazz.getExtendsList().getTextLength() == 0 &&
+ queryClazz.getExtendsList().getTextLength() == 0 &&
+ clazz.getExtendsList().getTextLength() != 0
+ ) {
+ replaceClazz.addBefore(clazz.getExtendsList().getPrevSibling(), replaceClazz.getExtendsList()); // whitespace
+ replaceClazz.getExtendsList().addRange(
+ clazz.getExtendsList().getFirstChild(), clazz.getExtendsList().getLastChild()
+ );
+ }
+
+ if (replaceClazz.getImplementsList().getTextLength() == 0 &&
+ queryClazz.getImplementsList().getTextLength() == 0 &&
+ clazz.getImplementsList().getTextLength() != 0
+ ) {
+ replaceClazz.addBefore(clazz.getImplementsList().getPrevSibling(), replaceClazz.getImplementsList()); // whitespace
+ replaceClazz.getImplementsList().addRange(
+ clazz.getImplementsList().getFirstChild(),
+ clazz.getImplementsList().getLastChild()
+ );
+ }
+
+ if (replaceClazz.getTypeParameterList().getTextLength() == 0 &&
+ queryClazz.getTypeParameterList().getTextLength() == 0 &&
+ clazz.getTypeParameterList().getTextLength() != 0
+ ) {
+ // skip < and >
+ replaceClazz.getTypeParameterList().replace(
+ clazz.getTypeParameterList()
+ );
+ }
+ }
+ }
+
+ replacement = handleSymbolReplacemenent(replacement, el);
+
+ el.replace(replacement);
+ }
+ }
+ else {
+ final PsiElement nextSibling = el.getNextSibling();
+ el.delete();
+ if (nextSibling instanceof PsiWhiteSpace && nextSibling.isValid()) {
+ nextSibling.delete();
+ }
+ }
+
+ if (listContext) {
+ final int matchSize = info.getMatchesCount();
+
+ for (int i = 0; i < matchSize; ++i) {
+ PsiElement matchElement = info.getMatch(i);
+ PsiElement element = findRealSubstitutionElement(matchElement);
+
+ if (element == null) continue;
+ PsiElement firstToDelete = element;
+ PsiElement lastToDelete = element;
+ PsiElement prevSibling = element.getPrevSibling();
+ PsiElement nextSibling = element.getNextSibling();
+
+ if (prevSibling instanceof PsiWhiteSpace) {
+ firstToDelete = prevSibling;
+ prevSibling = prevSibling != null ? prevSibling.getPrevSibling() : null;
+ }
+ else if (prevSibling == null && nextSibling instanceof PsiWhiteSpace) {
+ lastToDelete = nextSibling;
+ }
+
+ if (nextSibling instanceof XmlText && i + 1 < matchSize) {
+ final PsiElement next = info.getMatch(i + 1);
+ if (next != null && next == nextSibling.getNextSibling()) {
+ lastToDelete = nextSibling;
+ }
+ }
+
+ if (element instanceof PsiExpression) {
+ final PsiElement parent = element.getParent().getParent();
+ if ((parent instanceof PsiCall ||
+ parent instanceof PsiAnonymousClass
+ ) &&
+ prevSibling instanceof PsiJavaToken &&
+ ((PsiJavaToken)prevSibling).getTokenType() == JavaTokenType.COMMA
+ ) {
+ firstToDelete = prevSibling;
+ }
+ }
+ else if (element instanceof PsiParameter &&
+ prevSibling instanceof PsiJavaToken &&
+ ((PsiJavaToken)prevSibling).getTokenType() == JavaTokenType.COMMA
+ ) {
+ firstToDelete = prevSibling;
+ }
+
+ element.getParent().deleteChildRange(firstToDelete, lastToDelete);
+ }
+ }
+
+ if (options.isToShortenFQN() && elementParent.isValid()) {
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(elementParent, 0, elementParent.getTextLength());
+ }
+ }
+
+ @Nullable
+ private static PsiElement createSemicolon(final PsiElement space) throws IncorrectOperationException {
+ final PsiStatement text = JavaPsiFacade.getInstance(space.getProject()).getElementFactory().createStatementFromText(";", null);
+ return text.getFirstChild();
+ }
+
+ private static PsiElement createWhiteSpace(final PsiElement space) throws IncorrectOperationException {
+ return PsiParserFacade.SERVICE.getInstance(space.getProject()).createWhiteSpaceFromText(" ");
+ }
+
+ private static class ModifierListOwnerCollector extends JavaRecursiveElementWalkingVisitor {
+ HashMap<String, PsiNamedElement> namedElements = new HashMap<String, PsiNamedElement>(1);
+
+ @Override
+ public void visitClass(PsiClass aClass) {
+ if (aClass instanceof PsiAnonymousClass) return;
+ handleNamedElement(aClass);
+ }
+
+ private void handleNamedElement(final PsiNamedElement named) {
+ String name = named.getName();
+
+ assert name != null;
+
+ if (StructuralSearchUtil.isTypedVariable(name)) {
+ name = name.substring(1, name.length() - 1);
+ }
+
+ if (!namedElements.containsKey(name)) namedElements.put(name, named);
+ named.acceptChildren(this);
+ }
+
+ @Override
+ public void visitVariable(PsiVariable var) {
+ handleNamedElement(var);
+ }
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ handleNamedElement(method);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java
new file mode 100644
index 000000000000..c738b55b85ae
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java
@@ -0,0 +1,675 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.codeInsight.template.JavaCodeContextType;
+import com.intellij.codeInsight.template.TemplateContextType;
+import com.intellij.codeInsight.template.TemplateManager;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.structuralsearch.impl.matcher.*;
+import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.compiler.JavaCompilingVisitor;
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+import com.intellij.structuralsearch.impl.matcher.filters.JavaLexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.ParameterInfo;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementBuilder;
+import com.intellij.structuralsearch.plugin.replace.impl.ReplacementContext;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchContext;
+import com.intellij.structuralsearch.plugin.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class JavaStructuralSearchProfile extends StructuralSearchProfile {
+ private JavaLexicalNodesFilter myJavaLexicalNodesFilter;
+
+ public String getText(PsiElement match, int start,int end) {
+ if (match instanceof PsiIdentifier) {
+ PsiElement parent = match.getParent();
+ if (parent instanceof PsiJavaCodeReferenceElement && !(parent instanceof PsiExpression)) {
+ match = parent; // care about generic
+ }
+ }
+ final String matchText = match.getText();
+ if (start==0 && end==-1) return matchText;
+ return matchText.substring(start,end == -1? matchText.length():end);
+ }
+
+ public Class getElementContextByPsi(PsiElement element) {
+ if (element instanceof PsiIdentifier) {
+ element = element.getParent();
+ }
+
+ if (element instanceof PsiMember) {
+ return PsiMember.class;
+ } else {
+ return PsiExpression.class;
+ }
+ }
+
+ public String getTypedVarString(final PsiElement element) {
+ String text;
+
+ if (element instanceof PsiNamedElement) {
+ text = ((PsiNamedElement)element).getName();
+ }
+ else if (element instanceof PsiAnnotation) {
+ PsiJavaCodeReferenceElement referenceElement = ((PsiAnnotation)element).getNameReferenceElement();
+ text = referenceElement == null ? null : referenceElement.getQualifiedName();
+ }
+ else if (element instanceof PsiNameValuePair) {
+ text = ((PsiNameValuePair)element).getName();
+ }
+ else {
+ text = element.getText();
+ if (StringUtil.startsWithChar(text, '@')) {
+ text = text.substring(1);
+ }
+ if (StringUtil.endsWithChar(text, ';')) text = text.substring(0, text.length() - 1);
+ else if (element instanceof PsiExpressionStatement) {
+ int i = text.indexOf(';');
+ if (i != -1) text = text.substring(0, i);
+ }
+ }
+
+ if (text==null) text = element.getText();
+
+ return text;
+ }
+
+ @Override
+ public String getMeaningfulText(PsiElement element) {
+ if (element instanceof PsiReferenceExpression &&
+ ((PsiReferenceExpression)element).getQualifierExpression() != null) {
+ final PsiElement resolve = ((PsiReferenceExpression)element).resolve();
+ if (resolve instanceof PsiClass) return element.getText();
+
+ final PsiElement referencedElement = ((PsiReferenceExpression)element).getReferenceNameElement();
+ String text = referencedElement != null ? referencedElement.getText() : "";
+
+ if (resolve == null && text.length() > 0 && Character.isUpperCase(text.charAt(0))) {
+ return element.getText();
+ }
+ return text;
+ }
+ return super.getMeaningfulText(element);
+ }
+
+ @Override
+ public PsiElement updateCurrentNode(PsiElement targetNode) {
+ if (targetNode instanceof PsiCodeBlock && ((PsiCodeBlock)targetNode).getStatements().length == 1) {
+ PsiElement targetNodeParent = targetNode.getParent();
+ if (targetNodeParent instanceof PsiBlockStatement) {
+ targetNodeParent = targetNodeParent.getParent();
+ }
+
+ if (targetNodeParent instanceof PsiIfStatement || targetNodeParent instanceof PsiLoopStatement) {
+ targetNode = targetNodeParent;
+ }
+ }
+ return targetNode;
+ }
+
+ @Override
+ public PsiElement extendMatchedByDownUp(PsiElement targetNode) {
+ if (targetNode instanceof PsiIdentifier) {
+ targetNode = targetNode.getParent();
+ final PsiElement parent = targetNode.getParent();
+ if (parent instanceof PsiTypeElement || parent instanceof PsiStatement) targetNode = parent;
+ }
+ return targetNode;
+ }
+
+ @Override
+ public PsiElement extendMatchOnePsiFile(PsiElement file) {
+ if (file instanceof PsiIdentifier) {
+ // Searching in previous results
+ file = file.getParent();
+ }
+ return file;
+ }
+
+ public void compile(PsiElement[] elements, @NotNull GlobalCompilingVisitor globalVisitor) {
+ elements[0].getParent().accept(new JavaCompilingVisitor(globalVisitor));
+ }
+
+ @NotNull
+ public PsiElementVisitor createMatchingVisitor(@NotNull GlobalMatchingVisitor globalVisitor) {
+ return new JavaMatchingVisitor(globalVisitor);
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor getLexicalNodesFilter(@NotNull LexicalNodesFilter filter) {
+ if (myJavaLexicalNodesFilter == null) {
+ myJavaLexicalNodesFilter = new JavaLexicalNodesFilter(filter);
+ }
+ return myJavaLexicalNodesFilter;
+ }
+
+ @NotNull
+ public CompiledPattern createCompiledPattern() {
+ return new JavaCompiledPattern();
+ }
+
+ @Override
+ public boolean canProcess(@NotNull FileType fileType) {
+ return fileType == StdFileTypes.JAVA;
+ }
+
+ public boolean isMyLanguage(@NotNull Language language) {
+ return language == StdLanguages.JAVA;
+ }
+
+ @Override
+ public StructuralReplaceHandler getReplaceHandler(@NotNull ReplacementContext context) {
+ return new JavaReplaceHandler(context);
+ }
+
+ @NotNull
+ @Override
+ public PsiElement[] createPatternTree(@NotNull String text,
+ @NotNull PatternTreeContext context,
+ @NotNull FileType fileType,
+ @Nullable Language language,
+ String contextName, @Nullable String extension,
+ @NotNull Project project,
+ boolean physical) {
+ if (physical) {
+ throw new UnsupportedOperationException(getClass() + " cannot create physical PSI");
+ }
+ PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
+ if (context == PatternTreeContext.Block) {
+ PsiElement element = elementFactory.createStatementFromText("{\n" + text + "\n}", null);
+ final PsiElement[] children = ((PsiBlockStatement)element).getCodeBlock().getChildren();
+ final int extraChildCount = 4;
+
+ if (children.length > extraChildCount) {
+ PsiElement[] result = new PsiElement[children.length - extraChildCount];
+ final int extraChildStart = 2;
+ System.arraycopy(children, extraChildStart, result, 0, children.length - extraChildCount);
+ return result;
+ }
+ else {
+ return PsiElement.EMPTY_ARRAY;
+ }
+ }
+ else if (context == PatternTreeContext.Class) {
+ PsiElement element = elementFactory.createStatementFromText("class A {\n" + text + "\n}", null);
+ PsiClass clazz = (PsiClass)((PsiDeclarationStatement)element).getDeclaredElements()[0];
+ PsiElement startChild = clazz.getLBrace();
+ if (startChild != null) startChild = startChild.getNextSibling();
+
+ PsiElement endChild = clazz.getRBrace();
+ if (endChild != null) endChild = endChild.getPrevSibling();
+ if (startChild == endChild) return PsiElement.EMPTY_ARRAY; // nothing produced
+
+ final List<PsiElement> result = new ArrayList<PsiElement>(3);
+ assert startChild != null;
+ for (PsiElement el = startChild.getNextSibling(); el != endChild && el != null; el = el.getNextSibling()) {
+ if (el instanceof PsiErrorElement) continue;
+ result.add(el);
+ }
+
+ return PsiUtilCore.toPsiElementArray(result);
+ }
+ else {
+ return PsiFileFactory.getInstance(project).createFileFromText("__dummy.java", text).getChildren();
+ }
+ }
+
+ @NotNull
+ @Override
+ public Editor createEditor(@NotNull SearchContext searchContext,
+ @NotNull FileType fileType,
+ Language dialect,
+ String text,
+ boolean useLastConfiguration) {
+ // provides autocompletion
+
+ PsiElement element = searchContext.getFile();
+
+ if (element != null && !useLastConfiguration) {
+ final Editor selectedEditor = FileEditorManager.getInstance(searchContext.getProject()).getSelectedTextEditor();
+
+ if (selectedEditor != null) {
+ int caretPosition = selectedEditor.getCaretModel().getOffset();
+ PsiElement positionedElement = searchContext.getFile().findElementAt(caretPosition);
+
+ if (positionedElement == null) {
+ positionedElement = searchContext.getFile().findElementAt(caretPosition + 1);
+ }
+
+ if (positionedElement != null) {
+ element = PsiTreeUtil.getParentOfType(
+ positionedElement,
+ PsiClass.class, PsiCodeBlock.class
+ );
+ }
+ }
+ }
+
+ final PsiManager psimanager = PsiManager.getInstance(searchContext.getProject());
+ final Project project = psimanager.getProject();
+ final PsiCodeFragment file = createCodeFragment(project, text, element);
+ final Document doc = PsiDocumentManager.getInstance(searchContext.getProject()).getDocument(file);
+ DaemonCodeAnalyzer.getInstance(searchContext.getProject()).setHighlightingEnabled(file, false);
+ return UIUtil.createEditor(doc, searchContext.getProject(), true, true, getTemplateContextType());
+ }
+
+ @Override
+ public Class<? extends TemplateContextType> getTemplateContextTypeClass() {
+ return JavaCodeContextType.class;
+ }
+
+ public PsiCodeFragment createCodeFragment(Project project, String text, PsiElement context) {
+ final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project);
+ return factory.createCodeBlockCodeFragment(text, context, true);
+ }
+
+ @Override
+ public void checkSearchPattern(Project project, MatchOptions options) {
+ class ValidatingVisitor extends JavaRecursiveElementWalkingVisitor {
+ private PsiElement myCurrent;
+
+ @Override public void visitAnnotation(PsiAnnotation annotation) {
+ final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
+
+ if (nameReferenceElement == null ||
+ !nameReferenceElement.getText().equals(MatchOptions.MODIFIER_ANNOTATION_NAME)) {
+ return;
+ }
+
+ for(PsiNameValuePair pair:annotation.getParameterList().getAttributes()) {
+ final PsiAnnotationMemberValue value = pair.getValue();
+
+ if (value instanceof PsiArrayInitializerMemberValue) {
+ for(PsiAnnotationMemberValue v:((PsiArrayInitializerMemberValue)value).getInitializers()) {
+ final String name = StringUtil.stripQuotesAroundValue(v.getText());
+ checkModifier(name);
+ }
+
+ } else if (value != null) {
+ final String name = StringUtil.stripQuotesAroundValue(value.getText());
+ checkModifier(name);
+ }
+ }
+ }
+
+ private void checkModifier(final String name) {
+ if (!MatchOptions.INSTANCE_MODIFIER_NAME.equals(name) &&
+ !PsiModifier.PACKAGE_LOCAL.equals(name) &&
+ Arrays.binarySearch(JavaMatchingVisitor.MODIFIERS, name) < 0
+ ) {
+ throw new MalformedPatternException(SSRBundle.message("invalid.modifier.type",name));
+ }
+ }
+
+ @Override
+ public void visitErrorElement(PsiErrorElement element) {
+ super.visitErrorElement(element);
+ //final PsiElement parent = element.getParent();
+ //if (parent != myCurrent || !"';' expected".equals(element.getErrorDescription())) {
+ // throw new MalformedPatternException(element.getErrorDescription());
+ //}
+ }
+
+ public void setCurrent(PsiElement current) {
+ myCurrent = current;
+ }
+ }
+ ValidatingVisitor visitor = new ValidatingVisitor();
+ final CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, options);
+ final int nodeCount = compiledPattern.getNodeCount();
+ final NodeIterator nodes = compiledPattern.getNodes();
+ while (nodes.hasNext()) {
+ final PsiElement current = nodes.current();
+ visitor.setCurrent(nodeCount == 1 && current instanceof PsiExpressionStatement ? current : null);
+ current.accept(visitor);
+ nodes.advance();
+ }
+ nodes.reset();
+ }
+
+ @Override
+ public void checkReplacementPattern(Project project, ReplaceOptions options) {
+ MatchOptions matchOptions = options.getMatchOptions();
+ FileType fileType = matchOptions.getFileType();
+ PsiElement[] statements = MatcherImplUtil.createTreeFromText(
+ matchOptions.getSearchPattern(),
+ PatternTreeContext.Block,
+ fileType,
+ project
+ );
+ final boolean searchIsExpression = statements.length == 1 && statements[0].getLastChild() instanceof PsiErrorElement;
+
+ PsiElement[] statements2 = MatcherImplUtil.createTreeFromText(
+ options.getReplacement(),
+ PatternTreeContext.Block,
+ fileType,
+ project
+ );
+ final boolean replaceIsExpression = statements2.length == 1 && statements2[0].getLastChild() instanceof PsiErrorElement;
+
+ if (searchIsExpression != replaceIsExpression) {
+ throw new UnsupportedPatternException(
+ searchIsExpression ? SSRBundle.message("replacement.template.is.not.expression.error.message") :
+ SSRBundle.message("search.template.is.not.expression.error.message")
+ );
+ }
+ }
+
+ @Override
+ public LanguageFileType getDefaultFileType(LanguageFileType currentDefaultFileType) {
+ return StdFileTypes.JAVA;
+ }
+
+ @Override
+ Configuration[] getPredefinedTemplates() {
+ return JavaPredefinedConfigurations.createPredefinedTemplates();
+ }
+
+ @Override
+ public void provideAdditionalReplaceOptions(@NotNull PsiElement node, final ReplaceOptions options, final ReplacementBuilder builder) {
+ final String templateText = TemplateManager.getInstance(node.getProject()).createTemplate("", "", options.getReplacement()).getTemplateText();
+ node.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ visitElement(expression);
+ }
+
+ @Override
+ public void visitVariable(PsiVariable field) {
+ super.visitVariable(field);
+
+ final PsiExpression initializer = field.getInitializer();
+
+ if (initializer != null) {
+ final String initText = initializer.getText();
+
+ if (StructuralSearchUtil.isTypedVariable(initText)) {
+ final ParameterInfo initInfo = builder.findParameterization(Replacer.stripTypedVariableDecoration(initText));
+
+ if (initInfo != null) {
+ initInfo.setVariableInitialContext(true);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitClass(PsiClass aClass) {
+ super.visitClass(aClass);
+
+ MatchVariableConstraint constraint =
+ options.getMatchOptions().getVariableConstraint(CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME);
+ if (constraint != null) {
+ ParameterInfo e = new ParameterInfo();
+ e.setName(CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME);
+ e.setStartIndex(templateText.lastIndexOf('}'));
+ builder.addParametrization(e);
+ }
+ }
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+
+ String name = method.getName();
+ if (StructuralSearchUtil.isTypedVariable(name)) {
+ name = Replacer.stripTypedVariableDecoration(name);
+
+ ParameterInfo methodInfo = builder.findParameterization(name);
+ methodInfo.setScopeParameterization(true);
+ //if (scopedParameterizations != null) scopedParameterizations.put(method.getTextRange(), methodInfo);
+ }
+ }
+
+ @Override
+ public void visitParameter(PsiParameter parameter) {
+ super.visitParameter(parameter);
+
+ String name = parameter.getName();
+ String type = parameter.getType().getCanonicalText();
+
+ if (StructuralSearchUtil.isTypedVariable(name)) {
+ name = Replacer.stripTypedVariableDecoration(name);
+
+ if (StructuralSearchUtil.isTypedVariable(type)) {
+ type = Replacer.stripTypedVariableDecoration(type);
+ }
+ ParameterInfo nameInfo = builder.findParameterization(name);
+ ParameterInfo typeInfo = builder.findParameterization(type);
+
+ if (nameInfo != null && typeInfo != null && !(parameter.getParent() instanceof PsiCatchSection)) {
+ nameInfo.setParameterContext(false);
+ typeInfo.setParameterContext(false);
+ typeInfo.setMethodParameterContext(true);
+ nameInfo.setMethodParameterContext(true);
+ typeInfo.setElement(parameter.getTypeElement());
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public int handleSubstitution(final ParameterInfo info,
+ MatchResult match,
+ StringBuilder result,
+ int offset,
+ HashMap<String, MatchResult> matchMap) {
+ if (info.getName().equals(match.getName())) {
+ String replacementString = match.getMatchImage();
+ boolean forceAddingNewLine = false;
+
+ if (info.isMethodParameterContext()) {
+ StringBuilder buf = new StringBuilder();
+ handleMethodParameter(buf, info, matchMap);
+ replacementString = buf.toString();
+ }
+ else if (match.getAllSons().size() > 0 && !match.isScopeMatch()) {
+ // compound matches
+ StringBuilder buf = new StringBuilder();
+ MatchResult r = null;
+
+ for (final MatchResult matchResult : match.getAllSons()) {
+ MatchResult previous = r;
+ r = matchResult;
+
+ final PsiElement currentElement = r.getMatch();
+
+ if (buf.length() > 0) {
+ final PsiElement parent = currentElement.getParent();
+ if (info.isStatementContext()) {
+ final PsiElement previousElement = previous.getMatchRef().getElement();
+
+ if (!(previousElement instanceof PsiComment) &&
+ ( buf.charAt(buf.length() - 1) != '}' ||
+ previousElement instanceof PsiDeclarationStatement
+ )
+ ) {
+ buf.append(';');
+ }
+
+ final PsiElement prevSibling = currentElement.getPrevSibling();
+
+ if (prevSibling instanceof PsiWhiteSpace &&
+ prevSibling.getPrevSibling() == previous.getMatch()
+ ) {
+ // consequent statements matched so preserve whitespacing
+ buf.append(prevSibling.getText());
+ }
+ else {
+ buf.append('\n');
+ }
+ }
+ else if (info.isParameterContext()) {
+ buf.append(',');
+ }
+ else if (parent instanceof PsiClass) {
+ final PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(currentElement, PsiWhiteSpace.class);
+ if (prevSibling instanceof PsiJavaToken && JavaTokenType.COMMA.equals(((PsiJavaToken)prevSibling).getTokenType())) {
+ buf.append(',');
+ }
+ else {
+ buf.append('\n');
+ }
+ }
+ else if (parent instanceof PsiReferenceList) {
+ buf.append(',');
+ }
+ else {
+ buf.append(' ');
+ }
+ }
+
+ buf.append(r.getMatchImage());
+ removeExtraSemicolonForSingleVarInstanceInMultipleMatch(info, r, buf);
+ forceAddingNewLine = currentElement instanceof PsiComment;
+ }
+
+ replacementString = buf.toString();
+ } else {
+ StringBuilder buf = new StringBuilder();
+ if (info.isStatementContext()) {
+ forceAddingNewLine = match.getMatch() instanceof PsiComment;
+ }
+ buf.append(replacementString);
+ removeExtraSemicolonForSingleVarInstanceInMultipleMatch(info, match, buf);
+ replacementString = buf.toString();
+ }
+
+ offset = Replacer.insertSubstitution(result, offset, info, replacementString);
+ offset = removeExtraSemicolon(info, offset, result, match);
+ if (forceAddingNewLine && info.isStatementContext()) {
+ result.insert(info.getStartIndex() + offset + 1, '\n');
+ offset ++;
+ }
+ }
+ return offset;
+ }
+
+ @Override
+ public int processAdditionalOptions(ParameterInfo info, int offset, StringBuilder result, MatchResult r) {
+ if (info.isStatementContext()) {
+ return removeExtraSemicolon(info, offset, result, r);
+ }
+ return offset;
+ }
+
+ @Override
+ public boolean isIdentifier(PsiElement element) {
+ return element instanceof PsiIdentifier;
+ }
+
+ @Override
+ public Collection<String> getReservedWords() {
+ return Collections.singleton(PsiModifier.PACKAGE_LOCAL);
+ }
+
+ @Override
+ public boolean isDocCommentOwner(PsiElement match) {
+ return match instanceof PsiMember;
+ }
+
+ private static void handleMethodParameter(StringBuilder buf, ParameterInfo info, HashMap<String, MatchResult> matchMap) {
+ if(info.getElement() ==null) {
+ // no specific handling for name of method parameter since it is handled with type
+ return;
+ }
+
+ String name = ((PsiParameter)info.getElement().getParent()).getName();
+ name = StructuralSearchUtil.isTypedVariable(name) ? Replacer.stripTypedVariableDecoration(name):name;
+
+ final MatchResult matchResult = matchMap.get(name);
+ if (matchResult == null) return;
+
+ if (matchResult.isMultipleMatch()) {
+ for (MatchResult result : matchResult.getAllSons()) {
+ if (buf.length() > 0) {
+ buf.append(',');
+ }
+
+ appendParameter(buf, result);
+ }
+ } else {
+ appendParameter(buf, matchResult);
+ }
+ }
+
+ private static void appendParameter(final StringBuilder buf, final MatchResult _matchResult) {
+ for(Iterator<MatchResult> j = _matchResult.getAllSons().iterator();j.hasNext();) {
+ buf.append(j.next().getMatchImage()).append(' ').append(j.next().getMatchImage());
+ }
+ }
+
+ private static void removeExtraSemicolonForSingleVarInstanceInMultipleMatch(final ParameterInfo info, MatchResult r, StringBuilder buf) {
+ if (info.isStatementContext()) {
+ final PsiElement element = r.getMatchRef().getElement();
+
+ // remove extra ;
+ if (buf.charAt(buf.length()-1)==';' &&
+ r.getMatchImage().charAt(r.getMatchImage().length()-1)==';' &&
+ ( element instanceof PsiReturnStatement ||
+ element instanceof PsiDeclarationStatement ||
+ element instanceof PsiExpressionStatement ||
+ element instanceof PsiAssertStatement ||
+ element instanceof PsiBreakStatement ||
+ element instanceof PsiContinueStatement ||
+ element instanceof PsiMember ||
+ element instanceof PsiIfStatement && !(((PsiIfStatement)element).getThenBranch() instanceof PsiBlockStatement) ||
+ element instanceof PsiLoopStatement && !(((PsiLoopStatement)element).getBody() instanceof PsiBlockStatement)
+ )
+ ) {
+ // contains extra ;
+ buf.deleteCharAt(buf.length()-1);
+ }
+ }
+ }
+
+ private static int removeExtraSemicolon(ParameterInfo info, int offset, StringBuilder result, MatchResult match) {
+ if (info.isStatementContext()) {
+ int index = offset+ info.getStartIndex();
+ if (result.charAt(index)==';' &&
+ ( match == null ||
+ ( result.charAt(index-1)=='}' &&
+ !(match.getMatch() instanceof PsiDeclarationStatement) && // array init in dcl
+ !(match.getMatch() instanceof PsiNewExpression) // array initializer
+ ) ||
+ ( !match.isMultipleMatch() && // ; in comment
+ match.getMatch() instanceof PsiComment
+ ) ||
+ ( match.isMultipleMatch() && // ; in comment
+ match.getAllSons().get( match.getAllSons().size() - 1 ).getMatch() instanceof PsiComment
+ )
+ )
+ ) {
+ result.deleteCharAt(index);
+ --offset;
+ }
+ }
+
+ return offset;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaCompiledPattern.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaCompiledPattern.java
new file mode 100644
index 000000000000..9a6330bb799b
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaCompiledPattern.java
@@ -0,0 +1,90 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.strategies.ExprMatchingStrategy;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class JavaCompiledPattern extends CompiledPattern {
+ private static final String TYPED_VAR_PREFIX = "__$_";
+
+ private boolean requestsSuperFields;
+ private boolean requestsSuperMethods;
+ private boolean requestsSuperInners;
+
+ public JavaCompiledPattern() {
+ setStrategy(ExprMatchingStrategy.getInstance());
+ }
+
+ public String[] getTypedVarPrefixes() {
+ return new String[] {TYPED_VAR_PREFIX};
+ }
+
+ public boolean isTypedVar(final String str) {
+ if (str.charAt(0)=='@') {
+ return str.regionMatches(1,TYPED_VAR_PREFIX,0,TYPED_VAR_PREFIX.length());
+ } else {
+ return str.startsWith(TYPED_VAR_PREFIX);
+ }
+ }
+
+ @Override
+ public boolean isToResetHandler(PsiElement element) {
+ return !(element instanceof PsiJavaToken) &&
+ !(element instanceof PsiJavaCodeReferenceElement && element.getParent() instanceof PsiAnnotation);
+ }
+
+ @Nullable
+ @Override
+ public String getAlternativeTextToMatch(PsiElement node, String previousText) {
+ // Short class name is matched with fully qualified name
+ if(node instanceof PsiJavaCodeReferenceElement || node instanceof PsiClass) {
+ PsiElement element = (node instanceof PsiJavaCodeReferenceElement)?
+ ((PsiJavaCodeReferenceElement)node).resolve():
+ node;
+
+ if (element instanceof PsiClass) {
+ String text = ((PsiClass)element).getQualifiedName();
+ if (text != null && text.equals(previousText)) {
+ text = ((PsiClass)element).getName();
+ }
+
+ if (text != null) {
+ return text;
+ }
+ }
+ } else if (node instanceof PsiLiteralExpression) {
+ return node.getText();
+ }
+ return null;
+ }
+
+ public static final Key<String> ALL_CLASS_CONTENT_VAR_NAME_KEY = Key.create("AllClassContent");
+
+ public boolean isRequestsSuperFields() {
+ return requestsSuperFields;
+ }
+
+ public void setRequestsSuperFields(boolean requestsSuperFields) {
+ this.requestsSuperFields = requestsSuperFields;
+ }
+
+ public boolean isRequestsSuperInners() {
+ return requestsSuperInners;
+ }
+
+ public void setRequestsSuperInners(boolean requestsSuperInners) {
+ this.requestsSuperInners = requestsSuperInners;
+ }
+
+ public boolean isRequestsSuperMethods() {
+ return requestsSuperMethods;
+ }
+
+ public void setRequestsSuperMethods(boolean requestsSuperMethods) {
+ this.requestsSuperMethods = requestsSuperMethods;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchPredicateProvider.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchPredicateProvider.java
new file mode 100644
index 000000000000..042912e0354c
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchPredicateProvider.java
@@ -0,0 +1,62 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchVariableConstraint;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.predicates.*;
+
+import java.util.Set;
+
+public class JavaMatchPredicateProvider extends MatchPredicateProvider{
+ @Override
+ public void collectPredicates(MatchVariableConstraint constraint, String name, MatchOptions options, Set<MatchPredicate> predicates) {
+ if (constraint.isReadAccess()) {
+ MatchPredicate predicate = new ReadPredicate();
+
+ if (constraint.isInvertReadAccess()) {
+ predicate = new NotPredicate(predicate);
+ }
+ predicates.add(predicate);
+ }
+
+ if (constraint.isWriteAccess()) {
+ MatchPredicate predicate = new WritePredicate();
+
+ if (constraint.isInvertWriteAccess()) {
+ predicate = new NotPredicate(predicate);
+ }
+ predicates.add(predicate);
+ }
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getNameOfExprType())) {
+ MatchPredicate predicate = new ExprTypePredicate(
+ constraint.getNameOfExprType(),
+ name,
+ constraint.isExprTypeWithinHierarchy(),
+ options.isCaseSensitiveMatch(),
+ constraint.isPartOfSearchResults()
+ );
+
+ if (constraint.isInvertExprType()) {
+ predicate = new NotPredicate(predicate);
+ }
+ predicates.add(predicate);
+ }
+
+ if (!StringUtil.isEmptyOrSpaces(constraint.getNameOfFormalArgType())) {
+ MatchPredicate predicate = new FormalArgTypePredicate(
+ constraint.getNameOfFormalArgType(),
+ name,
+ constraint.isFormalArgTypeWithinHierarchy(),
+ options.isCaseSensitiveMatch(),
+ constraint.isPartOfSearchResults()
+ );
+ if (constraint.isInvertFormalType()) {
+ predicate = new NotPredicate(predicate);
+ }
+ predicates.add(predicate);
+ }
+
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java
new file mode 100644
index 000000000000..38e77c796281
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java
@@ -0,0 +1,1640 @@
+package com.intellij.structuralsearch.impl.matcher;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.javadoc.PsiDocTag;
+import com.intellij.psi.javadoc.PsiDocTagValue;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchResult;
+import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler;
+import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler;
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.structuralsearch.impl.matcher.iterators.DocValuesIterator;
+import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.structuralsearch.impl.matcher.predicates.NotPredicate;
+import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.*;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class JavaMatchingVisitor extends JavaElementVisitor {
+ public static final String[] MODIFIERS = {
+ PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC, PsiModifier.ABSTRACT, PsiModifier.FINAL,
+ PsiModifier.NATIVE, PsiModifier.SYNCHRONIZED, PsiModifier.STRICTFP, PsiModifier.TRANSIENT, PsiModifier.VOLATILE, PsiModifier.DEFAULT
+ };
+ public static final Key<List<PsiCatchSection>> UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY = Key.create("UnmatchedCatchSection");
+ private final GlobalMatchingVisitor myMatchingVisitor;
+ private PsiClass myClazz;
+
+ static {
+ Arrays.sort(MODIFIERS);
+ }
+
+ public JavaMatchingVisitor(GlobalMatchingVisitor matchingVisitor) {
+ this.myMatchingVisitor = matchingVisitor;
+ }
+
+ @Override
+ public void visitComment(PsiComment comment) {
+ PsiElement comment2 = null;
+
+ if (!(myMatchingVisitor.getElement() instanceof PsiComment)) {
+ if (myMatchingVisitor.getElement() instanceof PsiMember) {
+ final PsiElement[] children = myMatchingVisitor.getElement().getChildren();
+ if (children[0] instanceof PsiComment) {
+ comment2 = children[0];
+ }
+ }
+ }
+ else {
+ comment2 = myMatchingVisitor.getElement();
+ }
+
+ if (comment2 == null) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ final Object userData = comment.getUserData(CompiledPattern.HANDLER_KEY);
+
+ if (userData instanceof String) {
+ String str = (String)userData;
+ int end = comment2.getTextLength();
+
+ if (((PsiComment)comment2).getTokenType() == JavaTokenType.C_STYLE_COMMENT) {
+ end -= 2;
+ }
+ myMatchingVisitor.setResult(((SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(str)).handle(
+ comment2,
+ 2,
+ end,
+ myMatchingVisitor.getMatchContext()
+ ));
+ }
+ else if (userData instanceof MatchingHandler) {
+ myMatchingVisitor.setResult(((MatchingHandler)userData).match(comment, comment2, myMatchingVisitor.getMatchContext()));
+ }
+ else {
+ myMatchingVisitor.setResult(comment.getText().equals(comment2.getText()));
+ }
+ }
+
+ @Override
+ public void visitDocTagValue(final PsiDocTagValue value) {
+ final PsiDocTagValue value2 = (PsiDocTagValue)myMatchingVisitor.getElement();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(value);
+
+ if (isTypedVar) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(value, value2));
+ }
+ else {
+ myMatchingVisitor.setResult(value.textMatches(value2));
+ }
+ }
+
+ private static boolean isNotInstanceModifier(final PsiModifierList list2) {
+ return list2.hasModifierProperty(PsiModifier.STATIC) ||
+ list2.hasModifierProperty(PsiModifier.ABSTRACT);
+ }
+
+ @Override
+ public final void visitModifierList(final PsiModifierList list) {
+ final PsiModifierList list2 = (PsiModifierList)myMatchingVisitor.getElement();
+
+ for (@PsiModifier.ModifierConstant String modifier : MODIFIERS) {
+ if (list.hasModifierProperty(modifier) && !list2.hasModifierProperty(modifier)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+
+ final PsiAnnotation[] annotations = list.getAnnotations();
+ if (annotations.length > 0) {
+ HashSet<PsiAnnotation> set = new HashSet<PsiAnnotation>(Arrays.asList(annotations));
+
+ for (PsiAnnotation annotation : annotations) {
+ final PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
+
+ if (nameReferenceElement != null && MatchOptions.MODIFIER_ANNOTATION_NAME.equals(nameReferenceElement.getText())) {
+ final PsiAnnotationParameterList parameterList = annotation.getParameterList();
+ final PsiNameValuePair[] attributes = parameterList.getAttributes();
+
+ for (PsiNameValuePair pair : attributes) {
+ final PsiAnnotationMemberValue value = pair.getValue();
+ if (value == null) continue;
+
+ if (value instanceof PsiArrayInitializerMemberValue) {
+ boolean matchedOne = false;
+
+ for (PsiAnnotationMemberValue v : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
+ @PsiModifier.ModifierConstant String name = StringUtil.stripQuotesAroundValue(v.getText());
+ if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
+ if (isNotInstanceModifier(list2)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ else {
+ matchedOne = true;
+ }
+ }
+ else if (list2.hasModifierProperty(name)) {
+ matchedOne = true;
+ break;
+ }
+ }
+
+ if (!matchedOne) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+ else {
+ @PsiModifier.ModifierConstant String name = StringUtil.stripQuotesAroundValue(value.getText());
+ if (MatchOptions.INSTANCE_MODIFIER_NAME.equals(name)) {
+ if (isNotInstanceModifier(list2)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+ else if (!list2.hasModifierProperty(name)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+ }
+
+ set.remove(annotation);
+ }
+ }
+
+ myMatchingVisitor.setResult(set.isEmpty() || myMatchingVisitor
+ .matchInAnyOrder(set.toArray(new PsiAnnotation[set.size()]), list2.getAnnotations()));
+ }
+ else {
+ myMatchingVisitor.setResult(true);
+ }
+ }
+
+ @Override
+ public void visitDocTag(final PsiDocTag tag) {
+ final PsiDocTag tag2 = (PsiDocTag)myMatchingVisitor.getElement();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(tag.getNameElement());
+
+ myMatchingVisitor.setResult(isTypedVar || tag.getName().equals(tag2.getName()));
+
+ PsiElement psiDocTagValue = tag.getValueElement();
+ boolean isTypedValue = false;
+
+ if (myMatchingVisitor.getResult() && psiDocTagValue != null) {
+ final PsiElement[] children = psiDocTagValue.getChildren();
+ if (children.length == 1) {
+ psiDocTagValue = children[0];
+ }
+ isTypedValue = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(psiDocTagValue);
+
+ if (isTypedValue) {
+ if (tag2.getValueElement() != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(psiDocTagValue, tag2.getValueElement()));
+ }
+ else {
+ myMatchingVisitor.setResult(allowsAbsenceOfMatch(psiDocTagValue));
+ }
+ }
+ }
+
+ if (myMatchingVisitor.getResult() && !isTypedValue) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(
+ new DocValuesIterator(tag.getFirstChild()),
+ new DocValuesIterator(tag2.getFirstChild())
+ ));
+ }
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(tag.getNameElement(), tag2.getNameElement()));
+ }
+ }
+
+ private boolean allowsAbsenceOfMatch(final PsiElement element) {
+ MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(element);
+
+ if (handler instanceof SubstitutionHandler &&
+ ((SubstitutionHandler)handler).getMinOccurs() == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void visitDocComment(final PsiDocComment comment) {
+ PsiDocComment comment2;
+
+ if (myMatchingVisitor.getElement() instanceof PsiDocCommentOwner) {
+ comment2 = ((PsiDocCommentOwner)myMatchingVisitor.getElement()).getDocComment();
+
+ if (comment2 == null) {
+ // doc comment are not collapsed for inner classes!
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+ else {
+ comment2 = (PsiDocComment)myMatchingVisitor.getElement();
+
+ if (myMatchingVisitor.getElement().getParent() instanceof PsiDocCommentOwner) {
+ myMatchingVisitor.setResult(false);
+ return; // we should matched the doc before
+ }
+ }
+
+ if (comment.getTags().length > 0) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(comment.getTags(), comment2.getTags()));
+ }
+ else {
+ visitComment(comment);
+ }
+ }
+
+ @Override
+ public void visitElement(PsiElement el) {
+ myMatchingVisitor.setResult(el.textMatches(myMatchingVisitor.getElement()));
+ }
+
+ @Override
+ public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
+ final PsiArrayInitializerExpression expr2 = (PsiArrayInitializerExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(
+ new ArrayBackedNodeIterator(expression.getInitializers()),
+ new ArrayBackedNodeIterator(expr2.getInitializers())
+ ));
+ }
+
+ @Override
+ public void visitClassInitializer(PsiClassInitializer initializer) {
+ PsiClassInitializer initializer2 = (PsiClassInitializer)myMatchingVisitor.getElement();
+ myMatchingVisitor.setResult(myMatchingVisitor.match(initializer.getModifierList(), initializer2.getModifierList()) &&
+ myMatchingVisitor.match(initializer.getBody(), initializer2.getBody()));
+ }
+
+ @Override
+ public void visitCodeBlock(PsiCodeBlock block) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(block, myMatchingVisitor.getElement()));
+ }
+
+ @Override
+ public void visitJavaToken(final PsiJavaToken token) {
+ PsiElement element = myMatchingVisitor.getElement();
+ boolean result;
+
+ if (!(element instanceof PsiJavaToken)) {
+ result = token.textMatches(element);
+ } else {
+ final PsiJavaToken anotherToken = (PsiJavaToken)element;
+
+ result = token.getTokenType() == anotherToken.getTokenType() && token.textMatches(anotherToken);
+ }
+
+ myMatchingVisitor.setResult(result);
+ }
+
+ @Override
+ public void visitAnnotation(PsiAnnotation annotation) {
+ final PsiAnnotation psiAnnotation = (PsiAnnotation)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(annotation.getNameReferenceElement(), psiAnnotation.getNameReferenceElement()) &&
+ myMatchingVisitor
+ .matchInAnyOrder(annotation.getParameterList().getAttributes(),
+ psiAnnotation.getParameterList().getAttributes()));
+ }
+
+ @Override
+ public void visitNameValuePair(PsiNameValuePair pair) {
+ final PsiIdentifier nameIdentifier = pair.getNameIdentifier();
+ if (nameIdentifier == null) {
+ myMatchingVisitor.setResult(true);
+ return;
+ }
+
+ final PsiNameValuePair elementNameValuePair = (PsiNameValuePair)myMatchingVisitor.getElement();
+ PsiIdentifier matchedNameValuePair = elementNameValuePair.getNameIdentifier();
+
+ PsiAnnotationMemberValue annotationInitializer = pair.getValue();
+ boolean isTypedInitializer = annotationInitializer != null &&
+ myMatchingVisitor.getMatchContext().getPattern().isTypedVar(annotationInitializer) &&
+ annotationInitializer instanceof PsiReferenceExpression;
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(annotationInitializer, elementNameValuePair.getValue()) ||
+ (isTypedInitializer &&
+ elementNameValuePair.getValue() == null &&
+ allowsAbsenceOfMatch(annotationInitializer)
+ ));
+ if (myMatchingVisitor.getResult()) {
+ final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(nameIdentifier);
+
+ if (handler instanceof SubstitutionHandler) {
+ myMatchingVisitor
+ .setResult(((SubstitutionHandler)handler).handle(matchedNameValuePair,
+ myMatchingVisitor.getMatchContext()));
+ }
+ else {
+ myMatchingVisitor
+ .setResult(myMatchingVisitor.match(nameIdentifier, matchedNameValuePair));
+ }
+ }
+ }
+
+ private boolean checkHierarchy(PsiMember element, PsiMember patternElement) {
+ final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(patternElement);
+ if (handler instanceof SubstitutionHandler) {
+ final SubstitutionHandler handler2 = (SubstitutionHandler)handler;
+
+ if (!handler2.isSubtype()) {
+ if (handler2.isStrictSubtype()) {
+ // check if element is declared not in current class (in ancestors)
+ return element.getContainingClass() != myClazz;
+ }
+ }
+ else {
+ return true;
+ }
+ }
+
+ // check if element is declared in current class (not in ancestors)
+ return element.getContainingClass() == myClazz;
+ }
+
+ @Override
+ public void visitField(PsiField psiField) {
+ if (!checkHierarchy((PsiField)myMatchingVisitor.getElement(), psiField)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ super.visitField(psiField);
+ }
+
+ @Override
+ public void visitAnonymousClass(final PsiAnonymousClass clazz) {
+ final PsiAnonymousClass clazz2 = (PsiAnonymousClass)myMatchingVisitor.getElement();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(clazz.getFirstChild());
+
+ myMatchingVisitor.setResult((myMatchingVisitor.match(clazz.getBaseClassReference(), clazz2.getBaseClassReference()) || isTypedVar) &&
+ myMatchingVisitor.matchSons(clazz.getArgumentList(), clazz2.getArgumentList()) &&
+ compareClasses(clazz, clazz2));
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(clazz.getFirstChild(), clazz2.getFirstChild()));
+ }
+ }
+
+ @Override
+ public void visitLambdaExpression(PsiLambdaExpression expression) {
+ final PsiLambdaExpression expression2 = (PsiLambdaExpression)myMatchingVisitor.getElement();
+ boolean result = true;
+ final PsiParameterList parameterList1 = expression.getParameterList();
+ if (parameterList1.getParametersCount() != 0) {
+ result = myMatchingVisitor.matchSons(parameterList1, expression2.getParameterList());
+ }
+ final PsiElement body1 = getElementToMatch(expression.getBody());
+ if (body1 != null) {
+ result = myMatchingVisitor.matchSequentially(body1, getElementToMatch(expression2.getBody()));
+ }
+ myMatchingVisitor.setResult(result);
+ }
+
+ private static PsiElement getElementToMatch(PsiElement element) {
+ if (element instanceof PsiCodeBlock) {
+ element = PsiTreeUtil.getChildOfAnyType(element, PsiStatement.class, PsiComment.class);
+ }
+ if (element instanceof PsiExpressionStatement) {
+ element = ((PsiExpressionStatement)element).getExpression();
+ }
+ if (element instanceof PsiReturnStatement) {
+ element = ((PsiReturnStatement)element).getReturnValue();
+ }
+ return element;
+ }
+
+ protected boolean matchInAnyOrder(final PsiReferenceList elements, final PsiReferenceList elements2, GlobalMatchingVisitor visitor) {
+ if ((elements == null && visitor.isLeftLooseMatching()) ||
+ elements == elements2 // null
+ ) {
+ return true;
+ }
+
+ return visitor.matchInAnyOrder(
+ elements.getReferenceElements(),
+ (elements2 != null) ? elements2.getReferenceElements() : PsiElement.EMPTY_ARRAY
+ );
+ }
+
+ private boolean compareClasses(final PsiClass clazz, final PsiClass clazz2) {
+ final PsiClass saveClazz = this.myClazz;
+ final MatchContext.MatchedElementsListener oldListener = myMatchingVisitor.getMatchContext().getMatchedElementsListener();
+
+ this.myClazz = clazz2;
+
+ final CompiledPattern pattern = myMatchingVisitor.getMatchContext().getPattern();
+ assert pattern instanceof JavaCompiledPattern;
+ final JavaCompiledPattern javaPattern = (JavaCompiledPattern)pattern;
+
+ final String unmatchedHandlerName = clazz.getUserData(JavaCompiledPattern.ALL_CLASS_CONTENT_VAR_NAME_KEY);
+ final MatchingHandler allRemainingClassContentElementHandler = unmatchedHandlerName != null ? pattern.getHandler(unmatchedHandlerName) : null;
+ MatchContext.MatchedElementsListener newListener = null;
+
+ assert javaPattern instanceof JavaCompiledPattern;
+ if (allRemainingClassContentElementHandler != null) {
+ myMatchingVisitor.getMatchContext().setMatchedElementsListener(
+ newListener = new MatchContext.MatchedElementsListener() {
+ private Set<PsiElement> myMatchedElements;
+
+ public void matchedElements(Collection<PsiElement> matchedElements) {
+ if (matchedElements == null) return;
+ if (myMatchedElements == null) {
+ myMatchedElements = new HashSet<PsiElement>(matchedElements);
+ }
+ else {
+ myMatchedElements.addAll(matchedElements);
+ }
+ }
+
+ public void commitUnmatched() {
+ final SubstitutionHandler handler = (SubstitutionHandler)allRemainingClassContentElementHandler;
+
+ for (PsiElement el = clazz2.getFirstChild(); el != null; el = el.getNextSibling()) {
+ if (el instanceof PsiMember && (myMatchedElements == null || !myMatchedElements.contains(el))) {
+ handler.handle(el, myMatchingVisitor.getMatchContext());
+ }
+ }
+ }
+ }
+ );
+ }
+
+ boolean result = false;
+ try {
+ final boolean templateIsInterface = clazz.isInterface();
+ if (templateIsInterface != clazz2.isInterface()) return false;
+ if (templateIsInterface && clazz.isAnnotationType() && !clazz2.isAnnotationType()) return false;
+ final boolean templateIsEnum = clazz.isEnum();
+ if (templateIsEnum && !clazz2.isEnum()) return false;
+
+ if (!matchInAnyOrder(clazz.getExtendsList(), clazz2.getExtendsList(), myMatchingVisitor)) {
+ return false;
+ }
+
+ // check if implements is in extended classes implements
+ final PsiReferenceList implementsList = clazz.getImplementsList();
+ if (implementsList != null) {
+ if (!matchInAnyOrder(implementsList, clazz2.getImplementsList(), myMatchingVisitor)) {
+ final PsiReferenceList anotherExtendsList = clazz2.getExtendsList();
+ final PsiJavaCodeReferenceElement[] referenceElements = implementsList.getReferenceElements();
+
+ boolean accepted = false;
+
+ if (referenceElements.length > 0 && anotherExtendsList != null) {
+ final HierarchyNodeIterator iterator = new HierarchyNodeIterator(clazz2, true, true, false);
+
+ accepted = myMatchingVisitor.matchInAnyOrder(new ArrayBackedNodeIterator(referenceElements), iterator);
+ }
+
+ if (!accepted) return false;
+ }
+ }
+
+ final PsiField[] fields = clazz.getFields();
+
+ if (fields.length > 0) {
+ final PsiField[] fields2 = javaPattern.isRequestsSuperFields() ?
+ clazz2.getAllFields() :
+ clazz2.getFields();
+
+ if (!myMatchingVisitor.matchInAnyOrder(fields, fields2)) {
+ return false;
+ }
+ }
+
+ final PsiMethod[] methods = clazz.getMethods();
+
+ if (methods.length > 0) {
+ final PsiMethod[] methods2 = javaPattern.isRequestsSuperMethods() ?
+ clazz2.getAllMethods() :
+ clazz2.getMethods();
+
+ if (!myMatchingVisitor.matchInAnyOrder(methods, methods2)) {
+ return false;
+ }
+ }
+
+ final PsiClass[] nestedClasses = clazz.getInnerClasses();
+
+ if (nestedClasses.length > 0) {
+ final PsiClass[] nestedClasses2 = javaPattern.isRequestsSuperInners() ?
+ clazz2.getAllInnerClasses() :
+ clazz2.getInnerClasses();
+
+ if (!myMatchingVisitor.matchInAnyOrder(nestedClasses, nestedClasses2)) {
+ return false;
+ }
+ }
+
+ final PsiClassInitializer[] initializers = clazz.getInitializers();
+ if (initializers.length > 0) {
+ final PsiClassInitializer[] initializers2 = clazz2.getInitializers();
+
+ if (!myMatchingVisitor.matchInAnyOrder(initializers, initializers2)) {
+ return false;
+ }
+ }
+
+ result = true;
+ return result;
+ }
+ finally {
+ if (result && newListener != null) newListener.commitUnmatched();
+ this.myClazz = saveClazz;
+ myMatchingVisitor.getMatchContext().setMatchedElementsListener(oldListener);
+ }
+ }
+
+ private boolean compareBody(final PsiElement el1, final PsiElement el2) {
+ PsiElement compareElement1 = el1;
+ PsiElement compareElement2 = el2;
+
+ if (myMatchingVisitor.getMatchContext().getOptions().isLooseMatching()) {
+ if (el1 instanceof PsiBlockStatement) {
+ compareElement1 = ((PsiBlockStatement)el1).getCodeBlock().getFirstChild();
+ }
+
+ if (el2 instanceof PsiBlockStatement) {
+ compareElement2 = ((PsiBlockStatement)el2).getCodeBlock().getFirstChild();
+ }
+ }
+
+ return myMatchingVisitor.matchSequentially(compareElement1, compareElement2);
+ }
+
+ @Override
+ public void visitArrayAccessExpression(final PsiArrayAccessExpression slice) {
+ final PsiArrayAccessExpression slice2 = (PsiArrayAccessExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(slice.getArrayExpression(), slice2.getArrayExpression()) &&
+ myMatchingVisitor.match(slice.getIndexExpression(), slice2.getIndexExpression()));
+ }
+
+ @Override
+ public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
+ final PsiElement element = myMatchingVisitor.getElement();
+ if (!(element instanceof PsiMethodReferenceExpression)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ super.visitMethodReferenceExpression(expression);
+ }
+
+ @Override
+ public void visitReferenceExpression(final PsiReferenceExpression reference) {
+ final PsiExpression qualifier = reference.getQualifierExpression();
+
+ final PsiElement nameElement = reference.getReferenceNameElement();
+ final MatchContext context = myMatchingVisitor.getMatchContext();
+ MatchingHandler _handler = nameElement != null ? context.getPattern().getHandlerSimple(nameElement) : null;
+ if (!(_handler instanceof SubstitutionHandler)) _handler = context.getPattern().getHandlerSimple(reference);
+
+ final PsiElement element = myMatchingVisitor.getElement();
+ PsiElement other = element instanceof PsiExpression && context.getOptions().isLooseMatching() ?
+ PsiUtil.skipParenthesizedExprDown((PsiExpression)element) :
+ element;
+ if (_handler instanceof SubstitutionHandler &&
+ !(context.getPattern().getHandlerSimple(qualifier) instanceof SubstitutionHandler) &&
+ !(qualifier instanceof PsiThisExpression)
+ ) {
+ if (other instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression psiReferenceExpression = (PsiReferenceExpression)other;
+
+ final PsiExpression qualifier2 = psiReferenceExpression.getQualifierExpression();
+ if (qualifier2 == null || (context.getOptions().isLooseMatching() && qualifier2 instanceof PsiThisExpression)) {
+ other = psiReferenceExpression.getReferenceNameElement();
+ }
+ }
+
+ final SubstitutionHandler handler = (SubstitutionHandler)_handler;
+ if (handler.isSubtype() || handler.isStrictSubtype()) {
+ myMatchingVisitor.setResult(checkMatchWithingHierarchy(other, handler, reference));
+ }
+ else {
+ myMatchingVisitor.setResult(handler.handle(other, context));
+ }
+
+ return;
+ }
+
+ if (!(other instanceof PsiReferenceExpression)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ final PsiReferenceExpression reference2 = (PsiReferenceExpression)other;
+
+ // just variable
+ final PsiExpression reference2Qualifier = reference2.getQualifierExpression();
+ if (qualifier == null && reference2Qualifier == null) {
+ myMatchingVisitor.setResult(reference.getReferenceNameElement().textMatches(reference2.getReferenceNameElement()));
+ return;
+ }
+
+ // handle field selection
+ if (!(other.getParent() instanceof PsiMethodCallExpression) && qualifier != null) {
+ final PsiElement referenceElement = reference.getReferenceNameElement();
+ final PsiElement referenceElement2 = reference2.getReferenceNameElement();
+
+ if (context.getPattern().isTypedVar(referenceElement)) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(referenceElement, referenceElement2));
+ }
+ else {
+ myMatchingVisitor.setResult(
+ (referenceElement2 != null && referenceElement != null && referenceElement.textMatches(referenceElement2)) ||
+ referenceElement == referenceElement2);
+ }
+
+ if (!myMatchingVisitor.getResult()) {
+ return;
+ }
+ if (reference2Qualifier != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(qualifier, reference2Qualifier));
+ }
+ else {
+ final PsiElement referencedElement = MatchUtils.getReferencedElement(other);
+ if (referencedElement instanceof PsiField) {
+ final PsiField field = (PsiField)referencedElement;
+ if (qualifier instanceof PsiThisExpression) {
+ myMatchingVisitor.setResult(!field.hasModifierProperty(PsiModifier.STATIC));
+ return;
+ }
+ }
+ final MatchingHandler handler = context.getPattern().getHandler(qualifier);
+ matchImplicitQualifier(handler, referencedElement, context);
+ }
+
+ return;
+ }
+
+ myMatchingVisitor.setResult(false);
+ }
+
+ private static int countCStyleArrayDeclarationDims(final PsiElement type2) {
+ if (type2 != null) {
+ final PsiElement parentElement = type2.getParent();
+
+ if (parentElement instanceof PsiVariable) {
+ final PsiIdentifier psiIdentifier = ((PsiVariable)parentElement).getNameIdentifier();
+ if (psiIdentifier == null) return 0;
+
+ int count = 0;
+ for (PsiElement sibling = psiIdentifier.getNextSibling(); sibling != null; sibling = sibling.getNextSibling()) {
+ if (sibling instanceof PsiJavaToken) {
+ final IElementType tokenType = ((PsiJavaToken)sibling).getTokenType();
+ if (tokenType == JavaTokenType.LBRACKET) ++count;
+ else if (tokenType != JavaTokenType.RBRACKET) break;
+ }
+ }
+
+ return count;
+ }
+ }
+ return 0;
+ }
+
+ private void copyResults(final MatchResultImpl ourResult) {
+ if (ourResult.hasSons()) {
+ for (MatchResult son : ourResult.getAllSons()) {
+ myMatchingVisitor.getMatchContext().getResult().addSon((MatchResultImpl)son);
+ }
+ }
+ }
+
+ private boolean matchType(final PsiElement _type, final PsiElement _type2) {
+ PsiElement el = _type;
+ PsiElement el2 = _type2;
+ PsiType type1 = null;
+ PsiType type2 = null;
+
+ // check for generics
+ if (_type instanceof PsiTypeElement &&
+ ((PsiTypeElement)_type).getInnermostComponentReferenceElement() != null
+ ) {
+ el = ((PsiTypeElement)_type).getInnermostComponentReferenceElement();
+ type1 = ((PsiTypeElement)_type).getType();
+ }
+
+ if (_type2 instanceof PsiTypeElement &&
+ ((PsiTypeElement)_type2).getInnermostComponentReferenceElement() != null
+ ) {
+ el2 = ((PsiTypeElement)_type2).getInnermostComponentReferenceElement();
+ type2 = ((PsiTypeElement)_type2).getType();
+ }
+
+ PsiElement[] typeparams = null;
+ if (el2 instanceof PsiJavaCodeReferenceElement) {
+ typeparams = ((PsiJavaCodeReferenceElement)el2).getParameterList().getTypeParameterElements();
+ if (typeparams.length > 0) {
+ el2 = ((PsiJavaCodeReferenceElement)el2).getReferenceNameElement();
+ }
+ }
+ else if (el2 instanceof PsiTypeParameter) {
+ el2 = ((PsiTypeParameter)el2).getNameIdentifier();
+ }
+ else if (el2 instanceof PsiClass && ((PsiClass)el2).hasTypeParameters()
+ ) {
+ typeparams = ((PsiClass)el2).getTypeParameters();
+ el2 = ((PsiClass)el2).getNameIdentifier();
+ }
+ else if (el2 instanceof PsiMethod && ((PsiMethod)el2).hasTypeParameters()
+ ) {
+ typeparams = ((PsiMethod)_type2).getTypeParameters();
+ el2 = ((PsiMethod)_type2).getNameIdentifier();
+ }
+
+ PsiReferenceParameterList list = null;
+ if (el instanceof PsiJavaCodeReferenceElement) {
+ list = ((PsiJavaCodeReferenceElement)el).getParameterList();
+ }
+
+ if (list != null && list.getTypeParameterElements().length > 0) {
+ boolean result = typeparams != null &&
+ myMatchingVisitor.matchInAnyOrder(
+ list.getTypeParameterElements(),
+ typeparams
+ );
+
+ if (!result) return false;
+ el = ((PsiJavaCodeReferenceElement)el).getReferenceNameElement();
+ }
+ else {
+ if (_type2 instanceof PsiTypeElement) {
+ type2 = ((PsiTypeElement)_type2).getType();
+
+ if (typeparams == null || typeparams.length == 0) {
+ final PsiJavaCodeReferenceElement innermostComponentReferenceElement =
+ ((PsiTypeElement)_type2).getInnermostComponentReferenceElement();
+ if (innermostComponentReferenceElement != null) el2 = innermostComponentReferenceElement;
+ }
+ else {
+ el2 = _type2;
+ }
+ }
+ }
+
+ final int array2Dims = (type2 != null ? type2.getArrayDimensions() : 0) + countCStyleArrayDeclarationDims(_type2);
+ final int arrayDims = (type1 != null ? type1.getArrayDimensions() : 0) + countCStyleArrayDeclarationDims(_type);
+
+ if (myMatchingVisitor.getMatchContext().getPattern().isTypedVar(el)) {
+ final SubstitutionHandler handler = (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(el);
+
+ RegExpPredicate regExpPredicate = null;
+
+ if (arrayDims != 0) {
+ if (arrayDims != array2Dims) {
+ return false;
+ }
+ }
+ else if (array2Dims != 0) {
+ regExpPredicate = MatchingHandler.getSimpleRegExpPredicate(handler);
+
+ if (regExpPredicate != null) {
+ regExpPredicate.setNodeTextGenerator(new RegExpPredicate.NodeTextGenerator() {
+ public String getText(PsiElement element) {
+ StringBuilder builder = new StringBuilder(RegExpPredicate.getMeaningfulText(element));
+ for (int i = 0; i < array2Dims; ++i) builder.append("[]");
+ return builder.toString();
+ }
+ });
+ }
+ }
+
+ try {
+ if (handler.isSubtype() || handler.isStrictSubtype()) {
+ return checkMatchWithingHierarchy(el2, handler, el);
+ }
+ else {
+ return handler.handle(el2, myMatchingVisitor.getMatchContext());
+ }
+ }
+ finally {
+ if (regExpPredicate != null) regExpPredicate.setNodeTextGenerator(null);
+ }
+ }
+
+ if (array2Dims != arrayDims) {
+ return false;
+ }
+
+ if (el instanceof PsiIdentifier) {
+ final PsiElement parent = el.getParent();
+ if (parent instanceof PsiJavaCodeReferenceElement) {
+ el = parent;
+ }
+ }
+ if (el2 instanceof PsiIdentifier) {
+ final PsiElement parent = el2.getParent();
+ if (parent instanceof PsiJavaCodeReferenceElement) {
+ el2 = parent;
+ }
+ }
+ final String text = stripTypeParameters(el.getText());
+ if (text.indexOf('.') == -1 || !(el2 instanceof PsiJavaReference)) {
+ return MatchUtils.compareWithNoDifferenceToPackage(text, stripTypeParameters(el2.getText()));
+ }
+ else {
+ PsiElement element2 = ((PsiJavaReference)el2).resolve();
+
+ if (element2 != null) {
+ return text.equals(((PsiClass)element2).getQualifiedName());
+ }
+ else {
+ return MatchUtils.compareWithNoDifferenceToPackage(text, el2.getText());
+ }
+ }
+ }
+
+ private static String stripTypeParameters(String string) {
+ final int index = string.indexOf('<');
+ if (index == -1) {
+ return string;
+ }
+ return string.substring(0, index);
+ }
+
+ private boolean checkMatchWithingHierarchy(PsiElement el2, SubstitutionHandler handler, PsiElement context) {
+ boolean includeInterfaces = true;
+ boolean includeClasses = true;
+ final PsiElement contextParent = context.getParent();
+
+ if (contextParent instanceof PsiReferenceList) {
+ final PsiElement grandParentContext = contextParent.getParent();
+
+ if (grandParentContext instanceof PsiClass) {
+ final PsiClass psiClass = (PsiClass)grandParentContext;
+
+ if (contextParent == psiClass.getExtendsList()) {
+ includeInterfaces = psiClass.isInterface();
+ }
+ else if (contextParent == psiClass.getImplementsList()) {
+ includeClasses = false;
+ }
+ }
+ }
+
+ // is type2 is (strict) subtype of type
+ final NodeIterator node = new HierarchyNodeIterator(el2, includeClasses, includeInterfaces);
+
+ if (handler.isStrictSubtype()) {
+ node.advance();
+ }
+
+ final boolean notPredicate = handler.getPredicate() instanceof NotPredicate;
+ while (node.hasNext() && !handler.validate(node.current(), 0, -1, myMatchingVisitor.getMatchContext())) {
+ if (notPredicate) return false;
+ node.advance();
+ }
+
+ if (node.hasNext()) {
+ handler.addResult(el2, 0, -1, myMatchingVisitor.getMatchContext());
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ @Override
+ public void visitConditionalExpression(final PsiConditionalExpression cond) {
+ final PsiConditionalExpression cond2 = (PsiConditionalExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(cond.getCondition(), cond2.getCondition()) &&
+ myMatchingVisitor.matchSons(cond, cond2));
+ }
+
+ @Override
+ public void visitPolyadicExpression(PsiPolyadicExpression expression) {
+ PsiPolyadicExpression expr2 = (PsiPolyadicExpression)myMatchingVisitor.getElement();
+
+ boolean result = expression.getOperationTokenType().equals(expr2.getOperationTokenType());
+ if (result) {
+ PsiExpression[] operands1 = expression.getOperands();
+ PsiExpression[] operands2 = expr2.getOperands();
+ if (operands1.length != operands2.length) {
+ result = false;
+ }
+ else {
+ for (int i = 0; i < operands1.length; i++) {
+ PsiExpression e1 = operands1[i];
+ PsiExpression e2 = operands2[i];
+ if (!myMatchingVisitor.match(e1, e2)) {
+ result = false;
+ break;
+ }
+ }
+ }
+ }
+
+ myMatchingVisitor.setResult(result);
+ }
+
+ @Override
+ public void visitVariable(final PsiVariable var) {
+ myMatchingVisitor.getMatchContext().pushResult();
+ final PsiIdentifier nameIdentifier = var.getNameIdentifier();
+
+ boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(nameIdentifier);
+ boolean isTypedInitializer = var.getInitializer() != null &&
+ myMatchingVisitor.getMatchContext().getPattern().isTypedVar(var.getInitializer()) &&
+ var.getInitializer() instanceof PsiReferenceExpression;
+ final PsiVariable var2 = (PsiVariable)myMatchingVisitor.getElement();
+
+ try {
+ myMatchingVisitor.setResult((var.getName().equals(var2.getName()) || isTypedVar) &&
+ ((var.getParent() instanceof PsiClass && ((PsiClass)var.getParent()).isInterface()) ||
+ myMatchingVisitor.match(var.getModifierList(), var2.getModifierList())));
+ if (myMatchingVisitor.getResult()) {
+ final PsiTypeElement typeElement1 = var.getTypeElement();
+ if (typeElement1 != null) {
+ PsiTypeElement typeElement2 = var2.getTypeElement();
+ if (typeElement2 == null) {
+ typeElement2 = JavaPsiFacade.getElementFactory(var2.getProject()).createTypeElement(var2.getType());
+ }
+ myMatchingVisitor.setResult(myMatchingVisitor.match(typeElement1, typeElement2));
+ }
+ }
+
+ if (myMatchingVisitor.getResult()) {
+ // Check initializer
+ final PsiExpression var2Initializer = var2.getInitializer();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(var.getInitializer(), var2Initializer) ||
+ (isTypedInitializer &&
+ var2Initializer == null &&
+ allowsAbsenceOfMatch(var.getInitializer())
+ ));
+ }
+
+ if (myMatchingVisitor.getResult() && var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(
+ ((PsiCatchSection)var.getParent()).getCatchBlock(),
+ ((PsiCatchSection)var2.getParent()).getCatchBlock()
+ ));
+ }
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(nameIdentifier, var2.getNameIdentifier()));
+ }
+ }
+ finally {
+ saveOrDropResult(nameIdentifier, isTypedVar, var2.getNameIdentifier());
+ }
+ }
+
+ private void matchArrayDims(final PsiNewExpression new1, final PsiNewExpression new2) {
+ final PsiExpression[] arrayDims = new1.getArrayDimensions();
+ final PsiExpression[] arrayDims2 = new2.getArrayDimensions();
+
+ if (arrayDims.length == arrayDims2.length && arrayDims.length != 0) {
+ for (int i = 0; i < arrayDims.length; ++i) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(arrayDims[i], arrayDims2[i]));
+ if (!myMatchingVisitor.getResult()) return;
+ }
+ }
+ else {
+ myMatchingVisitor.setResult((arrayDims == arrayDims2) && myMatchingVisitor.matchSons(new1.getArgumentList(), new2.getArgumentList()));
+ }
+ }
+
+ private void saveOrDropResult(final PsiIdentifier methodNameNode, final boolean typedVar, final PsiIdentifier methodNameNode2) {
+ MatchResultImpl ourResult = myMatchingVisitor.getMatchContext().hasResult() ? myMatchingVisitor.getMatchContext().getResult() : null;
+ myMatchingVisitor.getMatchContext().popResult();
+
+ if (myMatchingVisitor.getResult()) {
+ if (typedVar) {
+ final SubstitutionHandler handler =
+ (SubstitutionHandler)myMatchingVisitor.getMatchContext().getPattern().getHandler(methodNameNode);
+ if (ourResult != null) ourResult.setScopeMatch(true);
+ handler.setNestedResult(ourResult);
+ myMatchingVisitor.setResult(handler.handle(methodNameNode2, myMatchingVisitor.getMatchContext()));
+
+ if (handler.getNestedResult() != null) { // some constraint prevent from adding
+ handler.setNestedResult(null);
+ copyResults(ourResult);
+ }
+ }
+ else if (ourResult != null) {
+ copyResults(ourResult);
+ }
+ }
+ }
+
+ private void matchImplicitQualifier(MatchingHandler matchingHandler, PsiElement target, MatchContext context) {
+ if (!(matchingHandler instanceof SubstitutionHandler)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ final SubstitutionHandler substitutionHandler = (SubstitutionHandler)matchingHandler;
+ final MatchPredicate predicate = substitutionHandler.getPredicate();
+ if (substitutionHandler.getMinOccurs() != 0) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ if (predicate == null) {
+ myMatchingVisitor.setResult(true);
+ return;
+ }
+ if (target == null) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ if (target instanceof PsiModifierListOwner && ((PsiModifierListOwner)target).hasModifierProperty(PsiModifier.STATIC)) {
+ myMatchingVisitor.setResult(predicate.match(null, PsiTreeUtil.getParentOfType(target, PsiClass.class), context));
+ } else {
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(target.getProject());
+ final PsiExpression implicitReference = factory.createExpressionFromText("this", target);
+ myMatchingVisitor.setResult(predicate.match(null, implicitReference, context));
+ }
+ }
+
+ @Override
+ public void visitMethodCallExpression(final PsiMethodCallExpression mcall) {
+ final PsiElement element = myMatchingVisitor.getElement();
+ if (!(element instanceof PsiMethodCallExpression)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ final PsiMethodCallExpression mcall2 = (PsiMethodCallExpression)element;
+ final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
+ final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
+
+ final String mcallname1 = mcallRef1.getReferenceName();
+ final String mcallname2 = mcallRef2.getReferenceName();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(mcallRef1.getReferenceNameElement());
+
+ if (mcallname1 != null && !mcallname1.equals(mcallname2) && !isTypedVar) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ final PsiExpression qualifier = mcallRef1.getQualifierExpression();
+ final PsiExpression elementQualifier = mcallRef2.getQualifierExpression();
+ if (qualifier != null) {
+
+ if (elementQualifier != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(qualifier, elementQualifier));
+ if (!myMatchingVisitor.getResult()) return;
+ }
+ else {
+ final PsiMethod method = mcall2.resolveMethod();
+ if (method != null) {
+ if (qualifier instanceof PsiThisExpression) {
+ myMatchingVisitor.setResult(!method.hasModifierProperty(PsiModifier.STATIC));
+ return;
+ }
+ }
+ final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(qualifier);
+ matchImplicitQualifier(handler, method, myMatchingVisitor.getMatchContext());
+ if (!myMatchingVisitor.getResult()) {
+ return;
+ }
+ }
+ }
+ else if (elementQualifier != null) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(mcall.getArgumentList(), mcall2.getArgumentList()));
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ boolean res = myMatchingVisitor.getResult();
+ res &= myMatchingVisitor.handleTypedElement(mcallRef1.getReferenceNameElement(), mcallRef2.getReferenceNameElement());
+ myMatchingVisitor.setResult(res);
+ }
+ }
+
+ @Override
+ public void visitExpressionStatement(final PsiExpressionStatement expr) {
+ final PsiExpressionStatement expr2 = (PsiExpressionStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(expr.getExpression(), expr2.getExpression()));
+ }
+
+ @Override
+ public void visitLiteralExpression(final PsiLiteralExpression const1) {
+ final PsiLiteralExpression const2 = (PsiLiteralExpression)myMatchingVisitor.getElement();
+
+ MatchingHandler handler = (MatchingHandler)const1.getUserData(CompiledPattern.HANDLER_KEY);
+
+ if (handler instanceof SubstitutionHandler) {
+ int offset = 0;
+ int length = const2.getTextLength();
+ final String text = const2.getText();
+
+ if (length > 2 && text.charAt(0) == '"' && text.charAt(length - 1) == '"') {
+ length--;
+ offset++;
+ }
+ myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(const2, offset, length, myMatchingVisitor.getMatchContext()));
+ }
+ else if (handler != null) {
+ myMatchingVisitor.setResult(handler.match(const1, const2, myMatchingVisitor.getMatchContext()));
+ }
+ else {
+ myMatchingVisitor.setResult(const1.textMatches(const2));
+ }
+ }
+
+ @Override
+ public void visitAssignmentExpression(final PsiAssignmentExpression assign) {
+ final PsiAssignmentExpression assign2 = (PsiAssignmentExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(assign.getOperationTokenType().equals(assign2.getOperationTokenType()) &&
+ myMatchingVisitor.match(assign.getLExpression(), assign2.getLExpression()) &&
+ myMatchingVisitor.match(assign.getRExpression(), assign2.getRExpression()));
+ }
+
+ @Override
+ public void visitIfStatement(final PsiIfStatement if1) {
+ final PsiIfStatement if2 = (PsiIfStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(if1.getCondition(), if2.getCondition()) &&
+ compareBody(if1.getThenBranch(), if2.getThenBranch()) &&
+ compareBody(if1.getElseBranch(), if2.getElseBranch()));
+ }
+
+ @Override
+ public void visitSwitchStatement(final PsiSwitchStatement switch1) {
+ final PsiSwitchStatement switch2 = (PsiSwitchStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(switch1.getExpression(), switch2.getExpression()) &&
+ myMatchingVisitor.matchSons(switch1.getBody(), switch2.getBody()));
+ }
+
+ @Override
+ public void visitForStatement(final PsiForStatement for1) {
+ final PsiForStatement for2 = (PsiForStatement)myMatchingVisitor.getElement();
+
+ final PsiStatement initialization = for1.getInitialization();
+ MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(initialization);
+
+ myMatchingVisitor.setResult(handler.match(initialization, for2.getInitialization(), myMatchingVisitor.getMatchContext()) &&
+ myMatchingVisitor.match(for1.getCondition(), for2.getCondition()) &&
+ myMatchingVisitor.match(for1.getUpdate(), for2.getUpdate()) &&
+ compareBody(for1.getBody(), for2.getBody()));
+ }
+
+ @Override
+ public void visitForeachStatement(PsiForeachStatement for1) {
+ final PsiForeachStatement for2 = (PsiForeachStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(for1.getIterationParameter(), for2.getIterationParameter()) &&
+ myMatchingVisitor.match(for1.getIteratedValue(), for2.getIteratedValue()) &&
+ compareBody(for1.getBody(), for2.getBody()));
+ }
+
+ @Override
+ public void visitWhileStatement(final PsiWhileStatement while1) {
+ final PsiWhileStatement while2 = (PsiWhileStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(while1.getCondition(), while2.getCondition()) &&
+ compareBody(while1.getBody(), while2.getBody()));
+ }
+
+ @Override
+ public void visitBlockStatement(final PsiBlockStatement block) {
+ if (myMatchingVisitor.getElement() instanceof PsiCodeBlock &&
+ !(myMatchingVisitor.getElement().getParent() instanceof PsiBlockStatement)
+ ) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(block.getCodeBlock(), myMatchingVisitor.getElement()));
+ }
+ else {
+ final PsiBlockStatement block2 = (PsiBlockStatement)myMatchingVisitor.getElement();
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(block, block2));
+ }
+ }
+
+ @Override
+ public void visitDeclarationStatement(final PsiDeclarationStatement dcl) {
+ final PsiDeclarationStatement declaration = (PsiDeclarationStatement)myMatchingVisitor.getElement();
+ myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(dcl.getDeclaredElements(), declaration.getDeclaredElements()));
+ }
+
+ @Override
+ public void visitDoWhileStatement(final PsiDoWhileStatement while1) {
+ final PsiDoWhileStatement while2 = (PsiDoWhileStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(while1.getCondition(), while2.getCondition()) &&
+ compareBody(while1.getBody(), while2.getBody()));
+ }
+
+ @Override
+ public void visitReturnStatement(final PsiReturnStatement return1) {
+ final PsiReturnStatement return2 = (PsiReturnStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(return1.getReturnValue(), return2.getReturnValue()));
+ }
+
+ @Override
+ public void visitPostfixExpression(final PsiPostfixExpression postfix) {
+ final PsiPostfixExpression postfix2 = (PsiPostfixExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(postfix.getOperationTokenType().equals(postfix2.getOperationTokenType())
+ && myMatchingVisitor.match(postfix.getOperand(), postfix2.getOperand()));
+ }
+
+ @Override
+ public void visitPrefixExpression(final PsiPrefixExpression prefix) {
+ final PsiPrefixExpression prefix2 = (PsiPrefixExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(prefix.getOperationTokenType().equals(prefix2.getOperationTokenType())
+ && myMatchingVisitor.match(prefix.getOperand(), prefix2.getOperand()));
+ }
+
+ @Override
+ public void visitAssertStatement(final PsiAssertStatement assert1) {
+ final PsiAssertStatement assert2 = (PsiAssertStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(assert1.getAssertCondition(), assert2.getAssertCondition()) &&
+ myMatchingVisitor.match(assert1.getAssertDescription(), assert2.getAssertDescription()));
+ }
+
+ @Override
+ public void visitBreakStatement(final PsiBreakStatement break1) {
+ final PsiBreakStatement break2 = (PsiBreakStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(break1.getLabelIdentifier(), break2.getLabelIdentifier()));
+ }
+
+ @Override
+ public void visitContinueStatement(final PsiContinueStatement continue1) {
+ final PsiContinueStatement continue2 = (PsiContinueStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(continue1.getLabelIdentifier(), continue2.getLabelIdentifier()));
+ }
+
+ @Override
+ public void visitSuperExpression(final PsiSuperExpression super1) {
+ myMatchingVisitor.setResult(true);
+ }
+
+ @Override
+ public void visitThisExpression(final PsiThisExpression this1) {
+ myMatchingVisitor.setResult(myMatchingVisitor.getElement() instanceof PsiThisExpression);
+ }
+
+ @Override
+ public void visitSynchronizedStatement(final PsiSynchronizedStatement synchronized1) {
+ final PsiSynchronizedStatement synchronized2 = (PsiSynchronizedStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(synchronized1.getLockExpression(), synchronized2.getLockExpression()) &&
+ myMatchingVisitor.matchSons(synchronized1.getBody(), synchronized2.getBody()));
+ }
+
+ @Override
+ public void visitThrowStatement(final PsiThrowStatement throw1) {
+ final PsiThrowStatement throw2 = (PsiThrowStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(throw1.getException(), throw2.getException()));
+ }
+
+ @Override
+ public void visitParenthesizedExpression(PsiParenthesizedExpression expr) {
+ if (myMatchingVisitor.getElement() instanceof PsiParenthesizedExpression) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(expr, myMatchingVisitor.getElement()));
+ }
+ else {
+ myMatchingVisitor.setResult(false);
+ }
+ }
+
+ @Override
+ public void visitCatchSection(final PsiCatchSection section) {
+ final PsiCatchSection section2 = (PsiCatchSection)myMatchingVisitor.getElement();
+ final PsiParameter parameter = section.getParameter();
+ if (parameter != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(parameter, section2.getParameter()));
+ }
+ else {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(section.getCatchBlock(), section2.getCatchBlock()));
+ }
+ }
+
+ @Override
+ public void visitTryStatement(final PsiTryStatement try1) {
+ final PsiTryStatement try2 = (PsiTryStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(try1.getTryBlock(), try2.getTryBlock()));
+
+ if (!myMatchingVisitor.getResult()) return;
+
+ final PsiResourceList resourceList1 = try1.getResourceList();
+ final PsiCatchSection[] catches1 = try1.getCatchSections();
+ final PsiCodeBlock finally1 = try1.getFinallyBlock();
+
+ final PsiResourceList resourceList2 = try2.getResourceList();
+ final PsiCatchSection[] catches2 = try2.getCatchSections();
+ final PsiCodeBlock finally2 = try2.getFinallyBlock();
+
+ final boolean looseMatching = myMatchingVisitor.getMatchContext().getOptions().isLooseMatching();
+ if (!looseMatching &&
+ ((catches1.length == 0 && catches2.length != 0) ||
+ (finally1 == null && finally2 != null) ||
+ (resourceList1 == null && resourceList2 != null))
+ ) {
+ myMatchingVisitor.setResult(false);
+ }
+ else {
+ if (resourceList1 != null) {
+ if (resourceList2 == null) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ final List<PsiResourceVariable> resourceVariables1 = resourceList1.getResourceVariables();
+ final List<PsiResourceVariable> resourceVariables2 = resourceList2.getResourceVariables();
+ myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(
+ resourceVariables1.toArray(new PsiResourceVariable[resourceVariables1.size()]),
+ resourceVariables2.toArray(new PsiResourceVariable[resourceVariables2.size()])));
+ if (!myMatchingVisitor.getResult()) return;
+ }
+
+ final List<PsiCatchSection> unmatchedCatchSections = new ArrayList<PsiCatchSection>();
+
+ ContainerUtil.addAll(unmatchedCatchSections, catches2);
+
+ for (int i = 0, j; i < catches1.length; ++i) {
+ MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(catches1[i]);
+ final PsiElement pinnedNode = handler.getPinnedNode(null);
+
+ if (pinnedNode != null) {
+ myMatchingVisitor.setResult(handler.match(catches1[i], pinnedNode, myMatchingVisitor.getMatchContext()));
+ if (!myMatchingVisitor.getResult()) return;
+ }
+ else {
+ for (j = 0; j < unmatchedCatchSections.size(); ++j) {
+ if (handler.match(catches1[i], unmatchedCatchSections.get(j), myMatchingVisitor.getMatchContext())) {
+ unmatchedCatchSections.remove(j);
+ break;
+ }
+ }
+
+ if (j == catches2.length) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+ }
+
+ if (finally1 != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(finally1, finally2));
+ }
+
+ if (myMatchingVisitor.getResult() && unmatchedCatchSections.size() > 0 && !looseMatching) {
+ try2.putUserData(UNMATCHED_CATCH_SECTION_CONTENT_VAR_KEY, unmatchedCatchSections);
+ }
+ }
+ }
+
+ @Override
+ public void visitSwitchLabelStatement(final PsiSwitchLabelStatement case1) {
+ final PsiSwitchLabelStatement case2 = (PsiSwitchLabelStatement)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(case1.isDefaultCase() == case2.isDefaultCase() &&
+ myMatchingVisitor.match(case1.getCaseValue(), case2.getCaseValue()));
+ }
+
+ @Override
+ public void visitInstanceOfExpression(final PsiInstanceOfExpression instanceOf) {
+ final PsiInstanceOfExpression instanceOf2 = (PsiInstanceOfExpression)myMatchingVisitor.getElement();
+ myMatchingVisitor.setResult(myMatchingVisitor.match(instanceOf.getOperand(), instanceOf2.getOperand()) &&
+ matchType(instanceOf.getCheckType(), instanceOf2.getCheckType()));
+ }
+
+ @Override
+ public void visitNewExpression(final PsiNewExpression new1) {
+ if (myMatchingVisitor.getElement() instanceof PsiArrayInitializerExpression &&
+ myMatchingVisitor.getElement().getParent() instanceof PsiVariable &&
+ new1.getArrayDimensions().length == 0 &&
+ new1.getArrayInitializer() != null
+ ) {
+ myMatchingVisitor.setResult(
+ myMatchingVisitor.match(new1.getClassReference(), ((PsiVariable)myMatchingVisitor.getElement().getParent()).getTypeElement()));
+ myMatchingVisitor.matchSons(new1.getArrayInitializer(), myMatchingVisitor.getElement());
+ return;
+ }
+
+ if (!(myMatchingVisitor.getElement() instanceof PsiNewExpression)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ final PsiNewExpression new2 = (PsiNewExpression)myMatchingVisitor.getElement();
+
+ if (new1.getClassReference() != null) {
+ if (new2.getClassReference() != null) {
+ myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), new2.getClassReference()) &&
+ myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
+
+ if (myMatchingVisitor.getResult()) {
+ // matching dims
+ matchArrayDims(new1, new2);
+ }
+ return;
+ }
+ else {
+ // match array of primitive by new 'T();
+ final PsiKeyword newKeyword = PsiTreeUtil.getChildOfType(new2, PsiKeyword.class);
+ final PsiElement element = PsiTreeUtil.getNextSiblingOfType(newKeyword, PsiWhiteSpace.class);
+
+ if (element != null && element.getNextSibling() instanceof PsiKeyword) {
+ ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true);
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), element.getNextSibling()) &&
+ myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
+
+ ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false);
+ if (myMatchingVisitor.getResult()) {
+ // matching dims
+ matchArrayDims(new1, new2);
+ }
+
+ return;
+ }
+ }
+ }
+
+ if (new1.getClassReference() == new2.getClassReference()) {
+ // probably anonymous class or array of primitive type
+ ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true);
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSons(new1, new2));
+ ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false);
+ }
+ else if (new1.getAnonymousClass() == null &&
+ new1.getClassReference() != null &&
+ new2.getAnonymousClass() != null) {
+ // allow matching anonymous class without pattern
+ myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), new2.getAnonymousClass().getBaseClassReference()) &&
+ myMatchingVisitor.matchSons(new1.getArgumentList(), new2.getArgumentList()));
+ }
+ else {
+ myMatchingVisitor.setResult(false);
+ }
+ }
+
+ @Override
+ public void visitKeyword(PsiKeyword keyword) {
+ myMatchingVisitor.setResult(keyword.textMatches(myMatchingVisitor.getElement()));
+ }
+
+ @Override
+ public void visitTypeCastExpression(final PsiTypeCastExpression cast) {
+ final PsiTypeCastExpression cast2 = (PsiTypeCastExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(cast.getCastType(), cast2.getCastType()) &&
+ myMatchingVisitor.match(cast.getOperand(), cast2.getOperand()));
+ }
+
+ @Override
+ public void visitClassObjectAccessExpression(final PsiClassObjectAccessExpression expr) {
+ final PsiClassObjectAccessExpression expr2 = (PsiClassObjectAccessExpression)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.setResult(myMatchingVisitor.match(expr.getOperand(), expr2.getOperand()));
+ }
+
+ @Override
+ public void visitReferenceElement(final PsiJavaCodeReferenceElement ref) {
+ myMatchingVisitor.setResult(matchType(ref, myMatchingVisitor.getElement()));
+ }
+
+ @Override
+ public void visitTypeElement(final PsiTypeElement typeElement) {
+ myMatchingVisitor.setResult(matchType(typeElement, myMatchingVisitor.getElement()));
+ }
+
+ @Override
+ public void visitTypeParameter(PsiTypeParameter psiTypeParameter) {
+ final PsiTypeParameter parameter = (PsiTypeParameter)myMatchingVisitor.getElement();
+ final PsiElement[] children = psiTypeParameter.getChildren();
+ final PsiElement[] children2 = parameter.getChildren();
+
+ final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(children[0]);
+
+ if (handler instanceof SubstitutionHandler) {
+ myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(children2[0], myMatchingVisitor.getMatchContext()));
+ }
+ else {
+ myMatchingVisitor.setResult(children[0].textMatches(children2[0]));
+ }
+
+ if (myMatchingVisitor.getResult() && children.length > 2) {
+ // constraint present
+ if (children2.length == 2) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ if (!children[2].getFirstChild().textMatches(children2[2].getFirstChild())) {
+ // constraint type (extends)
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(children[2].getChildren(), children2[2].getChildren()));
+ }
+ }
+
+ @Override
+ public void visitClass(PsiClass clazz) {
+ if (clazz.hasTypeParameters()) {
+ myMatchingVisitor
+ .setResult(
+ myMatchingVisitor.match(clazz.getTypeParameterList(), ((PsiClass)myMatchingVisitor.getElement()).getTypeParameterList()));
+
+ if (!myMatchingVisitor.getResult()) return;
+ }
+
+ PsiClass clazz2;
+
+ if (myMatchingVisitor.getElement() instanceof PsiDeclarationStatement &&
+ myMatchingVisitor.getElement().getFirstChild() instanceof PsiClass
+ ) {
+ clazz2 = (PsiClass)myMatchingVisitor.getElement().getFirstChild();
+ }
+ else {
+ clazz2 = (PsiClass)myMatchingVisitor.getElement();
+ }
+
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(clazz.getNameIdentifier());
+
+ if (clazz.getModifierList().getTextLength() > 0) {
+ if (!myMatchingVisitor.match(clazz.getModifierList(), clazz2.getModifierList())) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+ }
+
+ myMatchingVisitor.setResult((clazz.getName().equals(clazz2.getName()) || isTypedVar) &&
+ compareClasses(clazz, clazz2));
+
+ if (myMatchingVisitor.getResult() && isTypedVar) {
+ PsiElement id = clazz2.getNameIdentifier();
+ if (id == null) id = clazz2;
+ myMatchingVisitor.setResult(myMatchingVisitor.handleTypedElement(clazz.getNameIdentifier(), id));
+ }
+ }
+
+ @Override
+ public void visitTypeParameterList(PsiTypeParameterList psiTypeParameterList) {
+ myMatchingVisitor.setResult(myMatchingVisitor.matchSequentially(
+ psiTypeParameterList.getFirstChild(),
+ myMatchingVisitor.getElement().getFirstChild()
+ ));
+ }
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ final PsiIdentifier methodNameNode = method.getNameIdentifier();
+ final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(methodNameNode);
+ final PsiMethod method2 = (PsiMethod)myMatchingVisitor.getElement();
+
+ myMatchingVisitor.getMatchContext().pushResult();
+
+ try {
+ if (method.hasTypeParameters()) {
+ myMatchingVisitor.setResult(
+ myMatchingVisitor.match(method.getTypeParameterList(), ((PsiMethod)myMatchingVisitor.getElement()).getTypeParameterList()));
+
+ if (!myMatchingVisitor.getResult()) return;
+ }
+
+ if (!checkHierarchy(method2, method)) {
+ myMatchingVisitor.setResult(false);
+ return;
+ }
+
+ myMatchingVisitor.setResult((method.getName().equals(method2.getName()) || isTypedVar) &&
+ myMatchingVisitor.match(method.getModifierList(), method2.getModifierList()) &&
+ myMatchingVisitor.matchSons(method.getParameterList(), method2.getParameterList()) &&
+ myMatchingVisitor.match(method.getReturnTypeElement(), method2.getReturnTypeElement()) &&
+ matchInAnyOrder(method.getThrowsList(), method2.getThrowsList(), myMatchingVisitor) &&
+ myMatchingVisitor.matchSonsOptionally(method.getBody(), method2.getBody()));
+ }
+ finally {
+ final PsiIdentifier methodNameNode2 = method2.getNameIdentifier();
+
+ saveOrDropResult(methodNameNode, isTypedVar, methodNameNode2);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java
new file mode 100644
index 000000000000..271f1c468b0b
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/compiler/JavaCompilingVisitor.java
@@ -0,0 +1,589 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.psi.*;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.javadoc.PsiDocTag;
+import com.intellij.psi.search.*;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchVariableConstraint;
+import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.UnsupportedPatternException;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.JavaCompiledPattern;
+import com.intellij.structuralsearch.impl.matcher.filters.*;
+import com.intellij.structuralsearch.impl.matcher.handlers.*;
+import com.intellij.structuralsearch.impl.matcher.iterators.DocValuesIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.structuralsearch.impl.matcher.predicates.RegExpPredicate;
+import com.intellij.structuralsearch.impl.matcher.strategies.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
+ private final GlobalCompilingVisitor myCompilingVisitor;
+
+ @NonNls private static final String COMMENT = "\\s*(__\\$_\\w+)\\s*";
+ private static final Pattern ourPattern = Pattern.compile("//" + COMMENT, Pattern.DOTALL);
+ private static final Pattern ourPattern2 = Pattern.compile("/\\*" + COMMENT + "\\*/", Pattern.DOTALL);
+ private static final Pattern ourPattern3 = Pattern.compile("/\\*\\*" + COMMENT + "\\*/", Pattern.DOTALL);
+
+ public JavaCompilingVisitor(GlobalCompilingVisitor compilingVisitor) {
+ this.myCompilingVisitor = compilingVisitor;
+ }
+
+ @Override
+ public void visitDocTag(PsiDocTag psiDocTag) {
+ super.visitDocTag(psiDocTag);
+
+ NodeIterator sons = new DocValuesIterator(psiDocTag.getFirstChild());
+ while (sons.hasNext()) {
+ myCompilingVisitor.setHandler(sons.current(), new DocDataHandler());
+ sons.advance();
+ }
+ }
+
+ @Override
+ public void visitComment(PsiComment comment) {
+ super.visitComment(comment);
+
+ final String text = comment.getText();
+ Matcher matcher = ourPattern.matcher(text);
+ boolean matches = false;
+ if (!matcher.matches()) {
+ matcher = ourPattern2.matcher(text);
+
+ if (!matcher.matches()) {
+ matcher = ourPattern3.matcher(text);
+ }
+ else {
+ matches = true;
+ }
+ }
+ else {
+ matches = true;
+ }
+
+ if (matches || matcher.matches()) {
+ String str = matcher.group(1);
+ comment.putUserData(CompiledPattern.HANDLER_KEY, str);
+
+ GlobalCompilingVisitor.setFilter(
+ myCompilingVisitor.getContext().getPattern().getHandler(comment),
+ CommentFilter.getInstance()
+ );
+
+ SubstitutionHandler handler = (SubstitutionHandler)myCompilingVisitor.getContext().getPattern().getHandler(str);
+
+ if (handler.getPredicate() != null) {
+ ((RegExpPredicate)handler.getPredicate()).setMultiline(true);
+ }
+
+ RegExpPredicate predicate = MatchingHandler.getSimpleRegExpPredicate(handler);
+ if (GlobalCompilingVisitor.isSuitablePredicate(predicate, handler)) {
+ myCompilingVisitor.processTokenizedName(predicate.getRegExp(), true, GlobalCompilingVisitor.OccurenceKind.COMMENT);
+ }
+
+ matches = true;
+ }
+
+ if (!matches) {
+ MatchingHandler handler = myCompilingVisitor.processPatternStringWithFragments(text, GlobalCompilingVisitor.OccurenceKind.COMMENT);
+ if (handler != null) comment.putUserData(CompiledPattern.HANDLER_KEY, handler);
+ }
+ }
+
+ @Override
+ public void visitLiteralExpression(PsiLiteralExpression expression) {
+ String value = expression.getText();
+
+ if (value.length() > 2 && value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
+ @Nullable MatchingHandler handler =
+ myCompilingVisitor.processPatternStringWithFragments(value, GlobalCompilingVisitor.OccurenceKind.LITERAL);
+
+ if (handler != null) {
+ expression.putUserData(CompiledPattern.HANDLER_KEY, handler);
+ }
+ }
+ super.visitLiteralExpression(expression);
+ }
+
+ @Override
+ public void visitClassInitializer(final PsiClassInitializer initializer) {
+ super.visitClassInitializer(initializer);
+ PsiStatement[] psiStatements = initializer.getBody().getStatements();
+ if (psiStatements.length == 1 && psiStatements[0] instanceof PsiExpressionStatement) {
+ MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(psiStatements[0]);
+
+ if (handler instanceof SubstitutionHandler) {
+ myCompilingVisitor.getContext().getPattern().setHandler(initializer, new SubstitutionHandler((SubstitutionHandler)handler));
+ }
+ }
+ }
+
+ @Override
+ public void visitField(PsiField psiField) {
+ super.visitField(psiField);
+ CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
+ final MatchingHandler handler = pattern.getHandler(psiField);
+
+ if (needsSupers(psiField, handler)) {
+ assert pattern instanceof JavaCompiledPattern;
+ ((JavaCompiledPattern)pattern).setRequestsSuperFields(true);
+ }
+ }
+
+ @Override
+ public void visitMethod(PsiMethod psiMethod) {
+ super.visitMethod(psiMethod);
+ CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
+ final MatchingHandler handler = pattern.getHandler(psiMethod);
+
+ if (needsSupers(psiMethod, handler)) {
+ assert pattern instanceof JavaCompiledPattern;
+ ((JavaCompiledPattern)pattern).setRequestsSuperMethods(true);
+ }
+
+ GlobalCompilingVisitor.setFilter(handler, MethodFilter.getInstance());
+ handleReferenceText(psiMethod.getName(), myCompilingVisitor.getContext());
+ }
+
+ @Override
+ public void visitReferenceExpression(PsiReferenceExpression reference) {
+ visitElement(reference);
+
+ boolean typedVarProcessed = false;
+ final PsiElement referenceParent = reference.getParent();
+
+ if ((myCompilingVisitor.getContext().getPattern().isRealTypedVar(reference)) &&
+ reference.getQualifierExpression() == null &&
+ !(referenceParent instanceof PsiExpressionStatement)
+ ) {
+ // typed var for expression (but not top level)
+ MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(reference);
+ GlobalCompilingVisitor.setFilter(handler, ExpressionFilter.getInstance());
+ typedVarProcessed = true;
+ }
+
+ if (!(referenceParent instanceof PsiMethodCallExpression)) {
+ handleReference(reference);
+ }
+
+ MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(reference);
+
+ // We want to merge qname related to class to find it in any form
+ final String referencedName = reference.getReferenceName();
+
+ if (!typedVarProcessed &&
+ !(handler instanceof SubstitutionHandler)) {
+ final PsiElement resolve = reference.resolve();
+
+ PsiElement referenceQualifier = reference.getQualifier();
+ if (resolve instanceof PsiClass ||
+ (resolve == null &&
+ ((referencedName != null && Character.isUpperCase(referencedName.charAt(0))) ||
+ referenceQualifier == null
+ )
+ )
+ ) {
+ boolean hasNoNestedSubstitutionHandlers = false;
+ PsiExpression qualifier;
+ PsiReferenceExpression currentReference = reference;
+
+ while ((qualifier = currentReference.getQualifierExpression()) != null) {
+ if (!(qualifier instanceof PsiReferenceExpression) ||
+ myCompilingVisitor.getContext().getPattern().getHandler(qualifier) instanceof SubstitutionHandler
+ ) {
+ hasNoNestedSubstitutionHandlers = true;
+ break;
+ }
+ currentReference = (PsiReferenceExpression)qualifier;
+ }
+ if (!hasNoNestedSubstitutionHandlers) {
+ createAndSetSubstitutionHandlerFromReference(
+ reference,
+ resolve != null ? ((PsiClass)resolve).getQualifiedName() : reference.getText(),
+ referenceParent instanceof PsiExpression
+ );
+ }
+ }
+ else if (referenceQualifier != null && reference.getParent() instanceof PsiExpressionStatement) {
+ //Handler qualifierHandler = context.pattern.getHandler(referenceQualifier);
+ //if (qualifierHandler instanceof SubstitutionHandler &&
+ // !context.pattern.isRealTypedVar(reference)
+ // ) {
+ // createAndSetSubstitutionHandlerFromReference(reference, referencedName);
+ //
+ // SubstitutionHandler substitutionHandler = (SubstitutionHandler)qualifierHandler;
+ // RegExpPredicate expPredicate = Handler.getSimpleRegExpPredicate(substitutionHandler);
+ // //if (expPredicate != null)
+ // // substitutionHandler.setPredicate(new ExprTypePredicate(expPredicate.getRegExp(), null, true, true, false));
+ //}
+ }
+ }
+ }
+
+ @Override
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ handleReference(expression.getMethodExpression());
+ super.visitMethodCallExpression(expression);
+ }
+
+ @Override
+ public void visitBlockStatement(PsiBlockStatement psiBlockStatement) {
+ super.visitBlockStatement(psiBlockStatement);
+ myCompilingVisitor.getContext().getPattern().getHandler(psiBlockStatement).setFilter(BlockFilter.getInstance());
+ }
+
+ @Override
+ public void visitVariable(PsiVariable psiVariable) {
+ super.visitVariable(psiVariable);
+ myCompilingVisitor.getContext().getPattern().getHandler(psiVariable).setFilter(VariableFilter.getInstance());
+ handleReferenceText(psiVariable.getName(), myCompilingVisitor.getContext());
+ }
+
+ @Override
+ public void visitDeclarationStatement(PsiDeclarationStatement psiDeclarationStatement) {
+ super.visitDeclarationStatement(psiDeclarationStatement);
+
+ if (psiDeclarationStatement.getFirstChild() instanceof PsiTypeElement) {
+ // search for expression or symbol
+ final PsiJavaCodeReferenceElement reference =
+ ((PsiTypeElement)psiDeclarationStatement.getFirstChild()).getInnermostComponentReferenceElement();
+
+ if (reference != null &&
+ (myCompilingVisitor.getContext().getPattern().isRealTypedVar(reference.getReferenceNameElement())) &&
+ reference.getParameterList().getTypeParameterElements().length > 0
+ ) {
+ myCompilingVisitor.setHandler(psiDeclarationStatement, new TypedSymbolHandler());
+ final MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(psiDeclarationStatement);
+ // typed symbol
+ handler.setFilter(
+ TypedSymbolNodeFilter.getInstance()
+ );
+
+ final PsiTypeElement[] params = reference.getParameterList().getTypeParameterElements();
+ for (PsiTypeElement param : params) {
+ if (param.getInnermostComponentReferenceElement() != null &&
+ (myCompilingVisitor.getContext().getPattern().isRealTypedVar(
+ param.getInnermostComponentReferenceElement().getReferenceNameElement()))
+ ) {
+ myCompilingVisitor.getContext().getPattern().getHandler(param).setFilter(
+ TypeParameterFilter.getInstance()
+ );
+ }
+ }
+
+ return;
+ }
+ }
+
+ final MatchingHandler handler = new DeclarationStatementHandler();
+ myCompilingVisitor.getContext().getPattern().setHandler(psiDeclarationStatement, handler);
+ PsiElement previousNonWhiteSpace = psiDeclarationStatement.getPrevSibling();
+
+ while (previousNonWhiteSpace instanceof PsiWhiteSpace) {
+ previousNonWhiteSpace = previousNonWhiteSpace.getPrevSibling();
+ }
+
+ if (previousNonWhiteSpace instanceof PsiComment) {
+ ((DeclarationStatementHandler)handler)
+ .setCommentHandler(myCompilingVisitor.getContext().getPattern().getHandler(previousNonWhiteSpace));
+
+ myCompilingVisitor.getContext().getPattern().setHandler(
+ previousNonWhiteSpace,
+ handler
+ );
+ }
+
+ // detect typed symbol, it will have no variable
+ handler.setFilter(DeclarationFilter.getInstance());
+ }
+
+ @Override
+ public void visitDocComment(PsiDocComment psiDocComment) {
+ super.visitDocComment(psiDocComment);
+ myCompilingVisitor.getContext().getPattern().getHandler(psiDocComment).setFilter(JavaDocFilter.getInstance());
+ }
+
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
+ super.visitReferenceElement(reference);
+
+ if (reference.getParent() != null &&
+ reference.getParent().getParent() instanceof PsiClass) {
+ GlobalCompilingVisitor.setFilter(myCompilingVisitor.getContext().getPattern().getHandler(reference), TypeFilter.getInstance());
+ }
+
+ handleReference(reference);
+ }
+
+ @Override
+ public void visitClass(PsiClass psiClass) {
+ super.visitClass(psiClass);
+
+ CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
+ final MatchingHandler handler = pattern.getHandler(psiClass);
+
+ if (needsSupers(psiClass, handler)) {
+ ((JavaCompiledPattern)pattern).setRequestsSuperInners(true);
+ }
+ handleReferenceText(psiClass.getName(), myCompilingVisitor.getContext());
+
+ GlobalCompilingVisitor.setFilter(handler, ClassFilter.getInstance());
+
+ boolean hasSubstitutionHandler = false;
+ for (PsiElement element = psiClass.getFirstChild(); element != null; element = element.getNextSibling()) {
+ if (element instanceof PsiTypeElement && element.getNextSibling() instanceof PsiErrorElement) {
+ // found match that
+ MatchingHandler unmatchedSubstitutionHandler = pattern.getHandler(element);
+ if (unmatchedSubstitutionHandler != null) {
+ psiClass.putUserData(JavaCompiledPattern.ALL_CLASS_CONTENT_VAR_NAME_KEY, pattern.getTypedVarString(element));
+ hasSubstitutionHandler = true;
+ }
+ }
+ }
+
+ if (!hasSubstitutionHandler) {
+ String name = CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME;
+ psiClass.putUserData(JavaCompiledPattern.ALL_CLASS_CONTENT_VAR_NAME_KEY, name);
+ MatchOptions options = myCompilingVisitor.getContext().getOptions();
+ if (options.getVariableConstraint(name) == null) {
+ pattern.createSubstitutionHandler(name, name, false, 0, Integer.MAX_VALUE, true);
+ MatchVariableConstraint constraint = new MatchVariableConstraint(true);
+ constraint.setName(name);
+ constraint.setMinCount(0);
+ constraint.setMaxCount(Integer.MAX_VALUE);
+ options.addVariableConstraint(constraint);
+ }
+ }
+ }
+
+ private SubstitutionHandler createAndSetSubstitutionHandlerFromReference(final PsiElement expr, final String referenceText,
+ boolean classQualifier) {
+ final SubstitutionHandler substitutionHandler =
+ new SubstitutionHandler("__" + referenceText.replace('.', '_'), false, classQualifier ? 0 : 1, 1, false);
+ substitutionHandler.setPredicate(new RegExpPredicate(referenceText.replaceAll("\\.", "\\\\."), true, null, false, false));
+ myCompilingVisitor.getContext().getPattern().setHandler(expr, substitutionHandler);
+ return substitutionHandler;
+ }
+
+ @Override
+ public void visitExpressionStatement(PsiExpressionStatement expr) {
+ myCompilingVisitor.handle(expr);
+
+ super.visitExpressionStatement(expr);
+
+ final PsiElement child = expr.getLastChild();
+ if (!(child instanceof PsiJavaToken) && !(child instanceof PsiComment)) {
+ // search for expression or symbol
+ final PsiElement reference = expr.getFirstChild();
+ MatchingHandler referenceHandler = myCompilingVisitor.getContext().getPattern().getHandler(reference);
+
+ if (referenceHandler instanceof SubstitutionHandler &&
+ (reference instanceof PsiReferenceExpression)
+ ) {
+ // symbol
+ myCompilingVisitor.getContext().getPattern().setHandler(expr, referenceHandler);
+ referenceHandler.setFilter(
+ SymbolNodeFilter.getInstance()
+ );
+
+ myCompilingVisitor.setHandler(expr, new SymbolHandler((SubstitutionHandler)referenceHandler));
+ }
+ else if (reference instanceof PsiLiteralExpression) {
+ MatchingHandler handler = new ExpressionHandler();
+ myCompilingVisitor.setHandler(expr, handler);
+ handler.setFilter(ConstantFilter.getInstance());
+ }
+ else {
+ // just expression
+ MatchingHandler handler;
+ myCompilingVisitor.setHandler(expr, handler = new ExpressionHandler());
+
+ handler.setFilter(ExpressionFilter.getInstance());
+ }
+ }
+ else if (expr.getExpression() instanceof PsiReferenceExpression &&
+ (myCompilingVisitor.getContext().getPattern().isRealTypedVar(expr.getExpression()))) {
+ // search for statement
+ final MatchingHandler exprHandler = myCompilingVisitor.getContext().getPattern().getHandler(expr);
+ if (exprHandler instanceof SubstitutionHandler) {
+ SubstitutionHandler handler = (SubstitutionHandler)exprHandler;
+ handler.setFilter(new StatementFilter());
+ handler.setMatchHandler(new StatementHandler());
+ }
+ }
+ }
+
+ @Override
+ public void visitElement(PsiElement element) {
+ myCompilingVisitor.handle(element);
+ super.visitElement(element);
+ }
+
+
+ private void handleReference(PsiJavaCodeReferenceElement reference) {
+ handleReferenceText(reference.getReferenceName(), myCompilingVisitor.getContext());
+ }
+
+ private static void handleReferenceText(String refname, CompileContext compileContext) {
+ if (refname == null) return;
+
+ if (compileContext.getPattern().isTypedVar(refname)) {
+ SubstitutionHandler handler = (SubstitutionHandler)compileContext.getPattern().getHandler(refname);
+ RegExpPredicate predicate = MatchingHandler.getSimpleRegExpPredicate(handler);
+ if (!GlobalCompilingVisitor.isSuitablePredicate(predicate, handler)) {
+ return;
+ }
+
+ refname = predicate.getRegExp();
+
+ if (handler.isStrictSubtype() || handler.isSubtype()) {
+ final OptimizingSearchHelper searchHelper = compileContext.getSearchHelper();
+ if (addDescendantsOf(refname, handler.isSubtype(), searchHelper, compileContext)) {
+ searchHelper.endTransaction();
+ }
+
+ return;
+ }
+ }
+
+ GlobalCompilingVisitor.addFilesToSearchForGivenWord(refname, true, GlobalCompilingVisitor.OccurenceKind.CODE, compileContext);
+ }
+
+
+ public static boolean addDescendantsOf(final String refname, final boolean subtype, OptimizingSearchHelper searchHelper, CompileContext context) {
+ final List<PsiClass> classes = buildDescendants(refname, subtype, searchHelper, context);
+
+ for (final PsiClass aClass : classes) {
+ if (aClass instanceof PsiAnonymousClass) {
+ searchHelper.addWordToSearchInCode(((PsiAnonymousClass)aClass).getBaseClassReference().getReferenceName());
+ }
+ else {
+ searchHelper.addWordToSearchInCode(aClass.getName());
+ }
+ }
+
+ return classes.size() > 0;
+ }
+
+ private static List<PsiClass> buildDescendants(String className,
+ boolean includeSelf,
+ OptimizingSearchHelper searchHelper,
+ CompileContext context) {
+ if (!searchHelper.doOptimizing()) return Collections.emptyList();
+ final SearchScope scope = context.getOptions().getScope();
+ if (!(scope instanceof GlobalSearchScope)) return Collections.emptyList();
+
+ final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(context.getProject());
+ final PsiClass[] classes = cache.getClassesByName(className, (GlobalSearchScope)scope);
+ final List<PsiClass> results = new ArrayList<PsiClass>();
+
+ final PsiElementProcessor<PsiClass> processor = new PsiElementProcessor<PsiClass>() {
+ public boolean execute(@NotNull PsiClass element) {
+ results.add(element);
+ return true;
+ }
+
+ };
+
+ for (PsiClass aClass : classes) {
+ ClassInheritorsSearch.search(aClass, scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor));
+ }
+
+ if (includeSelf) {
+ Collections.addAll(results, classes);
+ }
+
+ return results;
+ }
+
+
+ @Override
+ public void visitCodeBlock(PsiCodeBlock block) {
+ myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() + 1);
+ MatchingStrategy strategy = null;
+
+ for (PsiElement el = block.getFirstChild(); el != null; el = el.getNextSibling()) {
+ if (GlobalCompilingVisitor.getFilter().accepts(el)) {
+ if (el instanceof PsiWhiteSpace) {
+ myCompilingVisitor.addLexicalNode(el);
+ }
+ }
+ else {
+ el.accept(this);
+ if (myCompilingVisitor.getCodeBlockLevel() == 1) {
+ MatchingStrategy newstrategy = findStrategy(el);
+ final MatchingHandler matchingHandler = myCompilingVisitor.getContext().getPattern().getHandler(el);
+ myCompilingVisitor.getContext().getPattern().setHandler(el, new TopLevelMatchingHandler(matchingHandler));
+
+ if (strategy == null || (strategy instanceof JavaDocMatchingStrategy)) {
+ strategy = newstrategy;
+ }
+ else {
+ if (strategy.getClass() != newstrategy.getClass()) {
+ if (!(strategy instanceof CommentMatchingStrategy)) {
+ throw new UnsupportedPatternException(SSRBundle.message("different.strategies.for.top.level.nodes.error.message"));
+ }
+ strategy = newstrategy;
+ }
+ }
+ }
+ }
+ }
+
+ if (myCompilingVisitor.getCodeBlockLevel() == 1) {
+ if (strategy == null) {
+ // this should happen only for error patterns
+ strategy = ExprMatchingStrategy.getInstance();
+ }
+ myCompilingVisitor.getContext().getPattern().setStrategy(strategy);
+ }
+ myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() - 1);
+ }
+
+ private MatchingStrategy findStrategy(PsiElement el) {
+ // identify matching strategy
+ final MatchingHandler handler = myCompilingVisitor.getContext().getPattern().getHandler(el);
+
+ //if (handler instanceof SubstitutionHandler) {
+ // final SubstitutionHandler shandler = (SubstitutionHandler) handler;
+ if (handler.getFilter() instanceof SymbolNodeFilter ||
+ handler.getFilter() instanceof TypedSymbolNodeFilter
+ ) {
+ return SymbolMatchingStrategy.getInstance();
+ }
+ //}
+
+ if (el instanceof PsiDocComment) {
+ return JavaDocMatchingStrategy.getInstance();
+ }
+ else if (el instanceof PsiComment) {
+ return CommentMatchingStrategy.getInstance();
+ }
+
+ return ExprMatchingStrategy.getInstance();
+ }
+
+ private static boolean needsSupers(final PsiElement element, final MatchingHandler handler) {
+ if (element.getParent() instanceof PsiClass &&
+ handler instanceof SubstitutionHandler
+ ) {
+ final SubstitutionHandler handler2 = (SubstitutionHandler)handler;
+
+ return (handler2.isStrictSubtype() || handler2.isSubtype());
+ }
+ return false;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/BlockFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/BlockFilter.java
new file mode 100644
index 000000000000..5cef7ffaf3c8
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/BlockFilter.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiBlockStatement;
+import com.intellij.psi.PsiCodeBlock;
+import com.intellij.psi.PsiElement;
+
+/**
+ * Filters block related nodes
+ */
+public class BlockFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+
+ @Override
+ public void visitBlockStatement(PsiBlockStatement psiBlockStatement) {
+ result = true;
+ }
+
+ @Override
+ public void visitCodeBlock(PsiCodeBlock psiCodeBlock) {
+ result = true;
+ }
+
+ private BlockFilter() {
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new BlockFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ClassFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ClassFilter.java
new file mode 100644
index 000000000000..6e68b08d70da
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ClassFilter.java
@@ -0,0 +1,43 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiAnonymousClass;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 26.12.2003
+ * Time: 19:37:13
+ * To change this template use Options | File Templates.
+ */
+public class ClassFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitAnonymousClass(PsiAnonymousClass psiAnonymousClass) {
+ result = true;
+ }
+
+ @Override public void visitClass(PsiClass psiClass) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new ClassFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private ClassFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/CommentFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/CommentFilter.java
new file mode 100644
index 000000000000..c2d974c9754e
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/CommentFilter.java
@@ -0,0 +1,48 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 22, 2004
+ * Time: 9:13:12 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class CommentFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitComment(PsiComment comment) {
+ result = true;
+ }
+
+ @Override public void visitField(PsiField field) {
+ result = true;
+ }
+
+ @Override public void visitMethod(PsiMethod method) {
+ result = true;
+ }
+
+ @Override public void visitClass(PsiClass clazz) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new CommentFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private CommentFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ConstantFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ConstantFilter.java
new file mode 100644
index 000000000000..401e3c15e365
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ConstantFilter.java
@@ -0,0 +1,38 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiLiteralExpression;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Apr 27, 2004
+ * Time: 7:55:40 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ConstantFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitLiteralExpression(PsiLiteralExpression psiLiteral) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new ConstantFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private ConstantFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/DeclarationFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/DeclarationFilter.java
new file mode 100644
index 000000000000..d5f5ef5bf36e
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/DeclarationFilter.java
@@ -0,0 +1,44 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 26.12.2003
+ * Time: 19:23:24
+ * To change this template use Options | File Templates.
+ */
+public class DeclarationFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitDeclarationStatement(PsiDeclarationStatement dcl) {
+ result = true;
+ }
+
+ @Override public void visitVariable(PsiVariable psiVar) {
+ result = true;
+ }
+
+ @Override public void visitClass(PsiClass psiClass) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new DeclarationFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private DeclarationFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ExpressionFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ExpressionFilter.java
new file mode 100644
index 000000000000..632cc403eabb
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/ExpressionFilter.java
@@ -0,0 +1,39 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiReferenceExpression;
+
+/**
+ * Filters expression nodes
+ */
+public class ExpressionFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) {
+ result = true;
+ }
+
+ @Override public void visitExpression(PsiExpression psiExpression) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new ExpressionFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private ExpressionFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaDocFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaDocFilter.java
new file mode 100644
index 000000000000..d12e9cbd0440
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaDocFilter.java
@@ -0,0 +1,33 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.PsiDocCommentOwner;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.javadoc.PsiDocComment;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 26.12.2003
+ * Time: 19:08:26
+ * To change this template use Options | File Templates.
+ */
+public class JavaDocFilter implements NodeFilter {
+ protected boolean result;
+
+ public boolean accepts(PsiElement element) {
+ return element instanceof PsiDocCommentOwner ||
+ element instanceof PsiDocComment;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new JavaDocFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private JavaDocFilter() {
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java
new file mode 100644
index 000000000000..1c86acda3e83
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java
@@ -0,0 +1,37 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.psi.*;
+import com.intellij.psi.javadoc.PsiDocComment;
+
+/**
+* @author Eugene.Kudelevsky
+*/
+public class JavaLexicalNodesFilter extends JavaElementVisitor {
+ private final LexicalNodesFilter myLexicalNodesFilter;
+
+ public JavaLexicalNodesFilter(LexicalNodesFilter lexicalNodesFilter) {
+ this.myLexicalNodesFilter = lexicalNodesFilter;
+ }
+
+ @Override public void visitJavaToken(final PsiJavaToken t) {
+ myLexicalNodesFilter.setResult(true);
+ }
+
+ @Override public void visitComment(final PsiComment comment) {
+ }
+
+ @Override public void visitDocComment(final PsiDocComment comment) {
+ }
+
+ @Override public void visitKeyword(PsiKeyword keyword) {
+ myLexicalNodesFilter.setResult(!myLexicalNodesFilter.isCareKeyWords());
+ }
+
+ @Override public void visitWhiteSpace(final PsiWhiteSpace space) {
+ myLexicalNodesFilter.setResult(true);
+ }
+
+ @Override public void visitErrorElement(final PsiErrorElement element) {
+ myLexicalNodesFilter.setResult(true);
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/MethodFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/MethodFilter.java
new file mode 100644
index 000000000000..00888bb86c5a
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/MethodFilter.java
@@ -0,0 +1,33 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * Filters method nodes
+ */
+public class MethodFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitMethod(PsiMethod psiMethod) {
+ result = true;
+ }
+
+ private MethodFilter() {}
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new MethodFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java
new file mode 100644
index 000000000000..91abc96139e1
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java
@@ -0,0 +1,33 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 26.12.2003
+ * Time: 17:46:10
+ * To change this template use Options | File Templates.
+ */
+public class StatementFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) {
+ result = false;
+ }
+
+ @Override public void visitStatement(PsiStatement psiStatement) {
+ result = true;
+ }
+
+ @Override public void visitComment(PsiComment comment) {
+ result = true;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/SymbolNodeFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/SymbolNodeFilter.java
new file mode 100644
index 000000000000..3e461b6738b6
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/SymbolNodeFilter.java
@@ -0,0 +1,72 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Tree filter for searching symbols ('T)
+ */
+public class SymbolNodeFilter extends JavaElementVisitor implements NodeFilter {
+ private boolean result;
+
+ @Override public void visitExpression(PsiExpression expr) {
+ result = true;
+ }
+
+ @Override public void visitLiteralExpression(PsiLiteralExpression psiLiteralExpression) {
+ result = true;
+ }
+
+ @Override public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) {
+ result = true;
+ }
+
+ @Override public void visitAnnotation(final PsiAnnotation annotation) {
+ result = true;
+ }
+
+ @Override public void visitAnnotationMethod(final PsiAnnotationMethod method) {
+ result = true;
+ }
+
+ @Override public void visitNameValuePair(final PsiNameValuePair pair) {
+ result = true;
+ }
+
+ @Override public void visitMethod(PsiMethod psiMethod) {
+ result = true;
+ }
+
+ @Override public void visitClass(PsiClass psiClass) {
+ result = true;
+ }
+
+ @Override public void visitReferenceElement(PsiJavaCodeReferenceElement psiJavaCodeReferenceElement) {
+ result = true;
+ }
+
+ @Override public void visitVariable(PsiVariable psiVar) {
+ result = true;
+ }
+
+ @Override public void visitTypeParameter(PsiTypeParameter psiTypeParameter) {
+ result = true;
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new SymbolNodeFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private SymbolNodeFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeFilter.java
new file mode 100644
index 000000000000..14dd452b0b7a
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeFilter.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiJavaCodeReferenceElement;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 23.01.2004
+ * Time: 1:07:09
+ * To change this template use File | Settings | File Templates.
+ */
+public class TypeFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitClass(PsiClass aClass) {
+ result = true;
+ }
+
+ @Override public void visitReferenceElement(PsiJavaCodeReferenceElement psiMethod) {
+ result = true;
+ }
+
+ private TypeFilter() {}
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new TypeFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeParameterFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeParameterFilter.java
new file mode 100644
index 000000000000..2f81c8b3980f
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypeParameterFilter.java
@@ -0,0 +1,43 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 03.01.2004
+ * Time: 1:06:23
+ * To change this template use Options | File Templates.
+ */
+public class TypeParameterFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ @Override public void visitTypeElement(PsiTypeElement psiTypeElement) {
+ result = true;
+ }
+
+ @Override public void visitTypeParameter(PsiTypeParameter psiTypeParameter) {
+ result = true;
+ }
+
+ @Override public void visitReferenceElement(PsiJavaCodeReferenceElement psiJavaCodeReferenceElement) {
+ result = true;
+ }
+
+ private TypeParameterFilter() {}
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new TypeParameterFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypedSymbolNodeFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypedSymbolNodeFilter.java
new file mode 100644
index 000000000000..4416b8b7db24
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/TypedSymbolNodeFilter.java
@@ -0,0 +1,44 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Filter for typed symbols
+ */
+public class TypedSymbolNodeFilter extends JavaElementVisitor implements NodeFilter {
+ private boolean result;
+
+ @Override public void visitMethod(PsiMethod psiMethod) {
+ result = psiMethod.hasTypeParameters();
+ }
+
+ @Override public void visitClass(PsiClass psiClass) {
+ result = psiClass.hasTypeParameters();
+ }
+
+ @Override public void visitReferenceElement(PsiJavaCodeReferenceElement psiJavaCodeReferenceElement) {
+ result = psiJavaCodeReferenceElement.getParameterList().getTypeParameterElements().length > 0;
+ }
+
+ @Override public void visitTypeParameter(PsiTypeParameter parameter) {
+ // we need this since TypeParameter instanceof PsiClass (?)
+ }
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new TypedSymbolNodeFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ private TypedSymbolNodeFilter() {
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/VariableFilter.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/VariableFilter.java
new file mode 100644
index 000000000000..e1907ecaf556
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/VariableFilter.java
@@ -0,0 +1,41 @@
+package com.intellij.structuralsearch.impl.matcher.filters;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReferenceExpression;
+import com.intellij.psi.PsiVariable;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 26.12.2003
+ * Time: 19:52:57
+ * To change this template use Options | File Templates.
+ */
+public class VariableFilter extends JavaElementVisitor implements NodeFilter {
+ protected boolean result;
+
+ public void visitReferenceExpression(final PsiReferenceExpression expression) {
+ }
+
+ @Override public void visitVariable(PsiVariable psiVariable) {
+ result = true;
+ }
+
+ private VariableFilter() {}
+
+ private static class NodeFilterHolder {
+ private static final NodeFilter instance = new VariableFilter();
+ }
+
+ public static NodeFilter getInstance() {
+ return NodeFilterHolder.instance;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DeclarationStatementHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DeclarationStatementHandler.java
new file mode 100644
index 000000000000..7342e96758f0
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DeclarationStatementHandler.java
@@ -0,0 +1,96 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
+import com.intellij.dupLocator.iterators.CountingNodeIterator;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim
+ * Date: 31.12.2004
+ * Time: 12:01:29
+ * To change this template use File | Settings | File Templates.
+ */
+public class DeclarationStatementHandler extends MatchingHandler {
+ private MatchingHandler myCommentHandler;
+
+ public boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context) {
+ if (patternNode instanceof PsiComment) {
+ //if (matchedNode instanceof PsiComment || matchedNode instanceof PsiClass || matchedNode instanceof PsiField)
+ return myCommentHandler.match(patternNode, matchedNode, context);
+ //return false;
+ }
+
+ if (!super.match(patternNode,matchedNode,context)) return false;
+ boolean result;
+ PsiDeclarationStatement dcl = (PsiDeclarationStatement)patternNode;
+
+ if (matchedNode instanceof PsiDeclarationStatement) {
+ result = GlobalMatchingVisitor.continueMatchingSequentially(
+ new SsrFilteringNodeIterator(patternNode.getFirstChild()),
+ new SsrFilteringNodeIterator(matchedNode.getFirstChild()),
+ context
+ );
+ } else {
+ final PsiElement[] declared = dcl.getDeclaredElements();
+
+ // declaration statement could wrap class or dcl
+ if (declared.length >0 &&
+ ( ( declared[0] instanceof PsiVariable && matchedNode instanceof PsiVariable) ||
+ ( declared[0] instanceof PsiClass && matchedNode instanceof PsiClass)
+ ) &&
+ !(matchedNode.getParent() instanceof PsiDeclarationStatement) // skip twice matching for child
+ ) {
+ result = GlobalMatchingVisitor.continueMatchingSequentially(
+ new ArrayBackedNodeIterator(declared),
+ new CountingNodeIterator(
+ declared.length,
+ new SsrFilteringNodeIterator(matchedNode)
+ ),
+ context
+ );
+
+ if (result &&
+ declared[0] instanceof PsiVariable && matchedNode instanceof PsiField
+ ) {
+ // we may have comments behind to match!
+ final PsiElement[] children = dcl.getChildren();
+
+ final PsiElement lastChild = children[children.length - 1];
+ if (lastChild instanceof PsiComment) {
+ final PsiElement[] fieldChildren = matchedNode.getChildren();
+
+ result = context.getPattern().getHandler(lastChild).match(
+ lastChild,
+ fieldChildren[fieldChildren.length-1],
+ context
+ );
+ }
+ }
+ } else {
+ result = false;
+ }
+ }
+
+ return result;
+ }
+
+ public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
+ if (patternElement instanceof PsiComment &&
+ ( matchedElement instanceof PsiField ||
+ matchedElement instanceof PsiClass
+ )
+ ) {
+ return false;
+ }
+
+ return super.shouldAdvanceTheMatchFor(patternElement,matchedElement);
+ }
+
+ public void setCommentHandler(final MatchingHandler commentHandler) {
+ myCommentHandler = commentHandler;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DocDataHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DocDataHandler.java
new file mode 100644
index 000000000000..dbc97ce67f75
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DocDataHandler.java
@@ -0,0 +1,70 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.JavaDocTokenType;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.javadoc.PsiDocTagValue;
+import com.intellij.psi.javadoc.PsiDocToken;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Handler for doc nodes
+ */
+public class DocDataHandler extends MatchingHandler {
+ @NonNls private static final String P_STR = "^\\s*((?:\\w|_|\\-|\\$)+)\\s*(?:=\\s*\"(.*)\"\\s*)?$";
+ private static final Pattern p = Pattern.compile(
+ P_STR,
+ Pattern.CASE_INSENSITIVE
+ );
+
+ public boolean match(PsiElement node, PsiElement match, MatchContext context) {
+ String text1 = node.getText();
+
+ text1 = getTextFromNode(node, text1);
+
+ Matcher m1 = p.matcher(text1);
+
+ String text2 = match.getText();
+ text2 = getTextFromNode(match, text2);
+
+ Matcher m2 = p.matcher(text2);
+
+ if (m1.matches() && m2.matches()) {
+ String name = m1.group(1);
+ String name2 = m2.group(1);
+ boolean isTypedName = context.getPattern().isTypedVar(name);
+
+ if (name.equals(name2) || isTypedName) {
+ String value = m1.group(2);
+ String value2 = m2.group(2);
+
+ if (value!=null) {
+ if (value2 == null || !value2.matches(value)) return false;
+ }
+ if (isTypedName) {
+ SubstitutionHandler handler = (SubstitutionHandler) context.getPattern().getHandler(name);
+ return handler.handle(match,context);
+ }
+ return true;
+ }
+ }
+ return text1.equals(text2);
+ }
+
+ // since doctag value may be inside doc comment we specially build text including skipped nodes
+ private static String getTextFromNode(final PsiElement node, String text1) {
+ PsiElement nextSibling = node.getNextSibling();
+ if (nextSibling instanceof PsiDocTagValue) {
+ text1 += nextSibling.getText();
+
+ nextSibling = nextSibling.getNextSibling();
+ if (nextSibling instanceof PsiDocToken && ((PsiDocToken)nextSibling).getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) {
+ text1 += nextSibling.getText();
+ }
+ }
+ return text1;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/ExpressionHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/ExpressionHandler.java
new file mode 100644
index 000000000000..6437c148dd0d
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/ExpressionHandler.java
@@ -0,0 +1,21 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpressionStatement;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Handler for substitution expression search
+ */
+public class ExpressionHandler extends MatchingHandler {
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ if (!super.match(patternNode,matchedNode,context)) {
+ return false;
+ }
+
+ return context.getMatcher().match(
+ ((PsiExpressionStatement)patternNode).getExpression(),
+ matchedNode
+ );
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/StatementHandler.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/StatementHandler.java
new file mode 100644
index 000000000000..c6361e2ad4e7
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/StatementHandler.java
@@ -0,0 +1,32 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+
+/**
+ * Handler for statement search
+ */
+public class StatementHandler extends MatchingHandler {
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ // filtering is done on SubstituionHandler level
+ if (patternNode==null) return false;
+ patternNode = ((PsiExpressionStatement)patternNode).getExpression();
+
+ /*if (matchedNode instanceof PsiExpressionStatement) {
+ //matchedNode = ((PsiExpressionStatement)matchedNode).getExpression();
+ } else*/ if (( !(matchedNode instanceof PsiStatement) &&
+ !(matchedNode instanceof PsiComment) // comments to be matched as statements
+ ) ||
+ ( matchedNode instanceof PsiBlockStatement &&
+ !(matchedNode.getParent() instanceof PsiBlockStatement) &&
+ !(matchedNode.getParent().getParent() instanceof PsiSwitchStatement)
+ )) {
+ // typed statement does not match this things
+ // (BlockStatement could be nontop level in if, etc)
+ return false;
+ }
+
+ return context.getMatcher().match(patternNode,matchedNode);
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/DocValuesIterator.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/DocValuesIterator.java
new file mode 100644
index 000000000000..c1323abd0951
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/DocValuesIterator.java
@@ -0,0 +1,64 @@
+package com.intellij.structuralsearch.impl.matcher.iterators;
+
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.psi.JavaDocTokenType;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.javadoc.PsiDocToken;
+import com.intellij.psi.javadoc.PsiDocTagValue;
+
+import java.util.ArrayList;
+
+/**
+ * Iterates over java doc values tag
+ */
+public class DocValuesIterator extends NodeIterator {
+ private int index;
+ private final ArrayList<PsiElement> tokens = new ArrayList<PsiElement>(2);
+ private static final IElementType tokenType = JavaDocTokenType.DOC_COMMENT_DATA;
+
+ public DocValuesIterator(PsiElement start) {
+ for(PsiElement e = start; e != null; e = e.getNextSibling()) {
+ if (e instanceof PsiDocTagValue) tokens.add(e);
+ else if (e instanceof PsiDocToken && ((PsiDocToken)e).getTokenType() == tokenType) {
+ tokens.add(e);
+ e = advanceToNext(e);
+ }
+ }
+ }
+
+ // since doctag value may be inside doc comment we specially skip that nodes from list
+ static PsiElement advanceToNext(PsiElement e) {
+ PsiElement nextSibling = e.getNextSibling();
+ if (nextSibling instanceof PsiDocTagValue) e = nextSibling;
+
+ nextSibling = e.getNextSibling();
+
+ if (nextSibling instanceof PsiDocToken &&
+ ((PsiDocToken)nextSibling).getTokenType() == tokenType
+ ) {
+ e = nextSibling;
+ }
+ return e;
+ }
+
+ public boolean hasNext() {
+ return index >=0 && index < tokens.size();
+ }
+
+ public PsiElement current() {
+ return hasNext() ? tokens.get(index) : null;
+ }
+
+ public void advance() {
+ if (index < tokens.size()) ++ index;
+ }
+
+ public void rewind() {
+ if (index >= 0) --index;
+ }
+
+ public void reset() {
+ index = 0;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/HierarchyNodeIterator.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/HierarchyNodeIterator.java
new file mode 100644
index 000000000000..324528435cb6
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/HierarchyNodeIterator.java
@@ -0,0 +1,128 @@
+package com.intellij.structuralsearch.impl.matcher.iterators;
+
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiClassImplUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Passes the hierarchy
+ */
+public class HierarchyNodeIterator extends NodeIterator {
+ private int index;
+ private ArrayList<PsiElement> remaining;
+ private boolean objectTaken;
+ private boolean firstElementTaken;
+ private final boolean acceptClasses;
+ private final boolean acceptInterfaces;
+ private final boolean acceptFirstElement;
+
+ private void build(PsiElement current, Set<PsiElement> visited) {
+
+ if (current!=null) {
+ final String str = current instanceof PsiClass ? ((PsiClass)current).getName():current.getText();
+
+ if (MatchUtils.compareWithNoDifferenceToPackage(str,"Object")) {
+ if(objectTaken) return;
+ objectTaken = true;
+ }
+
+ PsiElement element = MatchUtils.getReferencedElement(current);
+
+ if (element instanceof PsiClass) {
+ if (visited.contains(element)) return;
+ final PsiClass clazz = (PsiClass)element;
+
+ if (acceptInterfaces || !clazz.isInterface() ) visited.add(element);
+
+ if (!firstElementTaken && acceptFirstElement || firstElementTaken) remaining.add(clazz);
+ firstElementTaken = true;
+
+ if (clazz instanceof PsiAnonymousClass) {
+ build(((PsiAnonymousClass)clazz).getBaseClassReference(),visited);
+ return;
+ }
+
+ if (acceptClasses) {
+ processClasses(clazz, visited);
+
+ if (!objectTaken) {
+ build(PsiClassImplUtil.getSuperClass(clazz), visited);
+ }
+ }
+
+ if (acceptInterfaces) {
+ final PsiReferenceList implementsList = clazz.getImplementsList();
+
+ if (implementsList != null) {
+ final PsiElement[] implementsListElements = implementsList.getReferenceElements();
+
+ for (PsiElement anImplementsList : implementsListElements) {
+ build(anImplementsList,visited);
+ }
+ }
+
+ if (!acceptClasses) processClasses(clazz, visited);
+ }
+ } else {
+ remaining.add(current);
+ }
+ }
+ }
+
+ private void processClasses(final PsiClass clazz, final Set<PsiElement> visited) {
+ final PsiReferenceList clazzExtendsList = clazz.getExtendsList();
+ final PsiElement[] extendsList = (clazzExtendsList != null)?clazzExtendsList.getReferenceElements():null;
+
+ if (extendsList != null) {
+ for (PsiElement anExtendsList : extendsList) {
+ build(anExtendsList,visited);
+ }
+ }
+ }
+
+ public HierarchyNodeIterator(PsiElement reference, boolean acceptClasses, boolean acceptInterfaces) {
+ this(reference, acceptClasses, acceptInterfaces, true);
+ }
+
+ public HierarchyNodeIterator(PsiElement reference, boolean acceptClasses, boolean acceptInterfaces, boolean acceptFirstElement) {
+ remaining = new ArrayList<PsiElement>();
+ this.acceptClasses = acceptClasses;
+ this.acceptInterfaces = acceptInterfaces;
+ this.acceptFirstElement = acceptFirstElement;
+
+ if (reference instanceof PsiIdentifier) {
+ reference = reference.getParent();
+ }
+
+ build(reference,new HashSet<PsiElement>());
+ }
+
+ public boolean hasNext() {
+ return index < remaining.size();
+ }
+
+ public PsiElement current() {
+ return remaining.get(index);
+ }
+
+ public void advance() {
+ if (index!=remaining.size()) {
+ ++index;
+ }
+ }
+
+ public void rewind() {
+ if (index > 0) {
+ --index;
+ }
+ }
+
+ public void reset() {
+ index = 0;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java
new file mode 100644
index 000000000000..d66db76c272d
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ExprTypePredicate.java
@@ -0,0 +1,95 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator;
+import com.intellij.dupLocator.iterators.NodeIterator;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 23, 2004
+ * Time: 6:37:15 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class ExprTypePredicate extends MatchPredicate {
+ private final RegExpPredicate delegate;
+ private final boolean withinHierarchy;
+
+ public ExprTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch,boolean target) {
+ delegate = new RegExpPredicate(type,caseSensitiveMatch,baseName,false,target);
+ withinHierarchy = _withinHierarchy;
+ }
+
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ return match(patternNode, matchedNode, 0, -1, context);
+ }
+
+ public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) {
+ if (match instanceof PsiIdentifier) {
+ // since we pickup tokens
+ match = match.getParent();
+ }
+
+ if (match instanceof PsiExpression) {
+ final PsiType type = evalType((PsiExpression)match,context);
+ if (type==null) return false;
+
+ return doMatchWithTheType(type, context, match);
+ } else {
+ return false;
+ }
+ }
+
+ protected PsiType evalType(PsiExpression match, MatchContext context) {
+ PsiType type = null;
+
+ if (match instanceof PsiReferenceExpression &&
+ match.getParent() instanceof PsiMethodCallExpression) {
+ PsiMethod method = ((PsiMethodCallExpression)match.getParent()).resolveMethod();
+ if (method!=null) type = method.getReturnType();
+ }
+
+ if (type==null) type = match.getType();
+ return type;
+ }
+
+ private boolean doMatchWithTheType(final PsiType type, MatchContext context, PsiElement matchedNode) {
+ if (type instanceof PsiClassType) {
+ PsiClass clazz = ((PsiClassType)type).resolve();
+
+ if (clazz!=null) return checkClass(clazz, context);
+ }
+
+ if (type!=null) {
+ final String presentableText = type.getPresentableText();
+ boolean result = delegate.doMatch(presentableText,context, matchedNode);
+
+ if (!result && type instanceof PsiArrayType && ((PsiArrayType)type).getComponentType() instanceof PsiClassType) {
+ PsiClass clazz = ((PsiClassType)((PsiArrayType)type).getComponentType()).resolve();
+
+ if (clazz!=null) { // presentable text for array is not qualified!
+ result = delegate.doMatch(clazz.getQualifiedName()+"[]",context, matchedNode);
+ }
+ }
+ return result;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean checkClass(PsiClass clazz, MatchContext context) {
+ if (withinHierarchy) {
+ final NodeIterator parents = new HierarchyNodeIterator(clazz,true,true);
+
+ while(parents.hasNext() && !delegate.match(null,parents.current(),context)) {
+ parents.advance();
+ }
+
+ return parents.hasNext();
+ } else {
+ return delegate.match(null,clazz,context);
+ }
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/FormalArgTypePredicate.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/FormalArgTypePredicate.java
new file mode 100644
index 000000000000..02f1ee7d08e0
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/FormalArgTypePredicate.java
@@ -0,0 +1,38 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: Maxim.Mossienko
+ * Date: Mar 23, 2004
+ * Time: 6:37:15 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class FormalArgTypePredicate extends ExprTypePredicate {
+
+ public FormalArgTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch,boolean target) {
+ super(type, baseName, _withinHierarchy, caseSensitiveMatch, target);
+ }
+
+ protected PsiType evalType(PsiExpression match, MatchContext context) {
+ final PsiMethodCallExpression expr = PsiTreeUtil.getParentOfType(match,PsiMethodCallExpression.class);
+ if (expr == null) return null;
+
+ // find our parent in parameters of the method
+ final PsiMethod psiMethod = expr.resolveMethod();
+ if (psiMethod == null) return null;
+ final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters();
+ final PsiExpression[] expressions = expr.getArgumentList().getExpressions();
+
+ for(int i = 0;i < methodParameters.length; ++i) {
+ if (expressions[i] == match) {
+ if (i < methodParameters.length) return methodParameters[i].getType();
+ break;
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ReadPredicate.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ReadPredicate.java
new file mode 100644
index 000000000000..ce25b998ba9b
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/ReadPredicate.java
@@ -0,0 +1,28 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+
+/**
+ * Handler for value read
+ */
+public final class ReadPredicate extends MatchPredicate {
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ if (matchedNode instanceof PsiIdentifier) {
+ matchedNode = matchedNode.getParent();
+ }
+ if (matchedNode instanceof PsiReferenceExpression &&
+ ( !(matchedNode.getParent() instanceof PsiMethodCallExpression) &&
+ ( !(matchedNode.getParent() instanceof PsiAssignmentExpression) ||
+ ((PsiAssignmentExpression)matchedNode.getParent()).getLExpression() != matchedNode
+ )
+ ) &&
+ MatchUtils.getReferencedElement(matchedNode) instanceof PsiVariable
+ ) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/WritePredicate.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/WritePredicate.java
new file mode 100644
index 000000000000..e0d86824a920
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/predicates/WritePredicate.java
@@ -0,0 +1,33 @@
+package com.intellij.structuralsearch.impl.matcher.predicates;
+
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.MatchUtils;
+
+/**
+ * Handler for reading
+ */
+public final class WritePredicate extends MatchPredicate {
+ public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
+ if (matchedNode instanceof PsiIdentifier) {
+ matchedNode = matchedNode.getParent();
+ }
+ if (( matchedNode instanceof PsiReferenceExpression &&
+ matchedNode.getParent() instanceof PsiAssignmentExpression &&
+ ((PsiAssignmentExpression)matchedNode.getParent()).getLExpression() == matchedNode &&
+ MatchUtils.getReferencedElement(matchedNode) instanceof PsiVariable
+ ) ||
+ (
+ matchedNode instanceof PsiVariable &&
+ ((PsiVariable)matchedNode).getInitializer()!=null
+ ) ||
+ matchedNode.getParent() instanceof PsiPostfixExpression ||
+ matchedNode.getParent() instanceof PsiPrefixExpression
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/CommentMatchingStrategy.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/CommentMatchingStrategy.java
new file mode 100644
index 000000000000..7bba3250b768
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/CommentMatchingStrategy.java
@@ -0,0 +1,37 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassInitializer;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * Java doc matching strategy
+ */
+public final class CommentMatchingStrategy extends MatchingStrategyBase {
+ @Override public void visitClass(final PsiClass clazz) {
+ result = true;
+ }
+
+ @Override public void visitClassInitializer(final PsiClassInitializer clazzInit) {
+ result = true;
+ }
+
+ @Override public void visitMethod(final PsiMethod method) {
+ result = true;
+ }
+
+ @Override public void visitComment(final PsiComment comment) {
+ result = true;
+ }
+
+ private CommentMatchingStrategy() {}
+
+ private static class CommentMatchingStrategyHolder {
+ private static final CommentMatchingStrategy instance = new CommentMatchingStrategy();
+ }
+
+ public static MatchingStrategy getInstance() {
+ return CommentMatchingStrategyHolder.instance;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/ExprMatchingStrategy.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/ExprMatchingStrategy.java
new file mode 100644
index 000000000000..c892badb85be
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/ExprMatchingStrategy.java
@@ -0,0 +1,51 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.psi.*;
+
+/**
+ * Expression matching strategy
+ */
+public class ExprMatchingStrategy extends MatchingStrategyBase {
+ @Override public void visitExpression(final PsiExpression expr) {
+ result = true;
+ }
+
+ @Override public void visitVariable(final PsiVariable field) {
+ result = true;
+ }
+
+ @Override public void visitClass(final PsiClass clazz) {
+ result = true;
+ }
+
+ @Override public void visitClassInitializer(final PsiClassInitializer clazzInit) {
+ result = true;
+ }
+
+ @Override public void visitMethod(final PsiMethod method) {
+ result = true;
+ }
+
+ @Override public void visitExpressionList(final PsiExpressionList list) {
+ result = true;
+ }
+
+ @Override public void visitJavaFile(final PsiJavaFile file) {
+ result = true;
+ }
+
+ // finding parameters
+ @Override public void visitParameterList(final PsiParameterList list) {
+ result = true;
+ }
+
+ protected ExprMatchingStrategy() {}
+
+ private static class ExprMatchingStrategyHolder {
+ private static final ExprMatchingStrategy instance = new ExprMatchingStrategy();
+ }
+
+ public static MatchingStrategy getInstance() {
+ return ExprMatchingStrategyHolder.instance;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/JavaDocMatchingStrategy.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/JavaDocMatchingStrategy.java
new file mode 100644
index 000000000000..b65180eff650
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/JavaDocMatchingStrategy.java
@@ -0,0 +1,32 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassInitializer;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * Java doc matching strategy
+ */
+public final class JavaDocMatchingStrategy extends MatchingStrategyBase {
+ @Override public void visitClass(final PsiClass clazz) {
+ result = true;
+ }
+
+ @Override public void visitClassInitializer(final PsiClassInitializer clazzInit) {
+ result = true;
+ }
+
+ @Override public void visitMethod(final PsiMethod method) {
+ result = true;
+ }
+
+ private JavaDocMatchingStrategy() {}
+
+ private static class JavaDocMatchingStrategyHolder {
+ private static final JavaDocMatchingStrategy instance = new JavaDocMatchingStrategy();
+ }
+
+ public static MatchingStrategy getInstance() {
+ return JavaDocMatchingStrategyHolder.instance;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategyBase.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategyBase.java
new file mode 100644
index 000000000000..df6e0fd46832
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/MatchingStrategyBase.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.dupLocator.util.NodeFilter;
+import com.intellij.psi.*;
+
+/**
+ * Base filtering strategy to find statements
+ */
+public class MatchingStrategyBase extends JavaElementVisitor implements MatchingStrategy, NodeFilter {
+ protected boolean result;
+
+ @Override public void visitReferenceExpression(final PsiReferenceExpression psiReferenceExpression) {
+ visitExpression(psiReferenceExpression);
+ }
+
+ @Override public void visitCodeBlock(final PsiCodeBlock block) {
+ result = true;
+ }
+
+ @Override public void visitCatchSection(final PsiCatchSection section) {
+ result = true;
+ }
+
+ @Override public void visitStatement(final PsiStatement statement) {
+ result = true;
+ }
+
+ public boolean continueMatching(final PsiElement start) {
+ return accepts(start);
+ }
+
+ @Override
+ public boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
+ return false;
+ }
+
+ public boolean accepts(PsiElement element) {
+ result = false;
+ if (element!=null) element.accept(this);
+ return result;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/SymbolMatchingStrategy.java b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/SymbolMatchingStrategy.java
new file mode 100644
index 000000000000..f31ee37e8aed
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/strategies/SymbolMatchingStrategy.java
@@ -0,0 +1,54 @@
+package com.intellij.structuralsearch.impl.matcher.strategies;
+
+import com.intellij.psi.*;
+
+/**
+ * CommonStrategy to match symbols
+ */
+public class SymbolMatchingStrategy extends ExprMatchingStrategy {
+ @Override public void visitReferenceList(final PsiReferenceList list) {
+ result = true;
+ }
+
+ @Override public void visitAnnotation(final PsiAnnotation annotation) {
+ result = true;
+ }
+
+ @Override public void visitAnnotationParameterList(final PsiAnnotationParameterList list) {
+ result = true;
+ }
+
+ @Override public void visitModifierList(final PsiModifierList list) {
+ result = true;
+ }
+
+ @Override public void visitNameValuePair(final PsiNameValuePair pair) {
+ result = true;
+ }
+
+ @Override public void visitTypeParameterList(PsiTypeParameterList psiTypeParameterList) {
+ result = true;
+ }
+
+ @Override public void visitTypeElement(PsiTypeElement psiTypeElement) {
+ result = true;
+ }
+
+ @Override public void visitReferenceElement(PsiJavaCodeReferenceElement psiJavaCodeReferenceElement) {
+ result = true;
+ }
+
+ @Override public void visitReferenceParameterList(PsiReferenceParameterList psiReferenceParameterList) {
+ result = true;
+ }
+
+ private SymbolMatchingStrategy() {}
+
+ private static class SymbolMatchingStrategyHolder {
+ private static final SymbolMatchingStrategy instance = new SymbolMatchingStrategy();
+ }
+
+ public static MatchingStrategy getInstance() {
+ return SymbolMatchingStrategyHolder.instance;
+ }
+}
diff --git a/plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml b/plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml
new file mode 100644
index 000000000000..4b2ec18c28e6
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-java/structuralsearch-java.iml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="structuralsearch" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="java-impl" />
+ <orderEntry type="module" module-name="duplicates-analysis" />
+ </component>
+</module>
+
diff --git a/plugins/structuralsearch/structuralsearch-tests.iml b/plugins/structuralsearch/structuralsearch-tests.iml
new file mode 100644
index 000000000000..a05a995fe450
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch-tests.iml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$/testSource">
+ <sourceFolder url="file://$MODULE_DIR$/testSource" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="Groovy" level="project" />
+ <orderEntry type="module" module-name="structuralsearch" />
+ <orderEntry type="module" module-name="testFramework-java" />
+ <orderEntry type="module" module-name="xml" />
+ <orderEntry type="module" module-name="structuralsearch-java" />
+ <orderEntry type="module" module-name="java-i18n" />
+ </component>
+</module>
+
diff --git a/plugins/structuralsearch/structuralsearch.iml b/plugins/structuralsearch/structuralsearch.iml
new file mode 100644
index 000000000000..5bc64abd229c
--- /dev/null
+++ b/plugins/structuralsearch/structuralsearch.iml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="false" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/source" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
+ <orderEntry type="module" module-name="util" />
+ <orderEntry type="library" name="JDOM" level="project" />
+ <orderEntry type="library" name="Trove4j" level="project" />
+ <orderEntry type="module" module-name="xml" />
+ <orderEntry type="library" name="Groovy" level="project" />
+ <orderEntry type="module" module-name="platform-api" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="duplicates-analysis" />
+ <orderEntry type="module" module-name="lang-impl" />
+ </component>
+ <component name="copyright">
+ <Base>
+ <setting name="state" value="1" />
+ </Base>
+ </component>
+</module>
+
diff --git a/plugins/structuralsearch/testData/java/DoNotFindReturn.java b/plugins/structuralsearch/testData/java/DoNotFindReturn.java
new file mode 100644
index 000000000000..2a97989b7564
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/DoNotFindReturn.java
@@ -0,0 +1,43 @@
+class X {
+ void foo() {
+ boolean completed = JobUtil.invokeConcurrentlyUnderProgress(files, new Processor<VirtualFile>() {
+ public boolean process(final VirtualFile vfile) {
+ final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
+ public PsiFile compute() {
+ return myManager.findFile(vfile);
+ }
+ });
+ if (file != null && !(file instanceof PsiBinaryFile)) {
+ file.getViewProvider().getContents(); // load contents outside readaction
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ try {
+ PsiElement[] psiRoots = file.getPsiRoots();
+ Set<PsiElement> processed = new HashSet<PsiElement>(psiRoots.length * 2, (float)0.5);
+ for (PsiElement psiRoot : psiRoots) {
+ if (progress != null) progress.checkCanceled();
+ if (!processed.add(psiRoot)) continue;
+ if (!psiRootProcessor.process(psiRoot)) {
+ canceled.set(true);
+ return;
+ }
+ }
+ myManager.dropResolveCaches();
+ }
+ catch (ProcessCanceledException e) {
+ canceled.set(true);
+ pceThrown.set(true);
+ }
+ }
+ });
+ }
+ if (progress != null) {
+ double fraction = (double)counter.incrementAndGet() / size;
+ progress.setFraction(fraction);
+ }
+ return !canceled.get();
+ }
+ }, false, progress);
+
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_pattern.java b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_pattern.java
new file mode 100644
index 000000000000..1200d6f9624f
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_pattern.java
@@ -0,0 +1 @@
+assertTrue(StrictMath.abs('v1 - 'v2) < 't); \ No newline at end of file
diff --git a/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_replacement.java b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_replacement.java
new file mode 100644
index 000000000000..00a1012699b2
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_replacement.java
@@ -0,0 +1 @@
+java.util.List.assertEquals($v2$, $v1$, $t$); \ No newline at end of file
diff --git a/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_result.java b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_result.java
new file mode 100644
index 000000000000..2084a8da5075
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_result.java
@@ -0,0 +1,204 @@
+public class ForecastSummaryReportTest extends SOTestCase {
+ {
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ List.assertEquals(2, 1, 3);
+ }
+}
diff --git a/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_source.java b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_source.java
new file mode 100644
index 000000000000..edb15cbfa968
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/ReformatAndShortenClassRefPerformance_source.java
@@ -0,0 +1,204 @@
+public class ForecastSummaryReportTest extends SOTestCase {
+ {
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ assertTrue(StrictMath.abs(1 - 2) < 3);
+ }
+}
diff --git a/plugins/structuralsearch/testData/java/after1.java b/plugins/structuralsearch/testData/java/after1.java
new file mode 100644
index 000000000000..156cc38f997a
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/after1.java
@@ -0,0 +1,82 @@
+/*
+ * Created on Jan 30, 2004
+ *
+ */
+package somepackage;
+
+/**
+ * Title: ForecastSummaryReportTest
+ */
+public class ForecastSummaryReportTest extends SOTestCase {
+
+ ForecastSummaryReport oReport = null;
+ ScheduleGroupData oSkdgrp = null;
+ SODate oStart = null;
+ SODate oEnd = null;
+ SODateInterval oDateRange = null;
+
+
+ /**
+ * Constructor for ForecastSummaryReportTest.
+ *
+ * @param arg0
+ */
+ public ForecastSummaryReportTest(String arg0) {
+ super(arg0);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(ForecastSummaryReportTest.class);
+ }
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ oSkdgrp = ScheduleGroupData.getScheduleGroupData(new Integer(1001));
+ oDateRange = new SODateInterval(new SODate("01/23/2004"), new SODate("01/30/2004"));
+ oReport = new ForecastSummaryReport(oSkdgrp.getCorporateEntity(), oDateRange);
+ } catch (Exception e) {
+ System.out.println("Unhandled exception in Setup:" + e);
+ fail();
+ }
+
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ oReport = null;
+ }
+
+ public void testForecastSummaryReport() {
+ try {
+ ForecastSummaryReport testReport = new ForecastSummaryReport(oSkdgrp.getCorporateEntity(), oDateRange);
+ assertNotNull(testReport);
+ } catch (RetailException e) {
+ e.printStackTrace();
+ fail("RetailException: Could not create ForecastSummaryReport(CorporateEntity, SODateInterval)");
+ }
+ }
+
+ public void testSetIncludeSublocationsFlag() {
+ oReport.setIncludeSublocationsFlag(true);
+ assertTrue(oReport.isIncludeSublocationsFlagSet());
+ }
+
+ public void testIsIncludeSublocationsFlagSet() {
+ oReport.setIncludeSublocationsFlag(false);
+ assertFalse(oReport.isIncludeSublocationsFlagSet());
+ oReport.setIncludeSublocationsFlag(true);
+ assertTrue(oReport.isIncludeSublocationsFlagSet());
+ }
+
+ public void testRefresh() throws RetailException {
+ oReport.refresh();
+ assertNotNull(oReport);
+ }
+}
diff --git a/plugins/structuralsearch/testData/java/after2.java b/plugins/structuralsearch/testData/java/after2.java
new file mode 100644
index 000000000000..20974011a39b
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/after2.java
@@ -0,0 +1,11 @@
+public class Test {
+ int a;
+ @Override public void aaa() {}
+ int b;
+ @Override void aaa2() {}
+ int c;
+ @Override public void aaa3() {}
+ int d;
+ @Override void aaa4() {}
+ int e;
+}
diff --git a/plugins/structuralsearch/testData/java/before1.java b/plugins/structuralsearch/testData/java/before1.java
new file mode 100644
index 000000000000..948dc10eb3d8
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/before1.java
@@ -0,0 +1,89 @@
+/*
+ * Created on Jan 30, 2004
+ *
+ */
+package somepackage;
+
+/**
+ * Title: ForecastSummaryReportTest
+ *
+ *
+ */
+public class ForecastSummaryReportTest extends SOTestCase {
+
+ ForecastSummaryReport oReport = null;
+ ScheduleGroupData oSkdgrp = null;
+ SODate oStart = null;
+ SODate oEnd = null;
+ SODateInterval oDateRange = null;
+
+
+ /**
+ * Constructor for ForecastSummaryReportTest.
+ * @param arg0
+ */
+ public ForecastSummaryReportTest(String arg0) {
+ super(arg0);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(ForecastSummaryReportTest.class);
+ }
+
+ /*
+ * @see TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+ oSkdgrp = ScheduleGroupData.getScheduleGroupData(new Integer(1001));
+ oDateRange = new SODateInterval(new SODate("01/23/2004"), new SODate("01/30/2004"));
+ oReport = new ForecastSummaryReport(oSkdgrp.getCorporateEntity(),oDateRange);
+ } catch (Exception e) {
+ System.out.println("Unhandled exception in Setup:" + e);
+ fail();
+ }
+
+ }
+
+ /*
+ * @see TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ oReport = null;
+ }
+
+ /*
+ * Cannot test protected methods from this location
+ */
+ public void testGenerate() {
+ }
+
+ public void testForecastSummaryReport() {
+ try {
+ ForecastSummaryReport testReport = new ForecastSummaryReport(oSkdgrp.getCorporateEntity(),oDateRange);
+ assertNotNull(testReport);
+ } catch (RetailException e) {
+ e.printStackTrace();
+ fail("RetailException: Could not create ForecastSummaryReport(CorporateEntity, SODateInterval)");
+ }
+ }
+
+ public void testSetIncludeSublocationsFlag() {
+ oReport.setIncludeSublocationsFlag(true);
+ assertTrue(oReport.isIncludeSublocationsFlagSet());
+ }
+
+ public void testIsIncludeSublocationsFlagSet() {
+ oReport.setIncludeSublocationsFlag(false);
+ assertFalse(oReport.isIncludeSublocationsFlagSet());
+ oReport.setIncludeSublocationsFlag(true);
+ assertTrue(oReport.isIncludeSublocationsFlagSet());
+ }
+
+ public void testRefresh() throws RetailException {
+ oReport.refresh();
+ assertNotNull(oReport);
+ }
+}
diff --git a/plugins/structuralsearch/testData/java/before2.java b/plugins/structuralsearch/testData/java/before2.java
new file mode 100644
index 000000000000..371bbb3cbe30
--- /dev/null
+++ b/plugins/structuralsearch/testData/java/before2.java
@@ -0,0 +1,19 @@
+public class Test {
+ int a;
+ public void aaa() {
+ int field;
+ }
+ int b;
+ void aaa2() {
+ int field2;
+ }
+ int c;
+ public void aaa3() {
+ int field3;
+ }
+ int d;
+ void aaa4() {
+ int field4;
+ }
+ int e;
+}
diff --git a/plugins/structuralsearch/testData/ssBased/ExpressionStatement.java b/plugins/structuralsearch/testData/ssBased/ExpressionStatement.java
new file mode 100644
index 000000000000..383f6d8a484c
--- /dev/null
+++ b/plugins/structuralsearch/testData/ssBased/ExpressionStatement.java
@@ -0,0 +1,8 @@
+import java.io.File;
+import java.io.IOException;
+
+class Test{
+ void foo() throws IOException {
+ File f = <warning descr="Forbid File.createTempFile">File.createTempFile("", "")</warning>;
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/testData/ssBased/TwoStatementPattern.java b/plugins/structuralsearch/testData/ssBased/TwoStatementPattern.java
new file mode 100644
index 000000000000..e41879cd2f62
--- /dev/null
+++ b/plugins/structuralsearch/testData/ssBased/TwoStatementPattern.java
@@ -0,0 +1,13 @@
+class Scratch {
+
+ private String s = null;
+
+ void foo() {
+ s = "1";
+ <warning descr="silly null check">s = "2";</warning>
+ if (s == null) {
+ throw new IllegalStateException("drunk");
+ }
+ }
+
+}
diff --git a/plugins/structuralsearch/testData/ssBased/simple/expected.xml b/plugins/structuralsearch/testData/ssBased/simple/expected.xml
new file mode 100644
index 000000000000..f2a97d264f8e
--- /dev/null
+++ b/plugins/structuralsearch/testData/ssBased/simple/expected.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+
+ <problem>
+ <file>X.java</file>
+ <line>5</line>
+ <problem_class>Structural Search Inspection</problem_class>
+ <description />
+ </problem>
+
+ <problem>
+ <file>X.java</file>
+ <line>7</line>
+ <problem_class>Structural Search Inspection</problem_class>
+ <description />
+ </problem>
+
+</problems> \ No newline at end of file
diff --git a/plugins/structuralsearch/testData/ssBased/simple/src/x/X.java b/plugins/structuralsearch/testData/ssBased/simple/src/x/X.java
new file mode 100644
index 000000000000..3f5dc2f67974
--- /dev/null
+++ b/plugins/structuralsearch/testData/ssBased/simple/src/x/X.java
@@ -0,0 +1,10 @@
+package x;
+
+class S {
+ public void f() {
+ int i;
+ int j;
+ f();
+ int k;
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java
new file mode 100644
index 000000000000..f17c45bfcf3d
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/OptimizedSearchScanTest.java
@@ -0,0 +1,22 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
+import com.intellij.idea.Bombed;
+
+import java.util.Calendar;
+
+/**
+ * @author Maxim.Mossienko
+ */
+@Bombed(day = 28, description = "support it", month = Calendar.JULY, user = "maxim.mossienko")
+public abstract class OptimizedSearchScanTest extends StructuralSearchTestCase {
+ public void _testClassByQName() throws Exception {
+ String plan = findWordsToBeUsedWhenSearchingFor("A.f");
+ assertEquals("[in code:f]", plan);
+ }
+
+ private String findWordsToBeUsedWhenSearchingFor(final String s) {
+ findMatchesCount("{}",s);
+ return PatternCompiler.getLastFindPlan();
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java
new file mode 100644
index 000000000000..7971c1009fbd
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSBasedInspectionTest.java
@@ -0,0 +1,47 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspection;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchConfiguration;
+import com.intellij.testFramework.InspectionTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SSBasedInspectionTest extends InspectionTestCase {
+ private LocalInspectionToolWrapper myWrapper;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ SSBasedInspection inspection = new SSBasedInspection();
+ List<Configuration> configurations = new ArrayList<Configuration>();
+ SearchConfiguration configuration = new SearchConfiguration();
+ MatchOptions options = new MatchOptions();
+ options.setSearchPattern("int i;");
+ configuration.setMatchOptions(options);
+ configurations.add(configuration);
+ configuration = new SearchConfiguration();
+ options = new MatchOptions();
+ options.setSearchPattern("f();");
+ configuration.setMatchOptions(options);
+ configurations.add(configuration);
+ inspection.setConfigurations(configurations, myProject);
+ inspection.projectOpened(getProject());
+ myWrapper = new LocalInspectionToolWrapper(inspection);
+ }
+
+ public void testSimple() throws Exception {
+ doTest();
+ }
+
+ private void doTest() throws Exception {
+ doTest("ssBased/" + getTestName(true), myWrapper,"java 1.5");
+ }
+
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("structuralsearch") + "/testData";
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java
new file mode 100644
index 000000000000..5031f821c581
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/SSRCodeInsightTest.java
@@ -0,0 +1,75 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.structuralsearch.inspection.highlightTemplate.SSBasedInspection;
+import com.intellij.structuralsearch.plugin.ui.Configuration;
+import com.intellij.structuralsearch.plugin.ui.SearchConfiguration;
+import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.fixtures.*;
+import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
+
+import java.util.Collections;
+
+public class SSRCodeInsightTest extends UsefulTestCase {
+ protected CodeInsightTestFixture myFixture;
+ private SSBasedInspection myInspection;
+
+ public SSRCodeInsightTest() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();
+ TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(new DefaultLightProjectDescriptor());
+ final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture();
+ myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture,
+ new LightTempDirTestFixtureImpl(true));
+ myInspection = new SSBasedInspection();
+ myFixture.enableInspections(myInspection);
+ myFixture.setUp();
+ myFixture.setTestDataPath(getTestDataPath());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myFixture.tearDown();
+ myFixture = null;
+ myInspection = null;
+ super.tearDown();
+ }
+
+ public void testExpressionStatement() {
+ doTest("File.createTempFile($p1$, $p2$)", "Forbid File.createTempFile");
+ }
+
+ public void testTwoStatementPattern() {
+ doTest("$field$ = $something$;\n" +
+ "if ($field$ == null) {\n" +
+ " throw new $Exception$($msg$);\n" +
+ "}",
+ "silly null check");
+ }
+
+ private void doTest(final String searchPattern, final String patternName) {
+ final SearchConfiguration configuration = new SearchConfiguration();
+ //display name
+ configuration.setName(patternName);
+
+ //search pattern
+ final MatchOptions options = new MatchOptions();
+ options.setSearchPattern(searchPattern);
+ configuration.setMatchOptions(options);
+
+ myInspection.setConfigurations(Collections.<Configuration>singletonList(configuration), myFixture.getProject());
+ myInspection.projectOpened(myFixture.getProject());
+
+ myFixture.testHighlighting(true, false, false, getTestName(false) + ".java");
+ }
+
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("structuralsearch") + "/testData/ssBased";
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java
new file mode 100644
index 000000000000..d5848b611867
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java
@@ -0,0 +1,2133 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.psi.CommonClassNames;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.util.ThrowableRunnable;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+
+/**
+ * @by Maxim.Mossienko
+ */
+@SuppressWarnings({"ALL"})
+public class StructuralReplaceTest extends StructuralReplaceTestCase {
+ public void testReplaceInLiterals() {
+ String s1 = "String ID_SPEED = \"Speed\";";
+ String s2 = "String 'name = \"'string\";";
+ String s2_2 = "String 'name = \"'string:[regex( .* )]\";";
+ String s3 = "VSegAttribute $name$ = new VSegAttribute(\"$string$\");";
+ String expectedResult = "VSegAttribute ID_SPEED = new VSegAttribute(\"Speed\");";
+
+ String actualResult = replacer.testReplace(s1,s2,s3,options);
+ assertEquals(
+ "Matching/replacing literals",
+ expectedResult,
+ actualResult
+ );
+
+ actualResult = replacer.testReplace(s1,s2_2,s3,options);
+ assertEquals(
+ "Matching/replacing literals",
+ expectedResult,
+ actualResult
+ );
+
+ String s4 = "params.put(\"BACKGROUND\", \"#7B528D\");";
+ String s5 = "params.put(\"$FieldName$\", \"#$exp$\");";
+ String s6 = "String $FieldName$ = \"$FieldName$\";\n" +
+ "params.put($FieldName$, \"$exp$\");";
+ String expectedResult2 = "String BACKGROUND = \"BACKGROUND\";\n" +
+ "params.put(BACKGROUND, \"7B528D\");";
+
+ actualResult = replacer.testReplace(s4,s5,s6,options);
+
+ assertEquals(
+ "string literal replacement 2",
+ expectedResult2,
+ actualResult
+ );
+
+ String s7 = "IconLoader.getIcon(\"/ant/property.png\");\n" +
+ "IconLoader.getIcon(\"/ant/another/property.png\");\n";
+ String s8 = "IconLoader.getIcon(\"/'module/'name:[regex( \\w+ )].png\");";
+ String s9 = "Icons.$module$.$name$;";
+ String expectedResult3 = "Icons.ant.property;\n" +
+ "IconLoader.getIcon(\"/ant/another/property.png\");\n";
+
+ actualResult = replacer.testReplace(s7,s8,s9,options);
+
+ assertEquals(
+ "string literal replacement 3",
+ expectedResult3,
+ actualResult
+ );
+
+ String s10 = "configureByFile(path + \"1.html\");\n" +
+ " checkResultByFile(path + \"1_after.html\");\n" +
+ " checkResultByFile(path + \"1_after2.html\");\n" +
+ " checkResultByFile(path + \"1_after3.html\");";
+ String s11 = "\"'a.html\"";
+ String s12 = "\"$a$.\"+ext";
+ String expectedResult4 = "configureByFile(path + \"1.\"+ext);\n" +
+ " checkResultByFile(path + \"1_after.\"+ext);\n" +
+ " checkResultByFile(path + \"1_after2.\"+ext);\n" +
+ " checkResultByFile(path + \"1_after3.\"+ext);";
+
+ actualResult = replacer.testReplace(s10,s11,s12,options);
+ assertEquals(
+ "string literal replacement 4",
+ expectedResult4,
+ actualResult
+ );
+ }
+
+ public void testReplace2() {
+ String s1 = "package com.www.xxx.yyy;\n" +
+ "\n" +
+ "import javax.swing.*;\n" +
+ "\n" +
+ "public class Test {\n" +
+ " public static void main(String[] args) {\n" +
+ " if (1==1)\n" +
+ " JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" +
+ " }\n" +
+ "}";
+ String s2 = "JOptionPane.'showDialog(null, 'msg);";
+ String s3 = "//FIXME provide a parent frame\n" +
+ "JOptionPane.$showDialog$(null, $msg$);";
+
+ String expectedResult = "package com.www.xxx.yyy;\n" +
+ "\n" +
+ "import javax.swing.*;\n" +
+ "\n" +
+ "public class Test {\n" +
+ " public static void main(String[] args) {\n" +
+ " if (1==1)\n" +
+ " //FIXME provide a parent frame\n" +
+ "JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" +
+ " }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+ assertEquals(
+ "adding comment to statement inside the if body",
+ expectedResult,
+ actualResult
+ );
+
+ String s4 = "myButton.setText(\"Ok\");";
+ String s5 = "'Instance.'MethodCall:[regex( setText )]('Parameter*:[regex( \"Ok\" )]);";
+ String s6 = "$Instance$.$MethodCall$(\"OK\");";
+
+ String expectedResult2 = "myButton.setText(\"OK\");";
+
+ actualResult = replacer.testReplace(s4,s5,s6,options);
+ assertEquals(
+ "adding comment to statement inside the if body",
+ expectedResult2,
+ actualResult
+ );
+ }
+
+ public void testReplace() {
+ String str = "// searching for several constructions\n" +
+ " lastTest = \"several constructions match\";\n" +
+ " matches = testMatcher.findMatches(s5,s4, options);\n" +
+ " if (matches==null || matches.size()!=3) return false;\n" +
+ "\n" +
+ " // searching for several constructions\n" +
+ " lastTest = \"several constructions 2\";\n" +
+ " matches = testMatcher.findMatches(s5,s6, options);\n" +
+ " if (matches.size()!=0) return false;\n" +
+ "\n" +
+ " //options.setLooseMatching(true);\n" +
+ " // searching for several constructions\n" +
+ " lastTest = \"several constructions 3\";\n" +
+ " matches = testMatcher.findMatches(s7,s8, options);\n" +
+ " if (matches.size()!=2) return false;";
+
+ String str2=" lastTest = 'Descr;\n" +
+ " matches = testMatcher.findMatches('In,'Pattern, options);\n" +
+ " if (matches.size()!='Number) return false;";
+ String str3 = "assertEquals($Descr$,testMatcher.findMatches($In$,$Pattern$, options).size(),$Number$);";
+ String expectedResult1 = "// searching for several constructions\n" +
+ " lastTest = \"several constructions match\";\n" +
+ " matches = testMatcher.findMatches(s5, s4, options);\n" +
+ " if (matches == null || matches.size() != 3) return false;\n" +
+ "\n" +
+ " // searching for several constructions\n" +
+ " assertEquals(\"several constructions 2\", testMatcher.findMatches(s5, s6, options).size(), 0);\n" +
+ "\n" +
+ " //options.setLooseMatching(true);\n" +
+ " // searching for several constructions\n" +
+ " assertEquals(\"several constructions 3\", testMatcher.findMatches(s7, s8, options).size(), 2);";
+
+ String str4 = "";
+
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(str,str2,str3,options);
+ options.setToReformatAccordingToStyle(false);
+ assertEquals("Basic replacement with formatter",expectedResult1,actualResult);
+
+ actualResult = replacer.testReplace(str,str2,str4,options);
+ String expectedResult2 = "// searching for several constructions\n" +
+ " lastTest = \"several constructions match\";\n" +
+ " matches = testMatcher.findMatches(s5,s4, options);\n" +
+ " if (matches==null || matches.size()!=3) return false;\n" +
+ "\n" +
+ " // searching for several constructions\n" +
+ "\n" +
+ " //options.setLooseMatching(true);\n" +
+ " // searching for several constructions";
+
+ assertEquals("Empty replacement",expectedResult2,actualResult);
+
+ String str5 = "testMatcher.findMatches('In,'Pattern, options).size()";
+ String str6 = "findMatchesCount($In$,$Pattern$)";
+ String expectedResult3="// searching for several constructions\n" +
+ " lastTest = \"several constructions match\";\n" +
+ " matches = testMatcher.findMatches(s5, s4, options);\n" +
+ " if (matches == null || matches.size() != 3) return false;\n" +
+ "\n" +
+ " // searching for several constructions\n" +
+ " assertEquals(\"several constructions 2\", findMatchesCount(s5,s6), 0);\n" +
+ "\n" +
+ " //options.setLooseMatching(true);\n" +
+ " // searching for several constructions\n" +
+ " assertEquals(\"several constructions 3\", findMatchesCount(s7,s8), 2);";
+ actualResult = replacer.testReplace(expectedResult1,str5,str6,options);
+
+ assertEquals( "Expression replacement", expectedResult3,actualResult );
+
+ String str7 = "try { a.doSomething(); b.doSomething(); } catch(IOException ex) { ex.printStackTrace(); throw new RuntimeException(ex); }";
+ String str8 = "try { 'Statements+; } catch('_ '_) { 'HandlerStatements+; }";
+ String str9 = "$Statements$;";
+ String expectedResult4 = "a.doSomething(); b.doSomething();";
+
+ actualResult = replacer.testReplace(str7,str8,str9,options);
+ assertEquals( "Multi line match in replacement", expectedResult4,actualResult );
+
+ String str10 = " parentNode.insert(compositeNode, i);\n" +
+ " if (asyncMode) {\n" +
+ " myTreeModel.nodesWereInserted(parentNode,new int[] {i} );\n" +
+ " }";
+ String str11 = " 'parentNode.insert('newNode, 'i);\n" +
+ " if (asyncMode) {\n" +
+ " myTreeModel.nodesWereInserted('parentNode,new int[] {'i} );\n" +
+ " }";
+ String str12 = "addChild($parentNode$,$newNode$, $i$);";
+ String expectedResult5 = " addChild(parentNode,compositeNode, i);";
+
+ actualResult = replacer.testReplace(str10,str11,str12,options);
+ assertEquals( "Array initializer replacement", expectedResult5,actualResult);
+
+ String str13 = " aaa(5,6,3,4,1,2);";
+ String str14 = "aaa('t{2,2},3,4,'q{2,2});";
+ String str15 = "aaa($q$,3,4,$t$);";
+ String expectedResult6 = " aaa(1,2,3,4,5,6);";
+
+ actualResult = replacer.testReplace(str13,str14,str15,options);
+ assertEquals("Parameter multiple match",expectedResult6,actualResult);
+
+ String str16 = " int c = a();";
+ String str17 = "'t:a ('q*,'p*)";
+ String str18 = "$t$($q$,1,$p$)";
+ String expectedResult7 = " int c = a(1);";
+
+ actualResult = replacer.testReplace(str16,str17,str18,options);
+ assertEquals("Replacement of init in definition + empty substitution",expectedResult7,actualResult);
+
+ String str19 = " aaa(bbb);";
+ String str20 = "'t('_);";
+ String str21 = "$t$(ccc);";
+ String expectedResult8 = " aaa(ccc);";
+
+ actualResult = replacer.testReplace(str19,str20,str21,options);
+ assertEquals("One substition replacement",expectedResult8,actualResult);
+
+ String str22 = " instance.setAAA(anotherInstance.getBBB());";
+ String str23 = " 'i.'m:set(.+) ('a.'m2:get(.+) ());";
+ String str24 = " $a$.set$m2_1$( $i$.get$m_1$() );";
+ String expectedResult9 = " anotherInstance.setBBB( instance.getAAA() );";
+
+ actualResult = replacer.testReplace(str22,str23,str24,options);
+ assertEquals("Reg exp substitution replacement",expectedResult9,actualResult);
+
+ String str25 = " LaterInvocator.invokeLater(new Runnable() {\n" +
+ " public void run() {\n" +
+ " LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" +
+ " myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" +
+ " public void run() {\n" +
+ " semaphore.up();\n" +
+ " }\n" +
+ " });\n" +
+ " }\n" +
+ " });";
+ String str26 = " LaterInvocator.invokeLater('Params{1,10});";
+ String str27 = " com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater($Params$);";
+ String expectedResult10 = " com.intellij.openapi.application.ApplicationManager.getApplication().invokeLater(new Runnable() {\n" +
+ " public void run() {\n" +
+ " LOG.info(\"refreshFilesAsync, modalityState=\" + ModalityState.current());\n" +
+ " myHandler.getFiles().refreshFilesAsync(new Runnable() {\n" +
+ " public void run() {\n" +
+ " semaphore.up();\n" +
+ " }\n" +
+ " });\n" +
+ " }\n" +
+ " });";
+
+ actualResult = replacer.testReplace(str25,str26,str27,options);
+ assertEquals("Anonymous in parameter",expectedResult10,actualResult);
+
+ String str28 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile,\n" +
+ " processedElement.getTextOffset(), true,\n" +
+ " !myUsageViewDescriptor.toMarkInvalidOrReadonlyUsages(), null);";
+ String str29 = "new UTElementNode('param, 'directory, 'null, '0, 'true, !'descr.toMarkInvalidOrReadonlyUsages(),\n" +
+ " 'referencesWord)";
+ String str30 = "new UTElementNode($param$, $directory$, $null$, $0$, $true$, true,\n" +
+ " $referencesWord$)";
+
+ String expectedResult11 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile, processedElement.getTextOffset(), true, true,\n" +
+ " null);";
+ actualResult = replacer.testReplace(str28,str29,str30,options);
+ assertEquals("Replace in def initializer",expectedResult11,actualResult);
+
+ String s31 = "a = b; b = c; a=a; c=c;";
+ String s32 = "'a = 'a;";
+ String s33 = "1 = 1;";
+ String expectedResult12 = "a = b; b = c; 1 = 1; 1 = 1;";
+
+ actualResult = replacer.testReplace(s31,s32,s33,options);
+ assertEquals(
+ "replace silly assignments",
+ expectedResult12,
+ actualResult
+ );
+
+ String s34 = "ParamChecker.isTrue(1==1, \"!!!\");";
+ String s35 = "ParamChecker.isTrue('expr, 'msg)";
+ String s36 = "assert $expr$ : $msg$";
+
+ String expectedResult13 = "assert 1==1 : \"!!!\";";
+ actualResult = replacer.testReplace(s34,s35,s36,options);
+ assertEquals(
+ "replace with assert",
+ expectedResult13,
+ actualResult
+ );
+
+ String s37 = "try { \n" +
+ " ParamChecker.isTrue(1==1, \"!!!\");\n \n" +
+ " // comment we want to leave\n \n" +
+ " ParamChecker.isTrue(2==2, \"!!!\");\n" +
+ "} catch(Exception ex) {}";
+ String s38 = "try {\n" +
+ " 'Statement{0,100};\n" +
+ "} catch(Exception ex) {}";
+ String s39 = "$Statement$;";
+
+ String expectedResult14 = "ParamChecker.isTrue(1==1, \"!!!\");\n \n" +
+ " // comment we want to leave\n \n" +
+ " ParamChecker.isTrue(2==2, \"!!!\");";
+ actualResult = replacer.testReplace(s37,s38,s39,options);
+ assertEquals(
+ "remove try with comments inside",
+ expectedResult14,
+ actualResult
+ );
+
+ String s40 = "ParamChecker.instanceOf(queryKey, GroupBySqlTypePolicy.GroupKey.class);";
+ String s41 = "ParamChecker.instanceOf('obj, 'class.class);";
+ String s42 = "assert $obj$ instanceof $class$ : \"$obj$ is an instance of \" + $obj$.getClass() + \"; expected \" + $class$.class;";
+ String expectedResult15 = "assert queryKey instanceof GroupBySqlTypePolicy.GroupKey : \"queryKey is an instance of \" + queryKey.getClass() + \"; expected \" + GroupBySqlTypePolicy.GroupKey.class;";
+
+ actualResult = replacer.testReplace(s40,s41,s42,options);
+ assertEquals(
+ "Matching/replacing .class literals",
+ expectedResult15,
+ actualResult
+ );
+
+ String s43 = "class Wpd {\n" +
+ " static final String TAG_BEAN_VALUE = \"\";\n" +
+ "}\n" +
+ "XmlTag beanTag = rootTag.findSubTag(Wpd.TAG_BEAN_VALUE);";
+ String s44 = "'Instance?.findSubTag( 'Parameter:[exprtype( *String ) ])";
+ String s45 = "jetbrains.fabrique.util.XmlApiUtil.findSubTag($Instance$, $Parameter$)";
+ String expectedResult16 = "class Wpd {\n" +
+ " static final String TAG_BEAN_VALUE = \"\";\n" +
+ "}\n" +
+ "XmlTag beanTag = jetbrains.fabrique.util.XmlApiUtil.findSubTag(rootTag, Wpd.TAG_BEAN_VALUE);";
+
+ actualResult = replacer.testReplace(s43,s44,s45,options);
+ assertEquals(
+ "Matching/replacing static fields",
+ expectedResult16,
+ actualResult
+ );
+
+ String s46 = "Rectangle2D rec = new Rectangle2D.Double(\n" +
+ " drec.getX(),\n" +
+ " drec.getY(),\n" +
+ " drec.getWidth(),\n" +
+ " drec.getWidth());";
+ String s47 = "$Instance$.$MethodCall$()";
+ String s48 = "OtherClass.round($Instance$.$MethodCall$(),5)";
+ String expectedResult17 = "Rectangle2D rec = new Rectangle2D.Double(\n" +
+ " OtherClass.round(drec.getX(),5),\n" +
+ " OtherClass.round(drec.getY(),5),\n" +
+ " OtherClass.round(drec.getWidth(),5),\n" +
+ " OtherClass.round(drec.getWidth(),5));";
+ actualResult = replacer.testReplace(s46,s47,s48,options);
+
+ assertEquals(
+ "Replace in constructor",
+ expectedResult17,
+ actualResult
+ );
+
+ String s49 = "class A {}\n" +
+ "class B extends A {}\n" +
+ "A a = new B();";
+ String s50 = "A 'b = new 'B:*A ();";
+ String s51 = "A $b$ = new $B$(\"$b$\");";
+ String expectedResult18 = "class A {}\n" +
+ "class B extends A {}\n" +
+ "A a = new B(\"a\");";
+
+ actualResult = replacer.testReplace(s49,s50,s51,options);
+
+ assertEquals(
+ "Class navigation",
+ expectedResult18,
+ actualResult
+ );
+
+ String s52 = "try {\n" +
+ " aaa();\n" +
+ "} finally {\n" +
+ " System.out.println();" +
+ "}\n" +
+ "try {\n" +
+ " aaa2();\n" +
+ "} catch(Exception ex) {\n" +
+ " aaa3();\n" +
+ "}\n" +
+ "finally {\n" +
+ " System.out.println();\n" +
+ "}\n" +
+ "try {\n" +
+ " aaa4();\n" +
+ "} catch(Exception ex) {\n" +
+ " aaa5();\n" +
+ "}\n";
+ String s53 = "try { 'a; } finally {\n" +
+ " 'b;" +
+ "}";
+ String s54 = "$a$;";
+ String expectedResult19 = "aaa();\n" +
+ "try {\n" +
+ " aaa2();\n" +
+ "} catch(Exception ex) {\n" +
+ " aaa3();\n" +
+ "}\n" +
+ "finally {\n" +
+ " System.out.println();\n" +
+ "}\n" +
+ "try {\n" +
+ " aaa4();\n" +
+ "} catch(Exception ex) {\n" +
+ " aaa5();\n" +
+ "}\n";
+
+ actualResult = replacer.testReplace(s52,s53,s54,options);
+
+ assertEquals(
+ "Try/ catch/ finally is replace with try/finally",
+ expectedResult19,
+ actualResult
+ );
+
+ String s55 = "for(Iterator<String> iterator = stringlist.iterator(); iterator.hasNext();) {\n" +
+ " String str = iterator.next();\n" +
+ " System.out.println( str );\n" +
+ "}";
+ String s56 = "for (Iterator<$Type$> $variable$ = $container$.iterator(); $variable$.hasNext();) {\n" +
+ " $Type$ $var$ = $variable$.next();\n" +
+ " $Statements$;\n" +
+ "}";
+ String s57 = "for($Type$ $var$:$container$) {\n" +
+ " $Statements$;\n" +
+ "}";
+ String expectedResult20 = "for(String str :stringlist) {\n" +
+ " System.out.println( str );\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s55,s56,s57,options);
+
+ assertEquals(
+ "for with foreach",
+ expectedResult20,
+ actualResult
+ );
+
+ String s58 = "class A {\n" +
+ " static Set<String> b_MAP = new HashSet<String>();\n" +
+ " int c;\n" +
+ "}";
+ String s59 = "'a:[ regex( (.*)_MAP ) ]";
+ String s60 = "$a_1$_SET";
+ String expectedResult21 = "class A {\n" +
+ " static Set<String> b_SET = new HashSet<String>();\n" +
+ " int c;\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s58,s59,s60,options);
+
+ assertEquals(
+ "replace symbol in definition",
+ expectedResult21,
+ actualResult
+ );
+
+ String s64 = "int x = 42;\n" +
+ "int y = 42; // Stuff";
+ String s65 = "'Type 'Variable = 'Value; // 'Comment";
+ String s66 = "/**\n" +
+ " *$Comment$\n" +
+ " */\n" +
+ "$Type$ $Variable$ = $Value$;";
+ String expectedResult23 = "int x = 42;\n" +
+ "/**\n" +
+ " * Stuff\n" +
+ " */\n" +
+ "int y = 42;";
+
+ actualResult = replacer.testReplace(s64,s65,s66,options);
+
+ assertEquals(
+ "Replacement of the comment with javadoc",
+ expectedResult23,
+ actualResult
+ );
+
+ String s61 = "try { 1=1; } catch(Exception e) { 1=1; } catch(Throwable t) { 2=2; }";
+ String s62 = "try { 'a; } catch(Exception e) { 'b; }";
+ String s63 = "try { $a$; } catch(Exception1 e) { $b$; } catch(Exception2 e) { $b$; }";
+ String expectedResult22 = "try { 1=1; } catch(Exception1 e) { 1=1; } catch(Exception2 e) { 1=1; } catch (Throwable t) { 2=2; }";
+
+ actualResult = replacer.testReplace(s61,s62,s63,options);
+
+ assertEquals(
+ "try replacement by another try will leave the unmatched catch",
+ expectedResult22,
+ actualResult
+ );
+
+ }
+
+ public void testReplaceExpr() {
+ String s1 = "new SimpleDateFormat(\"yyyyMMddHHmmss\")";
+ String s2 = "'expr";
+ String s3 = "new AtomicReference<DateFormat>($expr$)";
+ String expectedResult = "new AtomicReference<DateFormat>(new SimpleDateFormat(\"yyyyMMddHHmmss\"))";
+
+ actualResult = replacer.testReplace(s1, s2, s3, options);
+
+ assertEquals("Replacement of top-level expression only", expectedResult, actualResult);
+
+ String s4 = "get(\"smth\")";
+ String s5 = "'expr";
+ String s6 = "new Integer($expr$)";
+ String expectedResult1 = "new Integer(get(\"smth\"))";
+
+ actualResult = replacer.testReplace(s4, s5, s6, options);
+ assertEquals("Replacement of top-level expression only", expectedResult1, actualResult);
+ }
+
+ public void testReplaceParameter() {
+ String s1 = "class A { void b(int c, int d, int e) {} }";
+ String s2 = "int d";
+ String s3 = "int d2";
+ String expectedResult = "class A { void b(int c, int d2, int e) {} }";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+
+ assertEquals(
+ "replace method parameter",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReplaceWithComments() {
+ String s1 = "map.put(key, value); // line 1";
+ String s2 = "map.put(key, value); // line 1";
+ String s3 = "map.put(key, value); // line 1";
+ String expectedResult = "map.put(key, value); // line 1";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+
+ assertEquals(
+ "replace self with comment after",
+ expectedResult,
+ actualResult
+ );
+
+ String s4 = "if (true) System.out.println(\"1111\"); else System.out.println(\"2222\");\n" +
+ "while(true) System.out.println(\"1111\");";
+ String s5 = "System.out.println('Test);";
+ String s6 = "/* System.out.println($Test$); */";
+ actualResult = replacer.testReplace(s4,s5,s6,options);
+ String expectedResult2 = "if (true) /* System.out.println(\"1111\"); */; else /* System.out.println(\"2222\"); */;\n" +
+ "while(true) /* System.out.println(\"1111\"); */;";
+
+ assertEquals(
+ "replace with comment",
+ expectedResult2,
+ actualResult
+ );
+ }
+
+ public void testSeveralStatements() {
+ String s1 = "{\n" +
+ " System.out.println(1);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(3);\n" +
+ " }\n" +
+ "{\n" +
+ " System.out.println(1);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(3);\n" +
+ " }\n" +
+ "{\n" +
+ " System.out.println(1);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(3);\n" +
+ " }";
+ String s2 =
+ " System.out.println(1);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(3);\n";
+ String s3 = " System.out.println(3);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(1);\n";
+ String expectedResult1 = " {\n" +
+ " System.out.println(3);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(1);\n" +
+ " }\n" +
+ " {\n" +
+ " System.out.println(3);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(1);\n" +
+ " }\n" +
+ " {\n" +
+ " System.out.println(3);\n" +
+ " System.out.println(2);\n" +
+ " System.out.println(1);\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+ options.setToReformatAccordingToStyle(false);
+ assertEquals(
+ "three statements replacement",
+ expectedResult1,
+ actualResult
+ );
+
+ String s4 = "ProgressManager.getInstance().startNonCancelableAction();\n" +
+ " try {\n" +
+ " read(id, READ_PARENT);\n" +
+ " return myViewport.parent;\n" +
+ " }\n" +
+ " finally {\n" +
+ " ProgressManager.getInstance().finishNonCancelableAction();\n" +
+ " }";
+ String s5 = "ProgressManager.getInstance().startNonCancelableAction();\n" +
+ " try {\n" +
+ " '_statement{2,2};\n" +
+ " }\n" +
+ " finally {\n" +
+ " ProgressManager.getInstance().finishNonCancelableAction();\n" +
+ " }";
+ String s6 = "$statement$;";
+ String expectedResult2 = "read(id, READ_PARENT);\n" +
+ " return myViewport.parent;";
+ actualResult = replacer.testReplace(s4,s5,s6,options);
+ assertEquals(
+ "extra ;",
+ expectedResult2,
+ actualResult
+ );
+
+ String s7 = "public class A {\n" +
+ " void f() {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " }\n" +
+ "\n" +
+ " private void l() {\n" +
+ " int i = 9;\n" +
+ " int j = 9;\n" +
+ " }\n" +
+ " };\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " }\n" +
+ "\n" +
+ " private void l() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ "}";
+ String s8 = "new Runnable() {\n" +
+ " public void run() {\n" +
+ " 'l ();\n" +
+ " }\n" +
+ " private void 'l () {\n" +
+ " 'st{2,2};\n" +
+ " }\n" +
+ "};";
+ String s9 = "new My() {\n" +
+ " public void f() {\n" +
+ " $st$;\n" +
+ " }\n" +
+ "};";
+
+ String expectedResult3 = "public class A {\n" +
+ " void f() {\n" +
+ " new My() {\n" +
+ " public void f() {\n" +
+ " int i = 9;\n" +
+ " int j = 9;\n" +
+ " }\n" +
+ " };\n" +
+ " new My() {\n" +
+ " public void f() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ "}";
+ boolean formatAccordingToStyle = options.isToReformatAccordingToStyle();
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s7,s8,s9,options);
+ assertEquals(
+ "extra ; 2",
+ expectedResult3,
+ actualResult
+ );
+
+ String s10 = "public class A {\n" +
+ " void f() {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " public void run2() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ "\n" +
+ " };\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " public void run2() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ "\n" +
+ " };\n" +
+ "new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " public void run2() {\n" +
+ " l2();\n" +
+ " l2();\n" +
+ " }\n" +
+ "\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " private void l() {\n" +
+ " int i = 9;\n" +
+ " int j = 9;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "abstract class My {\n" +
+ " abstract void f();\n" +
+ "}";
+ String s11 = "new Runnable() {\n" +
+ " public void run() {\n" +
+ " 'l{2,2};\n" +
+ " }\n" +
+ " public void run2() {\n" +
+ " 'l{2,2};\n" +
+ " }\n" +
+ "\n" +
+ " };";
+ String s12 = "new My() {\n" +
+ " public void f() {\n" +
+ " $l$;\n" +
+ " }\n" +
+ " };";
+ String expectedResult4 = "public class A {\n" +
+ " void f() {\n" +
+ " new My() {\n" +
+ " public void f() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " };\n" +
+ " new My() {\n" +
+ " public void f() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ " };\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " l();\n" +
+ " l();\n" +
+ " }\n" +
+ "\n" +
+ " public void run2() {\n" +
+ " l2();\n" +
+ " l2();\n" +
+ " }\n" +
+ "\n" +
+ " };\n" +
+ " }\n" +
+ "\n" +
+ " private void l() {\n" +
+ " int i = 9;\n" +
+ " int j = 9;\n" +
+ " }\n" +
+ "}\n" +
+ "\n" +
+ "abstract class My {\n" +
+ " abstract void f();\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s10,s11,s12,options);
+ assertEquals(
+ "same multiple occurences 2 times",
+ expectedResult4,
+ actualResult
+ );
+
+ options.setToReformatAccordingToStyle(formatAccordingToStyle);
+
+ String s13 = " PsiLock.LOCK.acquire();\n" +
+ " try {\n" +
+ " return value;\n" +
+ " }\n" +
+ " finally {\n" +
+ " PsiLock.LOCK.release();\n" +
+ " }";
+ String s13_2 = " PsiLock.LOCK.acquire();\n" +
+ " try {\n" +
+ " if (true) { return value; }\n" +
+ " }\n" +
+ " finally {\n" +
+ " PsiLock.LOCK.release();\n" +
+ " }";
+ String s13_3 = " PsiLock.LOCK.acquire();\n" +
+ " try {\n" +
+ " if (true) { return value; }\n\n" +
+ " if (true) { return value; }\n" +
+ " }\n" +
+ " finally {\n" +
+ " PsiLock.LOCK.release();\n" +
+ " }";
+ String s14 = " PsiLock.LOCK.acquire();\n" +
+ " try {\n" +
+ " 'T{1,1000};\n" +
+ " }\n" +
+ " finally {\n" +
+ " PsiLock.LOCK.release();\n" +
+ " }";
+ String s15 = "synchronized(PsiLock.LOCK) {\n" +
+ " $T$;\n" +
+ "}";
+
+ String expectedResult5 = " synchronized (PsiLock.LOCK) {\n" +
+ " return value;\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s13,s14,s15,options);
+ options.setToReformatAccordingToStyle(false);
+
+ assertEquals(
+ "extra ; over return",
+ expectedResult5,
+ actualResult
+ );
+
+ String expectedResult6 = " synchronized (PsiLock.LOCK) {\n" +
+ " if (true) {\n" +
+ " return value;\n" +
+ " }\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s13_2,s14,s15,options);
+ options.setToReformatAccordingToStyle(false);
+
+ assertEquals(
+ "extra ; over if",
+ expectedResult6,
+ actualResult
+ );
+
+ String expectedResult7 = " synchronized (PsiLock.LOCK) {\n" +
+ " if (true) {\n" +
+ " return value;\n" +
+ " }\n" +
+ "\n" +
+ " if (true) {\n" +
+ " return value;\n" +
+ " }\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s13_3,s14,s15,options);
+ options.setToReformatAccordingToStyle(false);
+ assertEquals(
+ "newlines in matches of several lines",
+ expectedResult7,
+ actualResult
+ );
+
+ String s16 = "public class SSTest {\n" +
+ " Object lock;\n" +
+ " public Object getProducts (String[] productNames) {\n" +
+ " synchronized (lock) {\n" +
+ " Object o = new Object ();\n" +
+ " assert o != null;\n" +
+ " return o;\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ String s16_2 = "public class SSTest {\n" +
+ " Object lock;\n" +
+ " public void getProducts (String[] productNames) {\n" +
+ " synchronized (lock) {\n" +
+ " boolean[] v = {true};\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ String s17 = "synchronized(lock) {\n" +
+ " 'Statement*;\n" +
+ "}";
+
+ String s18 = "$Statement$;";
+ String expectedResult8 = "public class SSTest {\n" +
+ " Object lock;\n" +
+ " public Object getProducts (String[] productNames) {\n" +
+ " Object o = new Object ();\n" +
+ " assert o != null;\n" +
+ " return o;\n" +
+ " }\n" +
+ "}";
+ String expectedResult8_2 = "public class SSTest {\n" +
+ " Object lock;\n" +
+ " public void getProducts (String[] productNames) {\n" +
+ " boolean[] v = {true};\n" +
+ " }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s16,s17,s18,options);
+ assertEquals(
+ "extra ;",
+ expectedResult8,
+ actualResult
+ );
+
+ actualResult = replacer.testReplace(s16_2,s17,s18,options);
+ assertEquals(
+ "missed ;",
+ expectedResult8_2,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement() {
+ boolean formatAccordingToStyle = options.isToReformatAccordingToStyle();
+ options.setToReformatAccordingToStyle(true);
+
+ String s1 = "class A { public void b() {} }";
+ String s2 = "class 'a { 'Other* }";
+ String s3 = "class $a$New { Logger LOG; $Other$ }";
+ String expectedResult = " class ANew {\n" +
+ " Logger LOG;\n\n" +
+ " public void b() {\n" +
+ " }\n" +
+ " }";
+ String actualResult;
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+ assertEquals(
+ "Basic class replacement",
+ expectedResult,
+ actualResult
+ );
+
+ String s4 = "class A { class C {} public void b() {} int f; }";
+ String s5 = "class 'a { 'Other* }";
+ String s6 = "class $a$ { Logger LOG; $Other$ }";
+ String expectedResult2 = " class A {\n" +
+ " Logger LOG;\n\n" +
+ " class C {\n" +
+ " }\n\n" +
+ " public void b() {\n" +
+ " }\n\n" +
+ " int f;\n" +
+ " }";
+
+ actualResult = replacer.testReplace(s4,s5,s6,options);
+ assertEquals(
+ "Order of members in class replacement",
+ expectedResult2,
+ actualResult
+ );
+
+ String s7 = "class A extends B { int c; void b() {} { a = 1; } }";
+ String s8 = "class 'A extends B { 'Other* }";
+ String s9 = "class $A$ extends B2 { $Other$ }";
+ String expectedResult3 = " class A extends B2 {\n" +
+ " int c;\n\n" +
+ " void b() {\n" +
+ " }\n\n" +
+ " {\n" +
+ " a = 1;\n" +
+ " }\n" +
+ " }";
+
+ actualResult = replacer.testReplace(s7,s8,s9,options);
+ assertEquals("Unsupported pattern exception",actualResult,expectedResult3);
+ options.setToReformatAccordingToStyle(formatAccordingToStyle);
+
+ String s10 = "/** @example */\n" +
+ "class A {\n" +
+ " class C {}\n" +
+ " public void b() {}\n" +
+ " int f;\n" +
+ "}";
+ String s11 = "class 'a { 'Other* }";
+ String s12 = "public class $a$ {\n" +
+ " $Other$\n" +
+ "}";
+ String expectedResult4 = "/** @example */\n" +
+ " public class A {\n" +
+ " class C {\n" +
+ " }\n\n" +
+ " public void b() {\n" +
+ " }\n\n" +
+ " int f;\n" +
+ " }";
+
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s10,s11,s12,options);
+ options.setToReformatAccordingToStyle(false);
+ assertEquals("Make class public",expectedResult4,actualResult);
+
+ String s13 = "class CustomThread extends Thread {\n" +
+ "public CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" +
+ " super(CustomThreadGroup.getThreadGroup(), \"CustomThread\");\n" +
+ " setDaemon(true);\n" +
+ " if (in instanceof BufferedInputStream) {\n" +
+ " bis = (BufferedInputStream)in;\n" +
+ " } else {\n" +
+ " bis = new BufferedInputStream(in);\n" +
+ " }\n" +
+ " this.out = out;\n" +
+ " this.closeOutOnExit = closeOutOnExit;\n" +
+ "}\n" +
+ "}";
+ String s14 = "class 'Class extends Thread {\n" +
+ " 'Class('ParameterType* 'ParameterName*) {\n" +
+ "\t super (CustomThreadGroup.getThreadGroup(), 'superarg* );\n" +
+ " 'Statement*;\n" +
+ " }\n" +
+ "}";
+ String s15 = "class $Class$ extends CustomThread {\n" +
+ " $Class$($ParameterType$ $ParameterName$) {\n" +
+ "\t super($superarg$);\n" +
+ " $Statement$;\n" +
+ " }\n" +
+ "}";
+
+ String expectedResult5 = " class CustomThread extends CustomThread {\n" +
+ " CustomThread(InputStream in, OutputStream out, boolean closeOutOnExit) {\n" +
+ " super(\"CustomThread\");\n" +
+ " setDaemon(true);\n" +
+ " if (in instanceof BufferedInputStream) {\n" +
+ " bis = (BufferedInputStream) in;\n" +
+ " } else {\n" +
+ " bis = new BufferedInputStream(in);\n" +
+ " }\n" +
+ " this.out = out;\n" +
+ " this.closeOutOnExit = closeOutOnExit;\n" +
+ " }\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s13,s14,s15,options);
+ options.setToReformatAccordingToStyle(false);
+ assertEquals("Constructor replacement",expectedResult5,actualResult);
+
+ String s16 = "public class A {}\n" +
+ "final class B {}";
+ String s17 = "class 'A { 'Other* }";
+ String s17_2 = "class 'A { private Log log = LogFactory.createLog(); 'Other* }";
+ String s18 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
+ String s18_2 = "class $A$ { $Other$ }";
+
+ actualResult = replacer.testReplace(s16,s17,s18,options);
+ String expectedResult6 = "public class A { private Log log = LogFactory.createLog(); }\n" +
+ "final class B { private Log log = LogFactory.createLog(); }";
+ assertEquals("Modifier list for class",expectedResult6,actualResult);
+
+ actualResult = replacer.testReplace(actualResult,s17_2,s18_2,options);
+ String expectedResult7 = "public class A { }\n" +
+ "final class B { }";
+ assertEquals("Removing field",expectedResult7,actualResult);
+
+ String s19 = "public class A extends Object implements Cloneable {}\n";
+ String s20 = "class 'A { 'Other* }";
+ String s21 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
+
+ actualResult = replacer.testReplace(s19,s20,s21,options);
+ String expectedResult8 = "public class A extends Object implements Cloneable { private Log log = LogFactory.createLog(); }\n";
+ assertEquals("Extends / implements list for class",expectedResult8,actualResult);
+
+ String s22 = "public class A<T> { int Afield; }\n";
+ String s23 = "class 'A { 'Other* }";
+ String s24 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
+
+ actualResult = replacer.testReplace(s22,s23,s24,options);
+ String expectedResult9 = "public class A<T> { private Log log = LogFactory.createLog(); int Afield; }\n";
+ assertEquals("Type parameters for the class",expectedResult9,actualResult);
+
+ String s25 = "class A {\n" +
+ " // comment before\n" +
+ " protected short a; // comment after\n" +
+ "}";
+ String s26 = "short a;";
+ String s27 = "Object a;";
+ String expectedResult10 = "class A {\n" +
+ " // comment before\n" +
+ " protected Object a; // comment after\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s25,s26,s27,options);
+
+ assertEquals(
+ "Replacing dcl with saving access modifiers",
+ expectedResult10,
+ actualResult
+ );
+
+ String s28 = "aaa";
+ String s29 = "class 'Class {\n" +
+ " 'Class('ParameterType 'ParameterName) {\n" +
+ " 'Class('ParameterName);\n" +
+ " }\n" +
+ "}";
+ String s30 = "class $Class$ {\n" +
+ " $Class$($ParameterType$ $ParameterName$) {\n" +
+ " this($ParameterName$);\n" +
+ " }\n" +
+ "}";
+ String expectedResult11 = "aaa";
+
+ actualResult = replacer.testReplace(s28,s29,s30,options);
+
+ assertEquals(
+ "Complex class replacement",
+ expectedResult11,
+ actualResult
+ );
+
+ String s31 = "class A {\n" +
+ " int a; // comment\n" +
+ " char b;\n" +
+ " int c; // comment2\n" +
+ "}";
+
+ String s32 = "'Type 'Variable = 'Value?; //'Comment";
+ String s33 = "/**$Comment$*/\n" +
+ "$Type$ $Variable$ = $Value$;";
+
+ String expectedResult12 = " class A {\n" +
+ " /**\n" +
+ " * comment\n" +
+ " */\n" +
+ " int a;\n" +
+ " char b;\n" +
+ " /**\n" +
+ " * comment2\n" +
+ " */\n" +
+ " int c;\n" +
+ " }";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s31,s32,s33,options);
+ options.setToReformatAccordingToStyle(false);
+
+ assertEquals(
+ "Replacing comments with javadoc for fields",
+ expectedResult12,
+ actualResult
+ );
+
+ String s34 = "/**\n" +
+ " * This interface stores XXX\n" +
+ " * <p/>\n" +
+ " */\n" +
+ "public interface X {\n" +
+ " public static final String HEADER = Headers.HEADER;\n" +
+ "\n" +
+ "}";
+
+ String s35 = "public interface 'MessageInterface {\n" +
+ " public static final String 'X = 'VALUE;\n" +
+ " 'blah*" +
+ "}";
+ String s36 = "public interface $MessageInterface$ {\n" +
+ " public static final String HEADER = $VALUE$;\n" +
+ " $blah$\n" +
+ "}";
+
+ String expectedResult13 = "/**\n" +
+ " * This interface stores XXX\n" +
+ " * <p/>\n" +
+ " */\n" +
+ "public interface X {\n" +
+ " public static final String HEADER = Headers.HEADER;\n" +
+ " \n" +
+ "}";
+
+ actualResult = replacer.testReplace(s34,s35,s36,options, true);
+
+ assertEquals(
+ "Replacing interface with interface, saving comments properly",
+ expectedResult13,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement3() {
+ if (true) return;
+ final String actualResult;
+ String s37 = "class A { int a = 1; void B() {} int C(char ch) { int z = 1; } int b = 2; }";
+
+ String s38 = "class 'A { 'T* 'M*('PT* 'PN*) { 'S*; } 'O* }";
+ String s39 = "class $A$ { $T$ $M$($PT$ $PN$) { System.out.println(\"$M$\"); $S$; } $O$ }";
+
+ String expectedResult14 = "class A { int a = 1; void B( ) { System.out.println(\"B\"); } int C(char ch) { System.out.println(\"C\"); int z = 1; } int b = 2;}";
+ String expectedResult14_2 = "class A { int a = 1; void B( ) { System.out.println(\"B\"); } int C(char ch) { System.out.println(\"C\"); int z = 1; } int b = 2;}";
+
+ actualResult = replacer.testReplace(s37,s38,s39,options, true);
+
+ assertEquals(
+ "Multiple methods replacement",
+ expectedResult14,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement4() {
+ final String actualResult;
+ String s1 = "class A {\n" +
+ " int a = 1;\n" +
+ " int b;\n" +
+ " private int c = 2;\n" +
+ "}";
+
+ String s2 = "@Modifier(\"PackageLocal\") 'Type 'Instance = 'Init?;";
+ String s3 = "public $Type$ $Instance$ = $Init$;";
+
+ String expectedResult = "class A {\n" +
+ " public int a = 1;\n" +
+ " public int b ;\n" +
+ " private int c = 2;\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options, true);
+
+ assertEquals(
+ "Multiple fields replacement",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement5() {
+ final String actualResult;
+ String s1 = "public class X {\n" +
+ " /**\n" +
+ " * zzz\n" +
+ " */\n" +
+ " void f() {\n" +
+ "\n" +
+ " }\n" +
+ "}";
+
+ String s2 = "class 'c {\n" +
+ " /**\n" +
+ " * zzz\n" +
+ " */\n" +
+ " void f(){}\n" +
+ "}";
+ String s3 = "class $c$ {\n" +
+ " /**\n" +
+ " * ppp\n" +
+ " */\n" +
+ " void f(){}\n" +
+ "}";
+
+ String expectedResult = "public class X {\n" +
+ " /**\n" +
+ " * ppp\n" +
+ " */\n" +
+ " void f(){}\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options, true);
+
+ assertEquals(
+ "Not preserving comment if it is present",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement6() {
+ String actualResult;
+ String s1 = "public class X {\n" +
+ " /**\n" +
+ " * zzz\n" +
+ " */\n" +
+ " private void f(int i) {\n" +
+ " //s\n" +
+ " }\n" +
+ "}";
+ String s1_2 = "public class X {\n" +
+ " /**\n" +
+ " * zzz\n" +
+ " */\n" +
+ " private void f(int i) {\n" +
+ " int a = 1;\n" +
+ " //s\n" +
+ " }\n" +
+ "}";
+
+ String s2 = "class 'c {\n" +
+ " /**\n" +
+ " * zzz\n" +
+ " */\n" +
+ " void f('t 'p){'s+;}\n" +
+ "}";
+ String s3 = "class $c$ {\n" +
+ " /**\n" +
+ " * ppp\n" +
+ " */\n" +
+ " void f($t$ $p$){$s$;}\n" +
+ "}";
+
+ String expectedResult = "public class X {\n" +
+ " /**\n" +
+ " * ppp\n" +
+ " */\n" +
+ " private void f(int i ){//s\n" +
+ "}\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+
+ assertEquals(
+ "Correct class replacement",
+ expectedResult,
+ actualResult
+ );
+
+ String expectedResult2 = "public class X {\n" +
+ " /**\n" +
+ " * ppp\n" +
+ " */\n" +
+ " private void f(int i ){int a = 1;\n" +
+ " //s\n" +
+ "}\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1_2,s2,s3,options);
+
+ assertEquals(
+ "Correct class replacement, 2",
+ expectedResult2,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement7() {
+ String s1 = "/**\n" +
+ "* Created by IntelliJ IDEA.\n" +
+ "* User: cdr\n" +
+ "* Date: Nov 15, 2005\n" +
+ "* Time: 4:23:29 PM\n" +
+ "* To change this template use File | Settings | File Templates.\n" +
+ "*/\n" +
+ "public class CC {\n" +
+ " /** My Comment */ int a = 3; // aaa\n" +
+ " // bbb\n" +
+ " long c = 2;\n" +
+ " void f() {\n" +
+ " }\n" +
+ "}";
+ String s2 = "/**\n" +
+ "* Created by IntelliJ IDEA.\n" +
+ "* User: 'USER\n" +
+ "* Date: 'DATE\n" +
+ "* Time: 'TIME\n" +
+ "* To change this template use File | Settings | File Templates.\n" +
+ "*/\n" +
+ "class 'c {\n" +
+ " 'other*\n" +
+ "}";
+ String s3 = "/**\n" +
+ "* by: $USER$\n" +
+ "*/\n" +
+ "class $c$ {\n" +
+ " $other$\n" +
+ "}";
+ String expectedResult = "/**\n" +
+ "* by: cdr\n" +
+ "*/\n" +
+ "public class CC {\n" +
+ " /** My Comment */ int a = 3; // aaa\n" +
+ "// bbb\n" +
+ " long c = 2;\n" +
+ "void f() {\n" +
+ " }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options,true);
+
+ assertEquals(
+ "Class with comment replacement",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testClassReplacement8() {
+ String s1 = "public class CC {\n" +
+ " /** AAA*/ int b = 1; // comment\n" +
+ "}";
+ String s2 = "int b = 1;";
+ String s3 = "long c = 2;";
+ String expectedResult = "public class CC {\n" +
+ " /** AAA*/ long c = 2; // comment\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options,true);
+
+ assertEquals(
+ "Class field replacement with simple pattern",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("structuralsearch") + "/testData/";
+ }
+
+ public void testClassReplacement9() throws IOException {
+ String s1 = loadFile("before1.java");
+ String s2 = "class 'A extends 'TestCaseCass:[regex( .*TestCase ) ] {\n" +
+ " 'OtherStatement*;\n" +
+ " public void 'testMethod*:[regex( test.* )] () {\n" +
+ " }\n" +
+ " 'OtherStatement2*;\n" +
+ "}";
+ String s3 = "class $A$ extends $TestCaseCass$ {\n" +
+ " $OtherStatement$;\n" +
+ " $OtherStatement2$;\n" +
+ "}";
+ String expectedResult = loadFile("after1.java");
+
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s1,s2,s3,options,true);
+
+ assertEquals(
+ "Class replacement 9",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReplaceReturnWithArrayInitializer() {
+ String searchIn = "return ( new String[]{CoreVars.CMUAudioPort + \"\"} );";
+ String searchFor = "return ( 'A );";
+ String replaceBy = "return $A$;";
+ String expectedResult = "return new String[]{CoreVars.CMUAudioPort + \"\"};";
+
+ actualResult = replacer.testReplace(searchIn,searchFor,replaceBy,options);
+
+ assertEquals(
+ "ReplaceReturnWithArrayInitializer",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void _testClassReplacement10() throws IOException {
+ String s1 = loadFile("before2.java");
+ String s2 = "class '_Class {\n" +
+ " '_ReturnType+ '_MethodName+('_ParameterType* '_Parameter*){\n" +
+ " '_content*;\n" +
+ " }\n" +
+ " '_remainingclass*" +
+ "}";
+ String s3 = "class $Class$ {\n" +
+ " $remainingclass$\n" +
+ " @Override $ReturnType$ $MethodName$($ParameterType$ $Parameter$){\n" +
+ " $content$;\n" +
+ " }\n" +
+ "}";
+ String expectedResult = loadFile("after2.java");
+
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s1,s2,s3,options,true);
+
+ assertEquals(
+ "Class replacement 10",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testCatchReplacement() throws Exception {
+ String s1 = "try {\n" +
+ " aaa();\n" +
+ "} catch(Exception ex) {\n" +
+ " LOG.assertTrue(false);\n" +
+ "}";
+ String s2 = "{ LOG.assertTrue(false); }";
+ String s3 = "{ if (false) LOG.assertTrue(false); }";
+ String expectedResult = "try {\n" +
+ " aaa();\n" +
+ "} catch (Exception ex) {\n" +
+ " if (false) LOG.assertTrue(false);\n" +
+ "}";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+ options.setToReformatAccordingToStyle(false);
+
+ assertEquals(
+ "Catch replacement by block",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testSavingAccessModifiersDuringClassReplacement() {
+ String actualResult;
+
+ String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }";
+ String s44 = "class 'Class implements 'Interface { 'Content* }";
+ String s45 = "@MyAnnotation\n" +
+ "class $Class$ implements $Interface$ {$Content$}";
+ String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
+ "class Foo implements Comparable<Foo> {int x;\n" +
+ "void m(){}}";
+
+ actualResult = replacer.testReplace(s43,s44,s45,options, true);
+ assertEquals(
+ "Preserving var modifiers and generic information in type during replacement",
+ expectedResult16,
+ actualResult
+ );
+ }
+
+ public void testDontRequireSpecialVarsForUnmatchedContent() {
+ String actualResult;
+
+ String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }";
+ String s44 = "class 'Class implements 'Interface {}";
+ String s45 = "@MyAnnotation\n" +
+ "class $Class$ implements $Interface$ {}";
+ String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
+ "class Foo implements Comparable<Foo> {int x;\nvoid m(){}}";
+
+ actualResult = replacer.testReplace(s43,s44,s45,options, true);
+ assertEquals(
+ "Preserving class modifiers and generic information in type during replacement",
+ expectedResult16,
+ actualResult
+ );
+ }
+
+ public void _testClassReplacement2() {
+ final String actualResult;
+ String s40 = "class A {\n" +
+ " /* special comment*/\n" +
+ " private List<String> a = new ArrayList();\n" +
+ " static {\n" +
+ " int a = 1;" +
+ " }\n" +
+ "}";
+ String s41 = "class 'Class {\n" +
+ " 'Stuff2*\n" +
+ " 'FieldType 'FieldName = 'Init?;\n" +
+ " static {\n" +
+ " 'Stmt*;\n" +
+ " }\n" +
+ " 'Stuff*\n" +
+ "}";
+ String s42 = "class $Class$ {\n" +
+ " $Stuff2$\n" +
+ " $FieldType$ $FieldName$ = build$FieldName$Map();\n" +
+ " private static $FieldType$ build$FieldName$Map() {\n" +
+ " $FieldType$ $FieldName$ = $Init$;\n" +
+ " $Stmt$;\n" +
+ " return $FieldName$;\n" +
+ " }\n" +
+ " $Stuff$\n" +
+ "}";
+ String expectedResult15 = "class A {\n" +
+ " \n" +
+ " /* special comment*/\n" +
+ " private List<String> a = buildaMap();\n" +
+ " private static List<String> buildaMap() {\n" +
+ " List<String> a = new ArrayList();\n" +
+ " int a = 1;\n" +
+ " return a;\n" +
+ " }\n" +
+ " \n" +
+ "}";
+
+ actualResult = replacer.testReplace(s40,s41,s42,options, true);
+
+ assertEquals(
+ "Preserving var modifiers and generic information in type during replacement",
+ expectedResult15,
+ actualResult
+ );
+
+ String s46 = "class Foo { int xxx; void foo() { assert false; } void yyy() {}}";
+ String s47 = "class 'Class { void 'foo:[regex( foo )](); }";
+ String s48 = "class $Class$ { void $foo$(int a); }";
+ String expectedResult17 = "class Foo { int xxx; void foo(int a) { assert false; } void yyy() {}}";
+
+ String actualResult2 = replacer.testReplace(s46,s47,s48,options, true);
+ assertEquals(
+ "Preserving method bodies",
+ expectedResult17,
+ actualResult2
+ );
+ }
+
+ public void testReplaceExceptions() {
+ String s1 = "a=a;";
+ String s2 = "'a";
+ String s3 = "$b$";
+
+ try {
+ replacer.testReplace(s1,s2,s3,options);
+ assertTrue("Undefined replace variable is not checked",false);
+ } catch(UnsupportedPatternException ex) {
+
+ }
+
+ String s4 = "a=a;";
+ String s5 = "a=a;";
+ String s6 = "a=a";
+
+ try {
+ replacer.testReplace(s4,s5,s6,options);
+ assertTrue("Undefined no ; in replace",false);
+ } catch(UnsupportedPatternException ex) {
+ }
+
+ try {
+ replacer.testReplace(s4,s6,s5,options);
+ assertTrue("Undefined no ; in search",false);
+ } catch(UnsupportedPatternException ex) {
+ }
+ }
+
+ public void testActualParameterReplacementInConstructorInvokation() {
+ String s1 = "filterActions[0] = new Action(TEXT,\n" +
+ " LifeUtil.getIcon(\"search\")) {\n" +
+ " void test() {\n" +
+ " int a = 1;\n" +
+ " }\n" +
+ "};";
+ String s2 = "LifeUtil.getIcon(\"search\")";
+ String s3 = "StdIcons.SEARCH_LIFE";
+ String expectedResult = "filterActions[0] = new Action(TEXT,\n" +
+ " StdIcons.SEARCH_LIFE) {\n" +
+ " void test() {\n" +
+ " int a = 1;\n" +
+ " }\n" +
+ "};";
+ options.setToReformatAccordingToStyle(true);
+ options.setToShortenFQN(true);
+
+ String actualResult = replacer.testReplace(s1, s2, s3, options);
+ assertEquals("Replace in anonymous class parameter", expectedResult, actualResult);
+ options.setToShortenFQN(false);
+ options.setToReformatAccordingToStyle(false);
+ }
+
+ public void testRemove() {
+ String s1 = "class A {\n" +
+ " /* */\n" +
+ " void a() {\n" +
+ " }\n" +
+ " /*\n" +
+ " */\n" +
+ " int b = 1;\n" +
+ " /*\n" +
+ " *\n" +
+ " */\n" +
+ " class C {}\n" +
+ " {\n" +
+ " /* aaa */\n" +
+ " int a;\n" +
+ " /* */\n" +
+ " a = 1;\n" +
+ " }\n" +
+ "}";
+ String s2 = "/* 'a:[regex( .* )] */";
+ String s2_2 = "/* */";
+ String s3 = "";
+ String expectedResult = "class A {\n" +
+ " void a() {\n" +
+ " }\n" +
+ "\n" +
+ " int b = 1;\n" +
+ "\n" +
+ " class C {\n" +
+ " }\n" +
+ "\n" +
+ " {\n" +
+ " int a;\n" +
+ " a = 1;\n" +
+ " }\n" +
+ "}";
+ options.setToReformatAccordingToStyle(true);
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+ options.setToReformatAccordingToStyle(false);
+
+ assertEquals(
+ "Removing comments",
+ expectedResult,
+ actualResult
+ );
+
+ String expectedResult2 = "class A {\n" +
+ " void a() {\n" +
+ " }\n" +
+ " /*\n" +
+ " */\n" +
+ " int b = 1;\n" +
+ " /*\n" +
+ " *\n" +
+ " */\n" +
+ " class C {}\n" +
+ " {\n" +
+ " /* aaa */\n" +
+ " int a;\n" +
+ " a = 1;\n" +
+ " }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2_2,s3,options);
+
+ assertEquals(
+ "Removing comments",
+ expectedResult2,
+ actualResult
+ );
+ }
+
+ public void testTryCatchInLoop() throws Exception {
+ String code = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" +
+ "{\n" +
+ " String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" +
+ " try\n" +
+ " {\n" +
+ " if (ENABLE_Z107_READING)\n" +
+ " { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" +
+ " else\n" +
+ " { data = ResourceHelper.readResource(s); }\n" +
+ " mime = MIMEHelper.MIME_MAP[i][1][0];\n" +
+ " break;\n" +
+ " }\n" +
+ " catch (final Exception e)\n" +
+ " { continue; }\n" +
+ "}";
+ String toFind = "try { 'TryStatement*; } catch(Exception 'ExceptionDcl) { 'CatchStatement*; }";
+ String replacement = "try { $TryStatement$; }\n" + "catch(Throwable $ExceptionDcl$) { $CatchStatement$; }";
+ String expectedResult = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" +
+ "{\n" +
+ " String s = aFileNameWithOutExtention + MIMEHelper.MIME_MAP[i][0][0];\n" +
+ " try { if (ENABLE_Z107_READING)\n" +
+ " { in = aFileNameWithOutExtention.getClass().getResourceAsStream(s); }\n" +
+ " else\n" +
+ " { data = ResourceHelper.readResource(s); }\n" +
+ " mime = MIMEHelper.MIME_MAP[i][1][0];\n" +
+ " break; }\n" +
+ "catch(final Throwable e) { continue; }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(code,toFind,replacement,options);
+
+ assertEquals(
+ "Replacing try/catch in loop",
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReformatAndShortenClassRefPerformance() throws IOException {
+ final String testName = getTestName(false);
+ final String ext = "java";
+ final String message = "Reformat And Shorten Class Ref Performance";
+
+ options.setToReformatAccordingToStyle(true);
+ options.setToShortenFQN(true);
+
+ PlatformTestUtil.startPerformanceTest("SSR should work fast", 3500, new ThrowableRunnable() {
+ public void run() {
+ doTest(testName, ext, message);
+ }
+ }
+ ).cpuBound().assertTiming();
+
+ options.setToReformatAccordingToStyle(false);
+ options.setToShortenFQN(false);
+ }
+
+ private void doTest(final String testName, final String ext, final String message) {
+ try {
+ String source = loadFile(testName + "_source." + ext);
+ String pattern = loadFile(testName + "_pattern." + ext);
+ String replacement = loadFile(testName + "_replacement." + ext);
+ String expected = loadFile(testName + "_result." + ext);
+
+ actualResult = replacer.testReplace(source,pattern,replacement,options);
+
+ assertEquals(
+ message,
+ expected,
+ actualResult
+ );
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void testLeastSurprise() {
+ String s1 = "@Nullable (a=String.class) @String class Test {\n" +
+ " void aaa(String t) {\n" +
+ " String a = String.valueOf(' ');" +
+ " String2 a2 = String2.valueOf(' ');" +
+ " }\n" +
+ "}";
+ String s2 = "'String:String";
+ String s2_2 = "String";
+ String s2_3 = "'String:java\\.lang\\.String";
+ String s2_4 = "java.lang.String";
+ String replacement = CommonClassNames.JAVA_UTIL_LIST;
+ String expected = "@Nullable (a=java.util.List.class) @java.util.List class Test {\n" +
+ " void aaa(java.util.List t) {\n" +
+ " java.util.List a = java.util.List.valueOf(' ');" +
+ " String2 a2 = String2.valueOf(' ');" +
+ " }\n" +
+ "}";
+
+ actualResult = replacer.testReplace(s1,s2,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+
+ actualResult = replacer.testReplace(s1,s2_2,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+
+ actualResult = replacer.testReplace(s1,s2_3,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+
+ actualResult = replacer.testReplace(s1,s2_4,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+ }
+
+ public void testLeastSurprise2() {
+ String s1 = "class B { int s(int a) { a = 1; a = 2; c(a); } }";
+ String s2 = "a";
+ String replacement = "a2";
+ String expected = "class B { int s(int a2) { a2 = 1; a2 = 2; c(a2); } }";
+
+ actualResult = replacer.testReplace(s1,s2,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+ }
+
+ public void testReplaceTry() {
+ String s1 = "try {\n" +
+ " em.persist(p);\n" +
+ " } catch (PersistenceException e) {\n" +
+ " // good\n" +
+ " }";
+ String s2 = "try { 'TryStatement; } catch('ExceptionType 'ExceptionDcl) { /* 'CommentContent */ }";
+ String replacement = "try { $TryStatement$; } catch($ExceptionType$ $ExceptionDcl$) { _logger.warning(\"$CommentContent$\", $ExceptionDcl$); }";
+ String expected = "try { em.persist(p); } catch(PersistenceException e) { _logger.warning(\" good\", e); }";
+
+ actualResult = replacer.testReplace(s1,s2,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+ }
+
+ public void testReplaceExtraSemicolon() {
+ String s1 = "try {\n" +
+ " String[] a = {\"a\"};\n" +
+ " System.out.println(\"blah\");\n" +
+ "} finally {\n" +
+ "}\n";
+ String s2 = "try {\n" + " 'statement*;\n" + "} finally {\n" + " \n" + "}";
+ String replacement = "$statement$;";
+ String expected = "String[] a = {\"a\"};\n" +
+ " System.out.println(\"blah\");\n";
+
+ actualResult = replacer.testReplace(s1,s2,replacement,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+
+ String s1_2 = "try {\n" +
+ " if (args == null) return ;\n" +
+ " while(true) return ;\n" +
+ " System.out.println(\"blah2\");\n" +
+ "} finally {\n" +
+ "}";
+ String expected_2 = "if (args == null) return ;\n" +
+ " while(true) return ;\n" +
+ " System.out.println(\"blah2\");";
+
+ actualResult = replacer.testReplace(s1_2,s2,replacement,options);
+
+ assertEquals(
+ expected_2,
+ actualResult
+ );
+
+ String s1_3 = "{\n" +
+ " try {\n" +
+ " System.out.println(\"blah1\");\n" +
+ "\n" +
+ " System.out.println(\"blah2\");\n" +
+ " } finally {\n" +
+ " }\n" +
+ "}";
+ String expected_3 = "{\n" +
+ " System.out.println(\"blah1\");\n" +
+ "\n" +
+ " System.out.println(\"blah2\");\n" +
+ "}";
+ actualResult = replacer.testReplace(s1_3,s2,replacement,options);
+
+ assertEquals(
+ expected_3,
+ actualResult
+ );
+
+ String s1_4 = "{\n" +
+ " try {\n" +
+ " System.out.println(\"blah1\");\n" +
+ " // indented comment\n" +
+ " System.out.println(\"blah2\");\n" +
+ " } finally {\n" +
+ " }\n" +
+ "}";
+ String expected_4 = "{\n" +
+ " System.out.println(\"blah1\");\n" +
+ " // indented comment\n" +
+ " System.out.println(\"blah2\");\n" +
+ "}";
+ actualResult = replacer.testReplace(s1_4,s2,replacement,options);
+
+ assertEquals(
+ expected_4,
+ actualResult
+ );
+ }
+
+ public void _testReplaceFinalModifier() throws Exception {
+ String s1 = "class Foo {\n" +
+ " void foo(final int i,final int i2, final int i3) {\n" +
+ " final int x = 5;\n" +
+ " }\n" +
+ "}";
+ String s2 = "final '_type 'var = '_init?";
+ String s3 = "$type$ $var$ = $init$";
+
+ String expected = "2 = 1;\nint b = a;\nb2 = 3;";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+ }
+
+ public void testRemovingRedundancy() throws Exception {
+ String s1 = "int a = 1;\n" +
+ "a = 2;\n" +
+ "int b = a;\n" +
+ "b2 = 3;";
+ String s2 = "int 'a = 'i;\n" +
+ "'st*;\n" +
+ "'a = 'c;";
+ String s3 = "$st$;\n" +
+ "$c$ = $i$;";
+
+ String expected = "2 = 1;\nint b = a;\nb2 = 3;";
+
+ actualResult = replacer.testReplace(s1,s2,s3,options);
+
+ assertEquals(
+ expected,
+ actualResult
+ );
+
+ String s2_2 = "int 'a = 'i;\n" +
+ "'st*;\n" +
+ "int 'c = 'a;";
+ String s3_2 = "$st$;\n" +
+ "int $c$ = $i$;";
+ String expected_2 = "a = 2;\nint b = 1;\nb2 = 3;";
+
+ actualResult = replacer.testReplace(s1,s2_2,s3_2,options);
+
+ assertEquals(
+ expected_2,
+ actualResult
+ );
+ }
+
+ public void testReplaceWithEmptyString() {
+ String source = "public class Peepers {\n public long serialVersionUID = 1L; \n}";
+ String search = "long serialVersionUID = $value$;";
+ String replace = "";
+ String expectedResult = "public class Peepers { \n}";
+
+ String actualResult = replacer.testReplace(source, search, replace, options, true);
+
+ assertEquals(
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReplaceMultipleFieldsInSingleDeclaration() {
+ String source = "abstract class MyClass implements java.util.List {\n private String a, b;\n}";
+ String search = "class 'Name implements java.util.List {\n 'ClassContent*\n}";
+ String replace = "class $Name$ {\n $ClassContent$\n}";
+ String expectedResult = "abstract class MyClass {\n private String a,b;\n}";
+
+ String actualResult = replacer.testReplace(source, search, replace, options, true);
+
+ assertEquals(
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReplaceInImplementsList() {
+ String source = "import java.io.Externalizable;\n" +
+ "import java.io.Serializable;\n" +
+ "abstract class MyClass implements Serializable, java.util.List, Externalizable {}";
+ String search = "class 'TestCase implements java.util.List, 'others* {\n 'MyClassContent\n}";
+ String replace = "class $TestCase$ implements $others$ {\n $MyClassContent$\n}";
+ String expectedResult = "import java.io.Externalizable;\n" +
+ "import java.io.Serializable;\n" +
+ "abstract class MyClass implements Externalizable,Serializable {\n \n}";
+
+ String actualResult = replacer.testReplace(source, search, replace, options, true);
+ assertEquals(
+ expectedResult,
+ actualResult
+ );
+ }
+
+ public void testReplaceFieldWithEndOfLineComment() {
+ String source = "class MyClass {\n" +
+ " private String b;// comment\n" +
+ " public void foo() {\n" +
+ " }\n" +
+ "}";
+ String search = "class 'Class {\n 'Content*\n}";
+ String replace = "class $Class$ {\n" +
+ " void x() {}\n" +
+ " $Content$\n" +
+ " void bar() {}\n" +
+ "}";
+ String expectedResult = "class MyClass {\n" +
+ " void x() {}\n" +
+ " private String b;// comment\n" +
+ "public void foo() {\n" +
+ " }\n" +
+ " void bar() {}\n" +
+ "}";
+
+ String actualResult = replacer.testReplace(source, search, replace, options, true);
+ assertEquals(
+ expectedResult,
+ actualResult
+ );
+ }
+} \ No newline at end of file
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java
new file mode 100644
index 000000000000..9a9fbb362a63
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTestCase.java
@@ -0,0 +1,42 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: maxim.mossienko
+ * Date: Oct 11, 2005
+ * Time: 10:10:48 PM
+ * To change this template use File | Settings | File Templates.
+ */
+abstract class StructuralReplaceTestCase extends LightQuickFixTestCase {
+ protected Replacer replacer;
+ protected ReplaceOptions options;
+ protected String actualResult;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ StructuralSearchUtil.ourUseUniversalMatchingAlgorithm = false;
+
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_4);
+
+ options = new ReplaceOptions();
+ options.setMatchOptions(new MatchOptions());
+ replacer = new Replacer(getProject(), null);
+ }
+
+ protected String loadFile(String fileName) throws IOException {
+ return FileUtilRt.loadFile(new File(getTestDataPath() + FileUtilRt.getExtension(fileName) + "/" + fileName), CharsetToolkit.UTF8, true);
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java
new file mode 100644
index 000000000000..a3fecba980df
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java
@@ -0,0 +1,2938 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.idea.Bombed;
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.psi.*;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * @author Maxim.Mossienko
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public class StructuralSearchTest extends StructuralSearchTestCase {
+ private static final String s1 =
+ "debug(\"In action performed:\"+event);"+
+ "project = (Project)event.getDataContext().getData(DataConstants.PROJECT);" +
+ "CodeEditorManager.getInstance(project).commitAllToPsiFile();" +
+ "file = (PsiFile) event.getDataContext().getData(\"psi.File\"); " +
+ "((dialog==null)?" +
+ " (dialog = new SearchDialog()):" +
+ " dialog" +
+ ").show();";
+
+ private static final String s2 = "((dialog==null)? (dialog = new SearchDialog()): dialog).show();";
+ private static final String s3 = "dialog = new SearchDialog()";
+
+ private static final String s4 =
+ " do { " +
+ " pattern = pattern.getNextSibling(); " +
+ " } " +
+ " while (pattern!=null && filterLexicalNodes(pattern));";
+
+ private static final String s5 =
+ "{ System.out.println();" +
+ " while(false) { " +
+ " do { " +
+ " pattern = pattern.getNextSibling(); " +
+ " } " +
+ " while (pattern!=null && filterLexicalNodes(pattern)); " +
+ " } " +
+ " do { " +
+ " pattern = pattern.getNextSibling(); " +
+ " } while (pattern!=null && filterLexicalNodes(pattern));" +
+ " { { " +
+ " do { " +
+ " pattern = pattern.getNextSibling(); " +
+ " } while (pattern!=null && filterLexicalNodes(pattern));" +
+ " } }" +
+ "}";
+
+ private static final String s6 =
+ " do { " +
+ " pattern.getNextSibling(); " +
+ " } " +
+ " while (pattern!=null && filterLexicalNodes(pattern));";
+
+ private static final String s7 =
+ " if (true) throw new UnsupportedPatternException(statement.toString());" +
+ " if (true) { " +
+ " throw new UnsupportedPatternException(statement.toString());" +
+ " } ";
+
+ private static final String s8 =
+ " if (true) { " +
+ " throw new UnsupportedPatternException(statement.toString());" +
+ " } ";
+
+ private static final String s9 = " if (true) throw new UnsupportedPatternException(statement.toString());";
+
+ private static final String s10 = "listener.add(new Runnable() { public void run() {} });";
+ private static final String s11 = " new XXX()";
+
+ private static final String s12 =
+ "new Runnable() {" +
+ " public void run() {" +
+ " matchContext.getSink().matchingFinished();" +
+ " } " +
+ " }";
+
+ private static final String s13 = "new Runnable() {}";
+ private static final String s14_1 = "if (true) { aaa(var); }";
+ private static final String s14_2 = "if (true) { aaa(var); bbb(var2); }\n if(1==1) { system.out.println('o'); }";
+ private static final String s15 = "'T;";
+ private static final String s16 = "if('_T) { '_T2; }";
+ private static final String s17 =
+ "token.getText().equals(token2.getText());" +
+ "token.getText().equals(token2.getText2());" +
+ "token.a.equals(token2.b);" +
+ "token.a.equals(token2.a);";
+ private static final String s18_1 = "'_T1.'_T2.equals('_T3.'_T2);";
+ private static final String s18_2 = "'_T1.'_T2().equals('_T3.'_T2());";
+ private static final String s18_3 = "'_T1.'_T2";
+ private static final String s19 = "Aaa a = (Aaa)b; Aaa c = (Bbb)d;";
+ private static final String s20 = "'_T1 'T2 = ('_T1)'_T3;";
+ private static final String s20_2 = "'_T1 '_T2 = ('_T1)'_T3;";
+ private static final String s21_1 = "'_T1:Aa* 'T2 = ('_T1)'_T3;";
+ private static final String s21_2 = "'_T1:A* 'T2 = ( '_T1:A+ )'_T3;";
+ private static final String s21_3 = "'_T1:Aa* 'T2 = ( '_T1:Aa* )'_T3;";
+
+ private static final String s22 = "Aaa a = (Aaa)b; Bbb c = (Bbb)d;";
+
+ private static final String s23 = "a[i] = 1; b[a[i]] = f(); if (a[i]==1) return b[c[i]];";
+ private static final String s24_1 = "'T['_T2:.*i.* ] = '_T3;";
+ private static final String s24_2 = "'T['_T2:.*i.* ]";
+ private static final String s25 = "class MatcherImpl { void doMatch(int a) {} }\n" +
+ "class Matcher { abstract void doMatch(int a);}\n " +
+ "class Matcher2Impl { void doMatch(int a, int b) {} } ";
+ private static final String s26 = "class 'T:.*Impl { '_T2 '_T3('_T4 '_T5) {\n\n} } ";
+ private static final String s27 = "class A {} interface B {}";
+ private static final String s28 = "interface 'T {}";
+
+ private static final String s29 = "class A { void B(int C) {} } class D { void E(double e) {} }";
+ private static final String s30 = "class '_ { void '_('_:int '_); } ";
+
+ private static final String s31 = "class A extends B { } class D extends B { } class C extends C {}";
+ private static final String s32 = "class '_ extends B { } ";
+
+ private static final String s33 = "class A implements B,C { } class D implements B,D { } class C2 implements C,B {}";
+ private static final String s34 = "class '_ implements B,C { } ";
+
+ private static final String s35 = "class A { int b; double c; void d() {} int e() {} } " +
+ "class A2 { int b; void d() {} }";
+ private static final String s36 = "class '_ { double '_; int '_; int '_() {} void '_() {} } ";
+
+ private static final String s37 = "class A { void d() throws B,C,D {} } class A2 { void d() throws B,C {} }";
+ private static final String s38 = "class 'T { '_ '_() throws D,C {} } ";
+
+ private static final String s39 = "class A extends B { } class A2 { }";
+ private static final String s40 = "class 'T { } ";
+
+ private static final String s41 = "class A extends B { int a = 1; } class B { int[] c= new int[2]; } " +
+ "class D { double e; } class E { int d; } ";
+ private static final String s42_1 = "class '_ { '_T '_T2 = '_T3; } ";
+ private static final String s42_2 = "class '_ { '_T '_T2; } ";
+
+ private static final String s43 = "interface A extends B { int B = 1; } " +
+ "interface D { public final static double e = 1; } " +
+ "interface E { final static ind d = 2; } " +
+ "interface F { } ";
+ private static final String s44 = "interface '_ { '_T 'T2 = '_T3; } ";
+ private static final String s45 = "class A extends B { private static final int B = 1; } " +
+ "class C extends D { int B = 1; }" +
+ "class E { }";
+
+ private static final String s46 = "class '_ { final static private '_T 'T2 = '_T3; } ";
+ private static final String s46_2 = "class '_ { '_T 'T2 = '_T3; } ";
+
+ private static final String s47 = "class C { java.lang.String t; } class B { BufferedString t2;} class A { String p;} ";
+ private static final String s48 = "class '_ { String '_; }";
+
+ private static final String s49 = "class C { void a() throws java.lang.RuntimeException {} } class B { BufferedString t2;}";
+ private static final String s50 = "class '_ { '_ '_() throws RuntimeException; }";
+
+ private static final String s51 = "class C extends B { } class B extends A { } class E {}";
+ private static final String s52 = "class '_ extends '_ { }";
+
+ private static final String s53 = "class C { " +
+ " String a = System.getProperty(\"abcd\"); " +
+ " static { String s = System.getProperty(a); }" +
+ " static void b() { String s = System.getProperty(a); }" +
+ " }";
+ private static final String s54 = "System.getProperty('T)";
+
+ private static final String s55 = " a = b.class; ";
+ private static final String s56 = "'T.class";
+
+ private static final String s57 = "{ /** @author Maxim */ class C { " +
+ "} " +
+ "class D {" +
+ "/** @serializable */ private int value; " +
+ "/** @since 1.4 */ void a() {} "+
+ "}" +
+ "class F { " +
+ "/** @since 1.4 */ void a() {} "+
+ "/** @serializable */ private int value2; " +
+ "}" +
+ "class G { /** @param a*/ void a() {} } }";
+ private static final String s57_2 = "/** @author Maxim */ class C { " +
+ "} " +
+ "class D {" +
+ "/** @serializable */ private int value; " +
+ "/** @since 1.4 */ void a() {} "+
+ "}" +
+ "class F { " +
+ "/** @since 1.4 */ void a() {} "+
+ "/** @serializable */ private int value2; " +
+ "}" +
+ "class G { /** @param a*/ void a() {} }";
+ private static final String s58 = "/** @'T '_T2 */ class '_ { }";
+ private static final String s58_2 = "class '_ { /** @serializable '_ */ '_ '_; }";
+ private static final String s58_3 = "class '_ { /** @'T 1.4 */ '_ '_() {} }";
+ private static final String s58_4 = "/** @'T '_T2 */";
+ private static final String s58_5 = "/** @'T '_T2? */";
+
+ private static final String s59 = "interface A { void B(); }";
+ private static final String s60 = "interface '_ { void '_(); }";
+
+ private static final String s61 = "{ a=b; c=d; return; } { e=f; } {}";
+ private static final String s62_1 = "{ 'T*; }";
+ private static final String s62_2 = "{ 'T+; }";
+ private static final String s62_3 = "{ 'T?; }";
+
+ private static final String s62_4 = "{ '_*; }";
+ private static final String s62_5 = "{ '_+; }";
+ private static final String s62_6 = "{ '_?; }";
+
+ private static final String s63 = " class A { A() {} } class B { public void run() {} }";
+ private static final String s63_2 = " class A { A() {} " +
+ "class B { public void run() {} } " +
+ "class D { public void run() {} } " +
+ "} " +
+ "class C {}";
+ private static final String s64 = " class 'T { public void '_T2:run () {} }";
+ private static final String s64_2 = "class '_ { class 'T { public void '_T2:run () {} } }";
+
+ private static final String s65 = " if (A instanceof B) {} else if (B instanceof C) {}";
+ private static final String s66 = " '_T instanceof '_T2:B";
+
+ private static final String s67 = " buf.append((VirtualFile)a);";
+ private static final String s68 = " (VirtualFile)'T";
+
+ private static final String s69 = " System.getProperties(); System.out.println(); java.lang.System.out.println(); some.other.System.out.println();";
+ private static final String s70 = " System.out ";
+ private static final String s70_2 = " java.lang.System.out ";
+
+ private static final String s71 = " class A { " +
+ "class D { D() { c(); } }" +
+ "void a() { c(); new MouseListenener() { void b() { c(); } } }" +
+ " }";
+ private static final String s72 = " c(); ";
+
+ private static final String s73 = " class A { int A; static int B=5; public abstract void a(int c); void q() { ind d=7; } }";
+ private static final String s74 = " '_Type 'Var = '_Init?; ";
+ private static final String s75 = "{ /** @class aClass\n @author the author */ class A {}\n" +
+ " /** */ class B {}\n" +
+ " /** @class aClass */ class C {} }";
+ private static final String s76 = " /** @'_tag+ '_value+ */";
+ private static final String s76_2 = " /** @'_tag* '_value* */";
+ private static final String s76_3 = " /** @'_tag? '_value? */ class 't {}";
+
+ private static final String s77 = " new ActionListener() {} ";
+ private static final String s78 = " class 'T:.*aaa {} ";
+
+ private static final String s79 = " class A { static { int c; } void a() { int b; b=1; }} ";
+ private static final String s80 = " { '_T 'T3 = '_T2?; '_*; } ";
+
+ private static final String s81 = "class Pair<First,Second> {" +
+ " <C,F> void a(B<C> b, D<F> e) throws C {" +
+ " P<Q> r = (S<T>)null;"+
+ " Q q = null; "+
+ " if (r instanceof S<T>) {}"+
+ " } " +
+ "} class Q { void b() {} } ";
+
+ private static final String s81_2 = "class Double<T> {} class T {} class Single<First extends A & B> {}";
+
+ private static final String s82 = "class '_<'T+> {}";
+ private static final String s82_2 = "'_Expr instanceof '_Type<'_Parameter+>";
+ private static final String s82_3 = "( '_Type<'_Parameter+> ) '_Expr";
+ private static final String s82_4 = "'_Type<'_Parameter+> 'a = '_Init?;";
+ private static final String s82_5 = "class '_ { <'_+> '_Type 'Method('_* '_*); }";
+ private static final String s82_6 = "class '_<'_+ extends 'res+> {}";
+ private static final String s82_7 = "'Type";
+
+ private static final String s83 = "/**\n" +
+ " * @hibernate.class\n" +
+ " * table=\"CATS\"\n" +
+ " */\n" +
+ "public class Cat {\n" +
+ " private Long id; // identifier\n" +
+ " private Date birthdate;\n" +
+ " /**\n" +
+ " * @hibernate.id\n" +
+ " * generator-class=\"native\"\n" +
+ " * column=\"CAT_ID\"\n" +
+ " */\n" +
+ " public Long getId() {\n" +
+ " return id;\n" +
+ " }\n" +
+ " private void setId(Long id) {\n" +
+ " this.id=id;\n" +
+ " }\n" +
+ "\n" +
+ " /**\n" +
+ " * @hibernate.property\n" +
+ " * column=\"BIRTH_DATE\"\n" +
+ " */\n" +
+ " public Date getBirthdate() {\n" +
+ " return birthdate;\n" +
+ " }\n" +
+ " void setBirthdate(Date date) {\n" +
+ " birthdate = date;\n" +
+ " }\n" +
+ " /**\n" +
+ " * @hibernate.property\n" +
+ " * column=\"SEX\"\n" +
+ " * not-null=\"true\"\n" +
+ " * update=\"false\"\n" +
+ " */\n" +
+ " public char getSex() {\n" +
+ " return sex;\n" +
+ " }\n" +
+ " void setSex(char sex) {\n" +
+ " this.sex=sex;\n" +
+ " }\n" +
+ "}";
+
+ private static final String s84 = " /**\n" +
+ " * @hibernate.property\n" +
+ " * 'Property+\n" +
+ " */\n";
+
+ private static final String s84_2 = " /**\n" +
+ " * @hibernate.property\n" +
+ " * update=\"fa.se\"\n" +
+ " */\n";
+
+ private static final String s85 = "{ int a; a=1; a=1; return a; }";
+ private static final String s86 = "'T; 'T;";
+
+ private static final String s87 = " getSomething(\"1\"); a.call(); ";
+ private static final String s88 = " '_Instance.'Call('_*); ";
+ private static final String s88_2 = " 'Call('_*); ";
+ private static final String s88_3 = " '_Instance?.'Call('_*); ";
+ private static final String s89 = "{ a = 1; b = 2; c=3; }";
+ private static final String s90 = "{ '_T*; '_T2*; }";
+ private static final String s90_2 = " { '_T*; '_T2*; '_T3+; } ";
+ private static final String s90_3 = " { '_T+; '_T2+; '_T3+; '_T4+; } ";
+ private static final String s90_4 = " { '_T{1,3}; '_T2{2}; } ";
+ private static final String s90_5 = " { '_T{1}?; '_T2*?; '_T3+?; } ";
+ private static final String s90_6 = " { '_T{1}?; '_T2{1,2}?; '_T3+?; '_T4+?; } ";
+
+ private static final String s91 = "class a {\n" +
+ " void b() {\n" +
+ " int c;\n" +
+ "\n" +
+ " c = 1;\n" +
+ " b();\n" +
+ " a a1;\n" +
+ " }\n" +
+ "}";
+ private static final String s92 = "'T:a";
+ private static final String s92_2 = "'T:b";
+ private static final String s92_3 = "'T:c";
+
+ private static final String s93 = " class A {" +
+ "private int field;" +
+ "public void b() {}" +
+ "}";
+ private static final String s94 = " class '_ {" +
+ "private void b() {}" +
+ "}";
+ private static final String s94_2 = " class '_ {" +
+ "public void b() {}" +
+ "}";
+ private static final String s94_3 = " class '_ {" +
+ "protected int field;" +
+ "}";
+ private static final String s94_4 = " class '_ {" +
+ "private int field;" +
+ "}";
+
+ private static final String s95 = " class Clazz {" +
+ "private int field;" +
+ "private int field2;" +
+ "private int fiel-d2;" +
+ "}";
+
+ private static final String s96 = " class '_ {" +
+ "private int 'T+:field.* ;" +
+ "}";
+
+ public void testSearchExpressions() {
+ assertFalse("subexpr match",findMatchesCount(s2,s3)==0);
+ assertEquals("search for new ",findMatchesCount(s10,s11),0);
+ assertEquals("search for anonymous classes",findMatchesCount(s12,s13),1);
+ // expr in definition initializer
+ assertEquals(
+ "expr in def initializer",
+ 3,
+ findMatchesCount(s53,s54)
+ );
+
+ // a.class expression search
+ assertEquals(
+ "a.class pattern",
+ findMatchesCount(s55,s56),
+ 1
+ );
+
+ String complexCode = "interface I { void b(); } interface I2 extends I {} class I3 extends I {} " +
+ "class A implements I2 { void b() {} } class B implements I3 { void b() {}} " +
+ "I2 a; I3 b; a.b(); b.b(); b.b(); A c; B d; c.b(); d.b(); d.b(); ";
+
+ String exprTypePattern1 = "'t:[exprtype( I2 )].b();";
+ String exprTypePattern2 = "'t:[!exprtype( I2 )].b();";
+
+ String exprTypePattern3 = "'t:[exprtype( *I2 )].b();";
+ String exprTypePattern4 = "'t:[!exprtype( *I2 )].b();";
+
+ assertEquals(
+ "expr type condition",
+ findMatchesCount(complexCode,exprTypePattern1),
+ 1
+ );
+
+ assertEquals(
+ "expr type condition 2",
+ 5,
+ findMatchesCount(complexCode,exprTypePattern2)
+ );
+
+ assertEquals(
+ "expr type condition 3",
+ findMatchesCount(complexCode,exprTypePattern3),
+ 2
+ );
+
+ assertEquals(
+ "expr type condition 4",
+ findMatchesCount(complexCode,exprTypePattern4),
+ 4
+ );
+
+ String complexCode2 = "enum X { XXX, YYY }\n class C { static void ordinal() {} void test() { C c; c.ordinal(); c.ordinal(); X.XXX.ordinal(); } }";
+ assertEquals(
+ "expr type condition with enums",
+ findMatchesCount(complexCode2, "'t:[exprtype( *java\\.lang\\.Enum )].ordinal()"),
+ 1
+ );
+
+ assertEquals(
+ "no smart detection of search target",
+ findMatchesCount("processInheritors(1,2,3,4); processInheritors(1,2,3); processInheritors(1,2,3,4,5,6);","'instance?.processInheritors('_param1{1,6});"),
+ 3
+ );
+
+ String arrays = "int[] a = new int[20];\n" +
+ "byte[] b = new byte[30]";
+ String arrayPattern = "new int[$a$]";
+ assertEquals(
+ "Improper array search",
+ 1,
+ findMatchesCount(arrays,arrayPattern)
+ );
+
+ String someCode = "a *= 2; a+=2;";
+ String otherCode = "a *= 2;";
+
+ assertEquals(
+ "Improper *= 2 search",
+ 1,
+ findMatchesCount(someCode,otherCode)
+ );
+
+ String s1 = "Thread t = new Thread(\"my thread\",\"my another thread\") {\n" +
+ " public void run() {\n" +
+ " // do stuff\n" +
+ " }\n" +
+ "}";
+ String s2 = "new Thread('args*) { '_Other* }";
+
+ assertEquals(
+ "Find inner class parameters",
+ 2,
+ findMatchesCount(s1,s2)
+ );
+
+ String s3 = "Thread t = new Thread(\"my thread\") {\n" +
+ " public void run() {\n" +
+ " // do stuff\n" +
+ " }\n" +
+ "};";
+ String s4 = "new Thread($args$)";
+
+ assertEquals(
+ "Find inner class by new",
+ 1,
+ findMatchesCount(s3,s4)
+ );
+
+ String s5 = "class A {\n" +
+ "public static <T> T[] copy(T[] array, Class<T> aClass) {\n" +
+ " int i = (int)0;\n" +
+ " int b = (int)0;\n" +
+ " return (T[])array.clone();\n" +
+ " }\n" +
+ "}";
+ String s6 = "($T$[])$expr$";
+
+ assertEquals(
+ "Find cast to array",
+ 1,
+ findMatchesCount(s5,s6)
+ );
+
+ String s7 = "import java.math.BigDecimal;\n" +
+ "\n" +
+ "public class Prorator {\n" +
+ " public void prorate(BigDecimal[] array) {\n" +
+ " // do nothing\n" +
+ " }\n" +
+ " public void prorate2(java.math.BigDecimal[] array) {\n" +
+ " // do nothing\n" +
+ " }\n" +
+ " public void prorate(BigDecimal bd) {\n" +
+ " // do nothing\n" +
+ " }\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " BigDecimal[] something = new BigDecimal[2];\n" +
+ " java.math.BigDecimal[] something2 = new BigDecimal[2];\n" +
+ " something[0] = new BigDecimal(1.0);\n" +
+ " something[1] = new BigDecimal(1.0);\n" +
+ "\n" +
+ " Prorator prorator = new Prorator();\n" +
+ "\n" +
+ "// ---------------------------------------------------\n" +
+ "// the line below should've been found, in my opinion.\n" +
+ "// --------------------------------------------------\n" +
+ " prorator.prorate(something);\n" +
+ " prorator.prorate(something2);\n" +
+
+ " prorator.prorate(something[0]);\n" +
+ " prorator.prorate(something[1]);\n" +
+ " prorator.prorate(something[0]);\n" +
+ " }\n" +
+ "}";
+ String s8 = "'_Instance.'_MethodCall:[regex( prorate )]('_Param:[exprtype( BigDecimal\\[\\] )]) ";
+
+ assertEquals(
+ "Find method call with array for parameter expr type",
+ 2,
+ findMatchesCount(s7,s8,true)
+ );
+
+ String s13 = "try { } catch(Exception e) { e.printStackTrace(); }";
+ String s14 = "'_Instance.'_MethodCall('_Parameter*)";
+
+ assertEquals(
+ "Find statement in catch",
+ 1,
+ findMatchesCount(s13,s14)
+ );
+
+ String s9 = "int a[] = new int[] { 1,2,3,4};\n" +
+ "int b[] = { 2,3,4,5 };\n" +
+ "Object[] c = new Object[] { \"\", null};";
+ String s10 = "new '_ []{ '_* }";
+ String s10_2 = "new int []{ '_* }";
+
+ assertEquals(
+ "Find array instatiation",
+ 3,
+ findMatchesCount(s9,s10)
+ );
+
+ assertEquals(
+ "Find array instatiation, 2",
+ 2,
+ findMatchesCount(s9,s10_2)
+ );
+ }
+
+ public void testLiteral() {
+ String s = "class A {\n" +
+ " static String a = 1;\n" +
+ " static String s = \"aaa\";\n" +
+ " static String s2;\n" +
+ "}";
+ String s2 = "static String '_FieldName = '_Init?:[!regex( \".*\" )];";
+ String s2_2 = "static String '_FieldName = '_Init:[!regex( \".*\" )];";
+
+ assertEquals(
+ "Literal",
+ 2,
+ findMatchesCount(s,s2)
+ );
+
+ assertEquals(
+ "Literal, 2",
+ 1,
+ findMatchesCount(s,s2_2)
+ );
+ }
+
+ public void testCovariantArraySearch() {
+ String s1 = "String[] argv;";
+ String s2 = "String argv;";
+ String s3 = "'T[] argv;";
+ String s3_2 = "'T:*Object [] argv;";
+
+ assertEquals(
+ "Find array types",
+ 0,
+ findMatchesCount(s1,s2)
+ );
+
+ assertEquals(
+ "Find array types, 2",
+ 0,
+ findMatchesCount(s2,s1)
+ );
+
+ assertEquals(
+ "Find array types, 3",
+ 0,
+ findMatchesCount(s2,s3)
+ );
+
+ assertEquals(
+ "Find array types, 3",
+ 1,
+ findMatchesCount(s1,s3_2)
+ );
+
+ String s11 = "class A {\n" +
+ " void main(String[] argv);" +
+ " void main(String argv[]);" +
+ " void main(String argv);" +
+ "}";
+ String s12 = "'_t:[regex( *Object\\[\\] ) ] '_t2";
+ String s12_2 = "'_t:[regex( *Object ) ] '_t2 []";
+ String s12_3 = "'_t:[regex( *Object ) ] '_t2";
+
+ assertEquals(
+ "Find array covariant types",
+ 2,
+ findMatchesCount(s11,s12)
+ );
+
+ assertEquals(
+ "Find array covariant types, 2",
+ 2,
+ findMatchesCount(s11,s12_2)
+ );
+
+ assertEquals(
+ "Find array covariant types, 3",
+ 1,
+ findMatchesCount(s11,s12_3)
+ );
+
+ String source = "class A { String ss[][]; }";
+ String target = "String[][] $s$;";
+ assertEquals(
+ "should find multi dimensional c-style array declarations",
+ 1,
+ findMatchesCount(source, target)
+ );
+ }
+
+ // @todo support back references (\1 in another reg exp or as fild member)
+ //private static final String s1002 = " setSSS( instance.getSSS() ); " +
+ // " setSSS( instance.SSS ); ";
+ //private static final String s1003 = " 't:set(.+) ( '_.get't_1() ); ";
+ //private static final String s1003_2 = " 't:set(.+) ( '_.'t_1 ); ";
+
+ public void testSearchStatements() {
+ assertEquals("statement search",findMatchesCount(s1,s2),1);
+ assertEquals("several constructions match",findMatchesCount(s5,s4),3);
+ assertFalse("several constructions 2",(findMatchesCount(s5,s6))!=0);
+
+ assertEquals("several constructions 3",findMatchesCount(s7,s8),2);
+ assertEquals("several constructions 4",findMatchesCount(s7,s9),2);
+
+ final String s1000 = "{ lastTest = \"search for parameterized pattern\";\n" +
+ " matches = testMatcher.findMatches(s14_1,s15, options);\n" +
+ " if (matches.size()!=2 ) return false;\n" +
+ "lastTest = \"search for parameterized pattern\";\n" +
+ " matches = testMatcher.findMatches(s14_1,s15, options);\n" +
+ " if (matches.size()!=2 ) return false; }";
+ final String s1001 = "lastTest = '_Descr; " +
+ " matches = testMatcher.findMatches('_In,'_Pattern, options);\n" +
+ " if (matches.size()!='_Number ) return false;";
+
+ assertEquals("several operators 5",findMatchesCount(s1000,s1001),2);
+
+ assertEquals(
+ "two the same statements search",
+ findMatchesCount(s85,s86),
+ 1
+ );
+
+ assertEquals(
+ "search for simple call",
+ findMatchesCount(s87,s88),
+ 1
+ );
+
+ assertEquals(
+ "search for simple call 2",
+ findMatchesCount(s87,s88_2),
+ 1
+ );
+
+ assertEquals(
+ "search for simple call 3",
+ findMatchesCount(s87,s88_3),
+ 2
+ );
+
+ String s10015 = "DocumentListener[] listeners = getCachedListeners();";
+ String s10016 = "'_Type 'Var = '_Call();";
+
+ assertEquals(
+ "search for definition with init",
+ 1,
+ findMatchesCount(s10015,s10016)
+ );
+
+ String s10017 = "a = b; b = c; a=a; c=c;";
+ String s10018 = "'_a = '_a;";
+
+ assertEquals(
+ "search silly assignments",
+ 2,
+ findMatchesCount(s10017,s10018)
+ );
+
+ String s10019 = "a.b(); a.b(null); a.b(null, 1);";
+ String s10020 = "a.b(null);";
+
+ assertEquals(
+ "search parameter",
+ 1,
+ findMatchesCount(s10019,s10020)
+ );
+
+ String s1008 = "int a, b, c, d; int a,b,c; int c,d; int e;";
+ String s1009 = "int '_a{3,4};";
+
+ assertEquals(
+ "search many declarations",
+ 2,
+ findMatchesCount(s1008,s1009)
+ );
+
+ String s1 = "super(1,1); call(1,1); call(2,2);";
+ String s2 = "super('_t*);";
+
+ assertEquals(
+ "search super",
+ 1,
+ findMatchesCount(s1,s2)
+ );
+
+ String s10021 = "short a = 1;\n" +
+ "short b = 2;\n" +
+ "short c = a.b();";
+ String s10022 = "short '_a = '_b.b();";
+
+ assertEquals(
+ "search def init bug",
+ 1,
+ findMatchesCount(s10021,s10022)
+ );
+
+ String s10023 = "abstract class A { public abstract short getType(); }\n" +
+ "A a;\n" +
+ "switch(a.getType()) {\n" +
+ " default:\n" +
+ " return 0;\n" +
+ "}\n" +
+ "switch(a.getType()) {\n" +
+ " case 1:\n" +
+ " { return 0; }\n" +
+ "}";
+ String s10024 = "switch('_a:[exprtype( short )]) { '_statement*; }";
+ assertEquals(
+ "finding switch",
+ 2,
+ findMatchesCount(s10023,s10024)
+ );
+
+ String s10025 = "A[] a;\n" +
+ "A b[];\n" +
+ "A c;";
+ String s10026 = "A[] 'a;";
+ String s10026_2 = "A 'a[];";
+
+ assertEquals(
+ "array types in dcl",
+ 2,
+ findMatchesCount(s10025,s10026)
+ );
+
+ assertEquals(
+ "array types in dcl 2",
+ 2,
+ findMatchesCount(s10025,s10026_2)
+ );
+
+ String s10027 = "try { a(); } catch(Exception ex) {}\n" +
+ "try { a(); } finally {}\n" +
+ "try { a(); } catch(Exception ex) {} finally {} \n";
+ String s10028 = "try { a(); } finally {}\n";
+ assertEquals(
+ "finally matching",
+ 2,
+ findMatchesCount(s10027,s10028)
+ );
+
+ String s10029 = "for(String a:b) { System.out.println(a); }";
+ String s10030 = "for(String a:b) { '_a; }";
+ assertEquals(
+ "for each matching",
+ 1,
+ findMatchesCount(s10029,s10030)
+ );
+
+ String s10031 = "try { a(); } catch(Exception ex) {} catch(Error error) { 1=1; }\n" +
+ "try { a(); } catch(Exception ex) {}";
+ String s10032 = "try { a(); } catch('_Type+ 'Arg+) { 'Statements*; }\n";
+ assertEquals(
+ "finally matching",
+ 2,
+ findMatchesCount(s10031,s10032)
+ );
+
+ String s10033 = "return x;\n" +
+ "return !x;\n" +
+ "return (x);\n" +
+ "return (x);\n" +
+ "return !(x);";
+ String s10034 = "return ('a);";
+ assertEquals("Find statement with parenthesized expr",2,findMatchesCount(s10033,s10034));
+ }
+
+ public void testSearchClass() {
+ // no modifier list in interface vars
+ assertEquals(
+ "no modifier for interface vars",
+ findMatchesCount(s43,s44),
+ 3
+ );
+
+ // different order of access modifiers
+ assertEquals(
+ "different order of access modifiers",
+ findMatchesCount(s45,s46),
+ 1
+ );
+
+ // no access modifiers
+ assertEquals(
+ "no access modifier",
+ findMatchesCount(s45,s46_2),
+ 2
+ );
+
+ // type could differ with package
+ assertEquals(
+ "type differs with package",
+ findMatchesCount(s47,s48),
+ 2
+ );
+
+ // reference element could differ in package
+ assertEquals(
+ "reference could differ in package",
+ findMatchesCount(s49,s50),
+ 1
+ );
+
+ String s51 = "class C extends java.awt.List {} class A extends java.util.List {} class B extends java.awt.List {} ";
+ String s52 = "class 'B extends '_C:java\\.awt\\.List {}";
+
+ assertEquals(
+ "reference could differ in package 2",
+ findMatchesCount(s51,s52),
+ 2
+ );
+
+ assertEquals(
+ "method access modifier",
+ findMatchesCount(s93,s94),
+ 0
+ );
+
+ assertEquals(
+ "method access modifier 2",
+ findMatchesCount(s93,s94_2),
+ 1
+ );
+
+ assertEquals(
+ "field access modifier",
+ findMatchesCount(s93,s94_3),
+ 0
+ );
+
+ assertEquals(
+ "field access modifier 2",
+ findMatchesCount(s93,s94_4),
+ 1
+ );
+
+ final String s127 = "class a { void b() { new c() {}; } }";
+ final String s128 = "class 't {}";
+ assertEquals(
+ "class finds anonymous class",
+ findMatchesCount(s127,s128),
+ 2
+ );
+
+ final String s129 = "class a { public void run() {} }\n" +
+ "class a2 { public void run() { run(); } }\n" +
+ "class a3 { public void run() { run(); } }\n" +
+ "class a4 { public void run(); }";
+
+ final String s130 = "class 'a { public void run() {} }";
+ final String s130_2 = "class 'a { public void run() { '_statement; } }";
+ final String s130_3 = "class 'a { public void run(); }";
+
+ assertEquals(
+ "empty method finds empty method only",
+ findMatchesCount(s129,s130),
+ 1
+ );
+
+ assertEquals(
+ "nonempty method finds nonempty method",
+ findMatchesCount(s129,s130_2),
+ 2
+ );
+
+ assertEquals(
+ "nonempty method finds nonempty method",
+ findMatchesCount(s129,s130_3),
+ 4
+ );
+
+ final String s133 = "class S {\n" +
+ "void cc() {\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " f();\n" +
+ " }\n" +
+ " private void f() {\n" +
+ " //To change body of created methods use File | Settings | File Templates.\n" +
+ " }\n" +
+ " };\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " f();\n" +
+ " }\n" +
+ " private void g() {\n" +
+ " //To change body of created methods use File | Settings | File Templates.\n" +
+ " }\n" +
+ " };\n" +
+ " new Runnable() {\n" +
+ " public void run() {\n" +
+ " f();\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ " private void f() {\n" +
+ " //To change body of created methods use File | Settings | File Templates.\n" +
+ " }\n" +
+ "} ";
+ final String s134 = "new Runnable() {\n" +
+ " public void run() {\n" +
+ " '_f ();\n" +
+ " }\n" +
+ " private void '_f ();\n" +
+ " }";
+ assertEquals(
+ "complex expr matching",
+ 1,
+ findMatchesCount(s133,s134)
+ );
+
+ final String s135 = "abstract class My {\n" +
+ " abstract void f();\n" +
+ "}\n" +
+ "abstract class My2 {\n" +
+ " abstract void f();\n" +
+ " void fg() {}\n" +
+ "}";
+ final String s136 = "class 'm {\n" +
+ " void f();\n" +
+ " '_type '_method{0,0} ('_paramtype* '_paramname* );\n" +
+ "}";
+ assertEquals(
+ "reject method with 0 max occurence",
+ findMatchesCount(s135,s136),
+ 1
+ );
+
+ final String s137 = "abstract class My {\n" +
+ " int a;\n" +
+ "}\n" +
+ "abstract class My2 {\n" +
+ " Project b;\n" +
+ "}" +
+ "abstract class My3 {\n" +
+ " Class clazz;"+
+ " Project b = null;\n" +
+ "}" +
+ "abstract class My {\n" +
+ " int a = 1;\n" +
+ "}\n";
+ final String s138 = "class 'm {\n" +
+ " Project '_f{0,0} = '_t?;\n" +
+ "}";
+ assertEquals(
+ "reject field with 0 max occurence",
+ findMatchesCount(s137,s138),
+ 2
+ );
+
+ final String s139 = "class My { boolean equals(Object o); int hashCode(); }";
+ final String s139_2 = "class My { boolean equals(Object o); }";
+ final String s140 = "class 'A { boolean equals(Object '_o ); int '_hashCode{0,0}:hashCode (); }";
+
+ assertEquals(
+ "reject method with constraint",
+ findMatchesCount(s139,s140),
+ 0
+ );
+
+ assertEquals(
+ "reject field with 0 max occurence",
+ findMatchesCount(s139_2,s140),
+ 1
+ );
+
+ final String s141 = "class A { static { a = 10 } }\n" +
+ "class B { { a = 10; } }\n" +
+ "class C { { a = 10; } }";
+ final String s142 = "class '_ { static { a = 10; } } ";
+ assertEquals(
+ "static block search",
+ findMatchesCount(s141,s142),
+ 1
+ );
+ }
+
+ public void testParameterlessContructorSearch() {
+ final String s143 = "class A { A() {} };\n" +
+ "class B { B(int a) {} };\n" +
+ "class C { C() {} C(int a) {} };\n" +
+ "class D {}\n" +
+ "class E {}";
+ final String s144 = "class '_a { '_d{0,0}:[ script( \"__context__.constructor\" ) ]('_b+ '_c+); }";
+ assertEquals(
+ "parameterless contructor search",
+ 3,
+ findMatchesCount(s143,s144)
+ );
+ }
+
+ public void testCheckScriptValidation() {
+ final String s1 = "";
+ final String s2 = "'_b:[script( \"^^^\" )]";
+
+ try {
+ final int count = findMatchesCount(s1, s2);
+ assertFalse("Validation does not work", true);
+ } catch (MalformedPatternException ex) {}
+ }
+
+ //public void testRelationBetweenVars() {
+ // final String s1 = "public class Foo {\n" +
+ // " public static final Logger log = Logger.getInstance(Foo.class);\n" +
+ // " public static final Logger log2 = Logger.getInstance(Foo2.class);\n" +
+ // " public static final Logger log3 = Logger.getInstance(Foo2.class);\n" +
+ // "}";
+ // final String s2 = "class '_a { static Logger 'log+ = Logger.getInstance('_b:[script( \"_a != _b\" )].class); }";
+ // assertEquals(
+ // "relation between vars in script",
+ // 2,
+ // findMatchesCount(s1,s2)
+ // );
+ //}
+
+ public void testExprTypeWithObject() {
+ String s1 = "import java.util.*;\n" +
+ "class A {\n" +
+ " void b() {\n" +
+ " Map map = new HashMap();" +
+ " class AppPreferences {}\n" +
+ " String key = \"key\";\n" +
+ " AppPreferences value = new AppPreferences();\n" +
+ " map.put(key, value );\n" +
+ " map.put(value, value );\n" +
+ " map.put(\"key\", value );\n" +
+ " map.put(\"key\", new AppPreferences());\n" +
+ " }\n" +
+ "}";
+ String s2 = "'_map:[exprtype( *java\\.util\\.Map )].put('_key:[ exprtype( *Object ) ], '_value:[ exprtype( *AppPreferences ) ]);";
+
+ assertEquals(
+ "expr type with object",
+ 4,
+ findMatchesCount(s1,s2,true)
+ );
+ }
+
+ public void testInterfaceImplementationsSearch() {
+ String in = "class A implements Cloneable {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " class B implements Serializable {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " class C implements Cloneable,Serializable {\n" +
+ " \n" +
+ " }\n" +
+ " class C2 implements Serializable,Cloneable {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " class E extends B implements Cloneable {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " class F extends A implements Serializable {\n" +
+ " \n" +
+ " }\n" +
+ " \n" +
+ " class D extends C {\n" +
+ " \n" +
+ " }";
+ String what = "class 'A implements '_B:*Serializable , '_C:*Cloneable {}";
+ assertEquals(
+ "search interface within hierarchy",
+ 5,
+ findMatchesCount(in, what)
+ );
+ }
+
+ public void testSearchBacktracking() {
+ assertEquals(
+ "backtracking greedy regexp",
+ findMatchesCount(s89,s90),
+ 1
+ );
+
+ assertEquals(
+ "backtracking greedy regexp 2",
+ findMatchesCount(s89,s90_2),
+ 1
+ );
+
+ assertEquals(
+ "backtracking greedy regexp 3",
+ findMatchesCount(s89,s90_3),
+ 0
+ );
+
+ assertEquals(
+ "counted regexp (with back tracking)",
+ findMatchesCount(s89,s90_4),
+ 1
+ );
+
+ assertEquals(
+ "nongreedy regexp (counted, with back tracking)",
+ findMatchesCount(s89,s90_5),
+ 1
+ );
+
+ assertEquals(
+ "nongreedy regexp (counted, with back tracking) 2",
+ findMatchesCount(s89,s90_6),
+ 0
+ );
+
+ String s1000 = "class A {\n" +
+ " void _() {}\n" +
+ " void a(String in, String pattern) {}\n" +
+ " }";
+ String s1001 = "class '_Class { \n" +
+ " '_ReturnType+ 'MethodName+ ('_ParameterType* '_Parameter* );\n" +
+ "}";
+ assertEquals(
+ "handling of no match",
+ findMatchesCount(s1000,s1001),
+ 2
+ );
+ }
+
+ public void testSearchSymbol() {
+ final String s131 = "a.b(); c.d = 1; ";
+ final String s132 = "'T:b|d";
+
+ assertEquals(
+ "symbol match",
+ 2,
+ findMatchesCount(s131,s132)
+ );
+
+ final String s129 = "A a = new A();";
+ final String s130 = "'Sym:A";
+
+ options.setCaseSensitiveMatch(true);
+ assertEquals(
+ "case sensitive match",
+ findMatchesCount(s129,s130),
+ 2
+ );
+
+ options.setDistinct(true);
+ assertEquals(
+ "case sensitive disitinct match",
+ findMatchesCount(s129,s130),
+ 1
+ );
+
+ options.setDistinct(false);
+
+ final String s133 = "class C { int a; int A() { a = 1; }} void c(int a) { a = 2; }";
+ final String s133_2 = "class C { int a() {} int A() { a(1); }}";
+ final String s134 = "a";
+
+ List<MatchResult> results = findMatches(s133, s134, true, StdFileTypes.JAVA);
+ assertEquals(
+ "find sym finds declaration",
+ 4, results.size()
+ );
+
+ assertEquals(
+ "find sym finds declaration",
+ 2, findMatchesCount(s133_2, s134, true)
+ );
+ }
+
+ public void testSearchGenerics() {
+ assertEquals(
+ "parameterized class match",
+ findMatchesCount(s81,s82),
+ 2
+ );
+
+ assertEquals(
+ "parameterized instanceof match",
+ findMatchesCount(s81,s82_2),
+ 1
+ );
+
+ assertEquals(
+ "parameterized cast match",
+ findMatchesCount(s81,s82_3),
+ 1
+ );
+
+ assertEquals(
+ "parameterized definition match",
+ findMatchesCount(s81,s82_4),
+ 3
+ );
+
+ assertEquals(
+ "parameterized method match",
+ findMatchesCount(s81,s82_5),
+ 1
+ );
+
+ assertEquals(
+ "parameterized constraint match",
+ findMatchesCount(s81_2,s82_6),
+ 2
+ );
+
+ assertEquals(
+ "symbol matches parameterization",
+ findMatchesCount(s81,s82_7),
+ 29
+ );
+
+ assertEquals(
+ "symbol matches parameterization 2",
+ findMatchesCount(s81_2,s82_7),
+ 7
+ );
+
+ String s81_3 = " class A {\n" +
+ " public static <T> Collection<T> unmodifiableCollection(int c) {\n" +
+ " return new d<T>(c);\n" +
+ " }\n" +
+ " static class d<E> implements Collection<E>, Serializable {\n" +
+ " public <T> T[] toArray(T[] a) {return c.toArray(a);}\n" +
+ " }\n" +
+ "}";
+ assertEquals(
+ "typed symbol symbol",
+ findMatchesCount(s81_3,s82_5),
+ 2
+ );
+
+ String s81_4="class A<B> { \n" +
+ " static <C> void c(D<E> f) throws R<S> {\n" +
+ " if ( f instanceof G<H>) {\n" +
+ " ((I<G<K>>)l).a();\n" +
+ " throw new P<Q>();" +
+ " }\n" +
+ " }\n" +
+ "} " +
+ "class C {\n" +
+ " void d(E f) throws Q {\n" +
+ " if (g instanceof H) { a.c(); b.d(new A() {}); throw new Exception(((I)k)); }"+
+ " }\n" +
+ "}";
+ String s82_8 = "'T<'_Subst+>";
+ assertEquals(
+ "typed symbol",
+ findMatchesCount(s81_4,s82_8),
+ 6
+ );
+
+ String s81_5 = "class A { HashMap<String, Integer> variable = new HashMap<String, Integer>(\"aaa\");}";
+ String s82_9 = "'_Type<'_GType, '_GType2> '_instance = new '_Type<'_GType, '_GType2>('_Param);";
+ assertEquals(
+ "generic vars in new",
+ findMatchesCount(s81_5,s82_9),
+ 1
+ );
+ String source1 = "class Comparator<T> { private Comparator<String> c; private Comparator d; }";
+ String target1 = "java.util.Comparator 'a;";
+ assertEquals(
+ "qualified type should not match 1",
+ 0,
+ findMatchesCount(source1, target1)
+ );
+
+ String target2 = "java.util.Comparator<String> 'a;";
+ assertEquals(
+ "qualified type should not match 2",
+ 0,
+ findMatchesCount(source1, target2)
+ );
+
+ // @todo typed vars constrains (super),
+ // @todo generic method invocation
+
+ //String s83 = "class A {} List<A> a; List b;";
+ //String s84 = "'a:List 'c;";
+ //String s84_2 = "'a:List\\<'_\\> 'c;";
+ //String s84_3 = "'a:List(?>\\<'_\\>) 'c;";
+ //
+ //assertEquals(
+ // "finding list",
+ // findMatchesCount(s83,s84),
+ // 2
+ //);
+ //
+ //assertEquals(
+ // "finding list 2",
+ // findMatchesCount(s83,s84_2),
+ // 1
+ //);
+ //
+ //assertEquals(
+ // "finding list 3",
+ // findMatchesCount(s83,s84_3),
+ // 1
+ //);
+ }
+
+ public void testSearchSubstitutions() {
+ // searching for parameterized pattern
+ assertEquals("search for parameterized pattern",findMatchesCount(s14_1,s15),2);
+
+ assertEquals("search for parameterized pattern 2",findMatchesCount(s14_2,s15),5);
+
+ options.setRecursiveSearch(false);
+
+ assertEquals("search for parameterized pattern-non-recursive",findMatchesCount(s14_1,s15),1);
+
+ assertEquals("search for parameterized pattern 2-non-recursive",findMatchesCount(s14_2,s15),2);
+
+ // typed vars with arrays
+ assertEquals("typed pattern with array 2-non-recursive",findMatchesCount(s23,s24_2),4);
+
+ options.setRecursiveSearch(true);
+
+ // searching for parameterized pattern
+ assertEquals("search for parameterized pattern 3",findMatchesCount(s14_2,s16),1);
+
+ // searching for parameterized pattern in complex expr (with field selection)
+ assertEquals("search for parameterized pattern in field selection",findMatchesCount(s17,s18_1),1);
+
+ // searching for parameterized pattern in complex expr (with method call)
+ assertEquals("search for parameterized pattern with method call",findMatchesCount(s17,s18_2),1);
+
+ // searching for parameterized pattern in complex expr (with method call)
+ assertEquals("search for parameterized pattern with method call ep.2",findMatchesCount(s17,s18_3),4);
+
+ // searching for parameterized pattern in definition with initializer
+ assertEquals("search for same var constraint",findMatchesCount(s19,s20),1);
+
+ // searching for semi anonymous parameterized pattern in definition with initializer
+ assertEquals("search for same var constraint for semi anonymous typed vars",findMatchesCount(s19,s20_2),1);
+
+ // support for type var constraint
+ assertEquals("search for typed var constraint",findMatchesCount(s22,s21_1),1);
+
+ // noncompatible same typed var constraints
+ try {
+ findMatchesCount(s22,s21_2);
+ assertFalse("search for noncompatible typed var constraint",false);
+ } catch(MalformedPatternException e) {
+ }
+
+ // compatible same typed var constraints
+ assertEquals("search for same typed var constraint",findMatchesCount(s22,s21_3),1);
+
+ // typed var with instanceof
+ assertEquals("typed instanceof",findMatchesCount(s65,s66),1);
+
+ // typed vars with arrays
+ assertEquals("typed pattern with array",findMatchesCount(s23,s24_1),2);
+
+ // typed vars with arrays
+ assertEquals("typed pattern with array 2",findMatchesCount(s23,s24_2),6);
+
+ // typed vars in class name, method name, its return type, parameter type and name
+ assertEquals("typed pattern in class name, method name, return type, parameter type and name",findMatchesCount(s25,s26),1);
+
+ assertEquals(
+ "finding interface",
+ findMatchesCount(s27,s28),
+ 1
+ );
+
+ // finding anonymous type vars
+ assertEquals(
+ "anonymous typed vars",
+ findMatchesCount(s29,s30),
+ 1
+ );
+
+ // finding descedants
+ assertEquals(
+ "finding class descendants",
+ findMatchesCount(s31,s32),
+ 2
+ );
+
+ // finding interface implementation
+ assertEquals(
+ "interface implementation",
+ findMatchesCount(s33,s34),
+ 2
+ );
+
+ // different order of fields and methods
+ assertEquals(
+ "different order of fields and methods",
+ findMatchesCount(s35,s36),
+ 1
+ );
+
+ // different order of exceptions in throws
+ assertEquals(
+ "differend order in throws",
+ findMatchesCount(s37,s38),
+ 1
+ );
+
+ // class pattern without extends matches pattern with extends
+ assertEquals(
+ "match of class without extends to class with it",
+ findMatchesCount(s39,s40),
+ 2
+ );
+
+ // class pattern without extends matches pattern with extends
+ assertEquals(
+ "match of class without extends to class with it, ep. 2",
+ findMatchesCount(s41,s42_1),
+ 2
+ );
+
+ // class pattern without extends matches pattern with extends
+ assertEquals(
+ "match of class without extends to class with it, ep 3",
+ findMatchesCount(s41,s42_2),
+ 2
+ );
+
+ // typed reference element
+ assertEquals(
+ "typed reference element",
+ findMatchesCount(s51,s52),
+ 2
+ );
+
+ // empty name of type var
+ assertEquals(
+ "empty name for typed var",
+ findMatchesCount(s59,s60),
+ 1
+ );
+
+ // comparing method with constructor
+ assertEquals(
+ "comparing method with constructor",
+ findMatchesCount(s63,s64),
+ 1
+ );
+
+ // comparing method with constructor
+ assertEquals(
+ "finding nested class",
+ findMatchesCount(s63_2,s64),
+ 2
+ );
+
+ // comparing method with constructor
+ assertEquals(
+ "finded nested class by special pattern",
+ findMatchesCount(s63_2,s64_2),
+ 1
+ );
+
+ assertEquals(
+ "* regexp for typed var",
+ findMatchesCount(s61,s62_1),
+ 5
+ );
+
+ assertEquals(
+ "+ regexp for typed var",
+ findMatchesCount(s61,s62_2),
+ 4
+ );
+
+ assertEquals(
+ "? regexp for typed var",
+ findMatchesCount(s61,s62_3),
+ 2
+ );
+
+ assertEquals(
+ "cast in method parameters",
+ findMatchesCount(s67,s68),
+ 1
+ );
+
+ assertEquals(
+ "searching for static field in static call",
+ 2,
+ findMatchesCount(s69,s70)
+ );
+
+ assertEquals(
+ "searching for static field in static call, 2",
+ 2,
+ findMatchesCount(s69,s70_2)
+ );
+
+ assertEquals(
+ "* regexp for anonymous typed var",
+ findMatchesCount(s61,s62_4),
+ 3
+ );
+
+ assertEquals(
+ "+ regexp for anonymous typed var",
+ findMatchesCount(s61,s62_5),
+ 2
+ );
+
+ assertEquals(
+ "? regexp for anonymous typed var",
+ findMatchesCount(s61,s62_6),
+ 2
+ );
+
+ assertEquals(
+ "statement inside anonymous class",
+ findMatchesCount(s71,s72),
+ 3
+ );
+
+ assertEquals(
+ "clever regexp match",
+ findMatchesCount(s91,s92),
+ 2
+ );
+
+ assertEquals(
+ "clever regexp match 2",
+ findMatchesCount(s91,s92_2),
+ 2
+ );
+
+ assertEquals(
+ "clever regexp match 3",
+ findMatchesCount(s91,s92_3),
+ 2
+ );
+ }
+
+ public void testSearchJavaDoc() {
+ // javadoc comment in class
+ assertEquals(
+ "java doc comment in class",
+ 1,
+ findMatchesCount(s57,s58)
+ );
+
+ assertEquals(
+ "java doc comment in class in file",
+ 1,
+ findMatchesCount(s57_2,s58,true)
+ );
+
+ // javadoc comment for field
+ assertEquals(
+ "javadoc comment for field",
+ 2,
+ findMatchesCount(s57, s58_2)
+ );
+
+ // javadoc comment for method
+ assertEquals(
+ "javadoc comment for method",
+ 3,
+ findMatchesCount(s57, s58_3)
+ );
+
+ // just javadoc comment search
+ assertEquals(
+ "just javadoc comment search",
+ 4,
+ findMatchesCount(s57,s58_4)
+ );
+
+ assertEquals(
+ "XDoclet metadata",
+ 2,
+ findMatchesCount(s83,s84)
+ );
+
+ assertEquals(
+ "XDoclet metadata 2",
+ 1,
+ findMatchesCount(s83,s84_2)
+ );
+
+ assertEquals(
+ "optional tag value match",
+ 6,
+ findMatchesCount(s57, s58_5)
+ );
+
+ assertEquals(
+ "multiple tags match +",
+ 2,
+ findMatchesCount(s75,s76)
+ );
+
+ assertEquals(
+ "multiple tags match *",
+ 3,
+ findMatchesCount(s75, s76_2)
+ );
+
+ assertEquals(
+ "multiple tags match ?",
+ 3,
+ findMatchesCount(s75, s76_3)
+ );
+
+ }
+
+ public void testNamedPatterns() {
+ String s133 = "class String1 implements java.io.Serializable { " +
+ "private static final long serialVersionUID = -6849794470754667710L;" +
+ "private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];" +
+ "}" +
+ "class StringBuilder1 implements java.io.Serializable {" +
+ " private void writeObject(java.io.ObjectOutputStream s)\n" +
+ " throws java.io.IOException {\n" +
+ " s.defaultWriteObject();\n" +
+ " }" +
+ "private void readObject(java.io.ObjectInputStream s)\n" +
+ " throws java.io.IOException, ClassNotFoundException {\n" +
+ " s.defaultReadObject();\n" +
+ " }" +
+ " static final long serialVersionUID = 4383685877147921099L;" +
+ "}";
+ String s134 = "class '_ implements '_:*Serializable {\n" +
+ " static final long 'VersionField?:serialVersionUID = '_?;\n" +
+ " private static final ObjectStreamField[] '_?:serialPersistentFields = '_?; \n" +
+ " private void '_SerializationWriteHandler?:writeObject (ObjectOutputStream s) throws IOException;\n" +
+ " private void '_SerializationReadHandler?:readObject (ObjectInputStream s) throws IOException, ClassNotFoundException;\n" +
+ " Object '_SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;" +
+ " Object '_SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;" +
+ "}";
+
+ assertEquals(
+ "serialization match",
+ findMatchesCount(s133,s134),
+ 2
+ );
+
+ String s135 = "class SimpleStudentEventActionImpl extends Action { " +
+ " public ActionForward execute(ActionMapping mapping,\n" +
+ " ActionForm _form,\n" +
+ " HttpServletRequest _request,\n" +
+ " HttpServletResponse _response)" +
+ " throws Exception {}" +
+ "} " +
+ "public class DoEnrollStudent extends SimpleStudentEventActionImpl { }" +
+ "public class DoCancelStudent extends SimpleStudentEventActionImpl { }";
+ String s136 = "public class 'StrutsActionClass extends '_*:Action {" +
+ " public ActionForward '_AnActionMethod:*execute (ActionMapping '_,\n" +
+ " ActionForm '_,\n" +
+ " HttpServletRequest '_,\n" +
+ " HttpServletResponse '_);" +
+ "}";
+
+ assertEquals(
+ "Struts actions",
+ findMatchesCount(s135,s136),
+ 2
+ );
+
+ final String s123 = "class NodeFilter {} public class MethodFilter extends NodeFilter {\n" +
+ " private MethodFilter() {}\n" +
+ "\n" +
+ " public static NodeFilter getInstance() {\n" +
+ " if (instance==null) instance = new MethodFilter();\n" +
+ " return instance;\n" +
+ " }\n" +
+ " private static NodeFilter instance;\n" +
+ "}";
+ final String s124 = "class 'Class {\n" +
+ " private 'Class('_* '_*) {\n" +
+ " '_*;\n" +
+ " }\n" +
+ " private static '_Class2:* '_Instance;\n" +
+ " static '_Class2:* '_GetInstance() {\n" +
+ " '_*;\n" +
+ " return '_Instance;\n" +
+ " }\n" +
+ "}";
+
+ assertEquals(
+ "singleton search",
+ findMatchesCount(s123,s124),
+ 1
+ );
+
+ String s1111 = "if (true) { a=1; b=1; } else { a=1; }\n" +
+ "if(true) { a=1; } else { a=1; b=1; }\n" +
+ "if(true) { a=1; b=2; } else { a = 1; b=2; }";
+ String s1112 = "if (true) { '_a{1,2}; } else { '_a; }";
+
+ assertEquals(
+ "same multiple name pattern",
+ findMatchesCount(s1111,s1112),
+ 1
+ );
+ }
+
+ public void testHierarchy() {
+ final String s105 = "class B {} class A extends B { }";
+ final String s106 = "class '_ extends '_:[ref('T)] {}";
+ assertEquals(
+ "extends match",
+ findMatchesCount(s105,s106),
+ 1
+ );
+
+ final String s107 = "interface IA {} interface IB extends IA { } interface IC extends IB {} interface ID extends IC {}" +
+ "class A implements IA {} class B extends A { } class C extends B implements IC {} class D extends C {}";
+ final String s108 = "class '_ extends 'Type:+A {}";
+ final String s108_2 = "class '_ implements 'Type:+IA {}";
+
+ assertEquals(
+ "extends navigation match",
+ findMatchesCount(s107,s108),
+ 2
+ );
+
+ assertEquals(
+ "implements navigation match",
+ 3,
+ findMatchesCount(s107,s108_2)
+ );
+
+ final String s109 = "interface I {} interface I2 extends I {} class A implements I2 {} class B extends A { } class C extends B {} class D { void e() { C c; B b; A a;} }";
+ final String s110 = "'_:*A '_;";
+ final String s110_2 = "'_:*I '_;";
+ final String s110_3 = "'_:*[regex( I ) && ref('T)] '_;";
+ final String s110_4 = "'_:*[regex( I ) && ref2('T)] '_;";
+ assertEquals(
+ "extends navigation match in definition",
+ findMatchesCount(s109,s110),
+ 3
+ );
+
+ assertEquals(
+ "implements navigation match in definition 2",
+ findMatchesCount(s109,s110_2),
+ 3
+ );
+
+ assertEquals(
+ "implements navigation match in definition 2 with nested conditions",
+ findMatchesCount(s109,s110_3),
+ 1
+ );
+
+ try {
+ findMatchesCount(s109,s110_4);
+ assertFalse("implements navigation match in definition 2 with nested conditions - incorrect cond",false);
+ } catch(UnsupportedPatternException ex) {}
+
+ final String s111 = "interface E {} class A implements E {} class B extends A { int f = 0; } class C extends B {} class D { void e() { C c; B b; A a;} }";
+ final String s112 = "'_";
+ assertEquals(
+ "symbol match",
+ findMatchesCount(s111,s112),
+ 17
+ );
+
+ final String s113 = "class B {int c; void d() {} } int a; B b; a = 1; b.d(); ++a; int c=a; System.out.println(a); " +
+ "b.c = 1; System.out.println(b.c); b.c++;";
+ final String s114 = "'_:[read]";
+ final String s114_2 = "'_:[write]";
+ assertEquals(
+ "read symbol match",
+ findMatchesCount(s113,s114),
+ 11
+ );
+
+ assertEquals(
+ "write symbol match",
+ findMatchesCount(s113,s114_2),
+ 5
+ );
+
+ final String s115 = "class B {} public class C {}";
+ final String s116 = "public class '_ {}";
+ assertEquals(
+ "public modifier for class",
+ findMatchesCount(s115,s116),
+ 1
+ );
+
+ final String s117 = "class A { int b; void c() { int e; b=1; this.b=1; e=5; " +
+ "System.out.println(e); " +
+ "System.out.println(b); System.out.println(this.b);} }";
+ final String s118 = "this.'Field";
+ final String s118_2 = "this.'Field:[read]";
+ final String s118_3 = "this.'Field:[write]";
+
+ assertEquals(
+ "fields of class",
+ 4,
+ findMatchesCount(s117,s118)
+ );
+
+ assertEquals(
+ "fields of class read",
+ findMatchesCount(s117,s118_2),
+ 2
+ );
+
+ assertEquals(
+ "fields of class written",
+ findMatchesCount(s117,s118_3),
+ 2
+ );
+
+ final String s119 = "try { a.b(); } catch(IOException e) { c(); } catch(Exception ex) { d(); }";
+ final String s120 = "try { '_; } catch('_ '_) { '_; }";
+ final String s120_2 = "try { '_; } catch(Throwable '_) { '_; }";
+ assertEquals(
+ "catches loose matching",
+ findMatchesCount(s119,s120),
+ 1
+ );
+
+ assertEquals(
+ "catches loose matching 2",
+ findMatchesCount(s119,s120_2),
+ 0
+ );
+
+ final String s121 = "class A { private int a; class Inner {} } " +
+ "class B extends A { private int a; class Inner2 {} }";
+ final String s122 = "class '_ { int '_:* ; }";
+ final String s122_2 = "class '_ { int '_:+hashCode (); }";
+ final String s122_3 = "class '_ { class '_:* {} }";
+ assertEquals(
+ "hierarchical matching",
+ findMatchesCount(s121,s122),
+ 2
+ );
+
+ assertEquals(
+ "hierarchical matching 2",
+ findMatchesCount(s121,s122_2),
+ 4
+ );
+
+ assertEquals(
+ "hierarchical matching 3",
+ findMatchesCount(s121,s122_3),
+ 2
+ );
+ }
+
+ public void testSearchInCommentsAndLiterals() {
+ String s1 = "{" +
+ "// This is some comment\n" +
+ "/* This is another\n comment*/\n" +
+ "// Some garbage\n"+
+ "/** And now third comment*/\n" +
+ "/** Some garbage*/ }";
+ String s2 = "// 'Comment:[regex( .*(?:comment).* )]";
+ String s3 = "/** 'Comment:[regex( .*(?:comment).* )] */";
+ String s2_2 = "/* 'Comment:[regex( .*(?:comment).* )] */";
+
+ assertEquals(
+ "Comment matching",
+ findMatchesCount(s1,s2),
+ 3
+ );
+
+ assertEquals(
+ "Comment matching, 2",
+ 3,
+ findMatchesCount(s1,s2_2)
+ );
+
+ assertEquals(
+ "Java doc matching",
+ findMatchesCount(s1,s3),
+ 1
+ );
+
+ String s4 = "\"'test\", \"another test\", \"garbage\"";
+ String s5 = "\"'test:[regex( .*test.* )]\"";
+ String s6 = "\"''test\"";
+
+ assertEquals(
+ "Literal content",
+ findMatchesCount(s4,s5),
+ 2
+ );
+
+ assertEquals(
+ "Literal content with escaping",
+ findMatchesCount(s4,s6),
+ 1
+ );
+
+ String s7 = "\"aaa\"";
+ String s8 = "\"'test:[regex( aaa )]\"";
+
+ assertEquals(
+ "Simple literal content",
+ findMatchesCount(s7,s8),
+ 1
+ );
+
+ String s9 = "\" aaa \" \" bbb \" \" ccc ccc aaa\"";
+ String s10 = "\"'test:[regexw( aaa|ccc )]\"";
+ String s11 = "\"'test:[regexw( bbb )]\"";
+
+ assertEquals(
+ "Whole word literal content with alternations",
+ findMatchesCount(s9,s10),
+ 2
+ );
+
+ assertEquals(
+ "Whole word literal content",
+ findMatchesCount(s9,s11),
+ 1
+ );
+
+ String s12 = "assert agentInfo != null : \"agentInfo is null\";\n" +
+ "assert addresses != null : \"addresses is null\";";
+ String s13 = "assert $exp$ != null : \"$exp$ is null\";";
+
+ assertEquals(
+ "reference to substitution in comment",
+ findMatchesCount(s12,s13),
+ 2
+ );
+
+ String s14 = "\"(some text with special chars)\"," +
+ "\" some\"," +
+ "\"(some)\"";
+ String s15 = "\"('a:[regexw( some )])\"";
+
+ assertEquals(
+ "meta char in literal",
+ 2,
+ findMatchesCount(s14,s15)
+ );
+
+ String s16 = "/**\n" +
+ "* Created by IntelliJ IDEA.\n" +
+ "* User: cdr\n" +
+ "* Date: Nov 15, 2005\n" +
+ "* Time: 4:23:29 PM\n" +
+ "* To change this template use File | Settings | File Templates.\n" +
+ "*/\n" +
+ "public class Y {\n" +
+ "}";
+ String s17 = "/**\n" +
+ "* Created by IntelliJ IDEA.\n" +
+ "* User: '_USER\n" +
+ "* Date: '_DATE\n" +
+ "* Time: '_TIME\n" +
+ "* To change this template use File | Settings | File Templates.\n" +
+ "*/\n" +
+ "class 'c {\n" +
+ "}";
+ assertEquals(
+ "complete comment match",
+ 1,
+ findMatchesCount(s16,s17,true)
+ );
+
+ String s18 = "public class A {\n" +
+ " private void f(int i) {\n" +
+ " int g=0; //sss\n" +
+ " }\n" +
+ "}";
+ String s19 = "class $c$ {\n" +
+ " $type$ $f$($t$ $p$){\n" +
+ " $s$; // sss\n" +
+ " }\n" +
+ "}";
+ assertEquals(
+ "statement match with comment",
+ 1,
+ findMatchesCount(s18,s19)
+ );
+ }
+
+ public void testOther() {
+ assertEquals(
+ "optional init match in definition",
+ findMatchesCount(s73,s74),
+ 4
+ );
+
+ assertEquals(
+ "null match",
+ findMatchesCount(s77,s78),
+ 0
+ );
+
+ assertEquals(
+ "body of method by block search",
+ findMatchesCount(s79,s80),
+ 2
+ );
+
+
+ assertEquals(
+ "first matches, next not",
+ findMatchesCount(s95,s96),
+ 2
+ );
+
+ final String s97 = "class A { int c; void b() { C d; } } class C { C() { A a; a.b(); a.c=1; } }";
+ final String s98 = "'_.'_:[ref('T)] ()";
+ final String s98_2 = "'_.'_:[ref('T)]";
+ final String s98_3 = "'_:[ref('T)].'_ ();";
+ final String s98_4 = "'_:[ref('T)] '_;";
+
+ assertEquals(
+ "method predicate match",
+ findMatchesCount(s97,s98),
+ 1
+ );
+
+ assertEquals(
+ "field predicate match",
+ findMatchesCount(s97,s98_2),
+ 1
+ );
+
+ assertEquals(
+ "dcl predicate match",
+ findMatchesCount(s97,s98_3),
+ 1
+ );
+
+ final String s99 = " char s = '\\u1111'; char s1 = '\\n'; ";
+ final String s100 = " char 'var = '\\u1111'; ";
+ final String s100_2 = " char 'var = '\\n'; ";
+ assertEquals(
+ "char constants in pattern",
+ findMatchesCount(s99,s100),
+ 1
+ );
+
+ assertEquals(
+ "char constants in pattern 2",
+ findMatchesCount(s99,s100_2),
+ 1
+ );
+
+ assertEquals(
+ "class predicate match (from definition)",
+ findMatchesCount(s97,s98_4),
+ 3
+ );
+
+ final String s125 = "a=1;";
+ final String s126 = "'t:[regex(a)]";
+
+ try {
+ findMatchesCount(s125,s126);
+ assertFalse("spaces around reg exp check",false);
+ } catch(MalformedPatternException ex) {}
+
+ options.setDistinct(true);
+
+ final String s101 = "class A { void b() { String d; String e; String[] f; f.length=1; f.length=1; } }";
+ final String s102 = "'_:[ref('T)] '_;";
+
+ assertEquals(
+ "distinct match",
+ findMatchesCount(s101,s102),
+ 1
+ );
+
+ options.setDistinct(false);
+
+ final String s103 = " a=1; ";
+ final String s104 = "'T:{ ;";
+ try {
+ findMatchesCount(s103,s104);
+ assertFalse("incorrect reg exp",false);
+ } catch(MalformedPatternException ex) {
+ }
+
+ final String s106 = "$_ReturnType$ $MethodName$($_ParameterType$ $_Parameter$);";
+ final String s105 = " aaa; ";
+
+ try {
+ findMatchesCount(s105,s106);
+ assertFalse("incorrect reg exp 2",false);
+ } catch(UnsupportedPatternException ex) {
+ }
+
+ String s107 = "class A {\n" +
+ " /* */\n" +
+ " void a() {\n" +
+ " }" +
+ " /* */\n" +
+ " int b = 1;\n" +
+ " /*" +
+ " *" +
+ " */\n" +
+ " class C {}" +
+ "}";
+ String s108 = " /*" +
+ " *" +
+ " */";
+
+ assertEquals("finding comments without typed var", 1, findMatchesCount(s107,s108));
+
+ String s109 = "class A { void b(); int b(int c); char d(char e); }\n" +
+ "A a; a.b(1); a.b(2); a.b(); a.d('e'); a.d('f'); a.d('g');";
+ String s110 = "'_a.'_b:[exprtype( int ) ]('_c*);";
+ assertEquals("caring about method return type", 2, findMatchesCount(s109,s110));
+
+ String s111 = "class A { void getManager() { getManager(); } };\n" +
+ "class B { void getManager() { getManager(); getManager(); } };";
+ String s112 = "'Instance?:[exprtype( B )].getManager()";
+ assertEquals("caring about missing qualifier type", 2, findMatchesCount(s111,s112));
+
+ String s112a = "'Instance?:[regex( B )].getManager()";
+ assertEquals("static query should not match instance method", 0, findMatchesCount(s111, s112a));
+
+ String s112b = "B.getManager()";
+ assertEquals("static query should not match instance method 2", 0, findMatchesCount(s111, s112b));
+
+ String s113 = "class A { static void a() { a(); }}\n" +
+ "class B { static void a() { a(); a(); }}\n";
+ String s114 = "'_Q?:[regex( B )].a()";
+ assertEquals("should care about implicit class qualifier", 2, findMatchesCount(s113, s114));
+
+ String s114a = "B.a()";
+ assertEquals("should match simple implicit class qualifier query", 2, findMatchesCount(s113, s114a));
+
+ String s114b = "'_Q?:[exprtype( B )].a()";
+ assertEquals("instance query should not match static method", 0, findMatchesCount(s113, s114b));
+
+ String s115 = "class A { int a; int f() { return a; }}\n" +
+ "class B { int a; int g() { return a + a; }}\n";
+ String s116 = "'_Instance?:[exprtype( B )].a";
+ assertEquals("should care about implicit instance qualifier", 2, findMatchesCount(s115, s116));
+
+ String s116a = "A.a";
+ assertEquals("should not match instance method", 0, findMatchesCount(s115, s116a));
+
+ String s117 = "class A { static int a; static int f() { return a; }}\n" +
+ "class B { static int a; static int g() { return a + a; }}\n";
+ String s118 = "'_Q?:[regex( B )].a";
+ assertEquals("should care about implicit class qualifier for field", 2, findMatchesCount(s117, s118));
+
+ // b) hierarchy navigation support
+ // c) or search support
+
+ // e) xml search (down-up, nested query), navigation from xml representation <-> java code
+ // f) impl data conversion (jdk 1.5 style) <-> other from (replace support)
+
+ // Directions:
+ // @todo different navigation on sub/supertyping relation (fixed depth), methods implementing interface,
+ // g. like predicates
+ // i. performance
+ // more context for top level classes, difference with interface, etc
+
+ // global issues:
+ // @todo matches out of context
+ // @todo proper regexp support
+
+ // @todo define strict equality of the matches
+ // @todo search for field selection retrieves packages also
+ }
+
+ public void testFQNInPatternAndVariableConstraints() {
+ String s1 = "import java.awt.List;\n" +
+ "class A { List l; }";
+ String s1_2 = "import java.util.List;\n" +
+ "class A { List l; }";
+ String s2 = "class '_ { 'Type:java\\.util\\.List '_Field; }";
+
+ assertEquals("No matches for qualified class",findMatchesCount(s1,s2,true),0);
+ assertEquals("Matches for qualified class",findMatchesCount(s1_2,s2,true),1);
+
+ String s3 = "import java.util.ArrayList;\n" +
+ "class A { ArrayList l; }";
+ String s4 = "class '_ { 'Type:*java\\.util\\.Collection '_Field; }";
+ assertEquals("Matches for qualified class in hierarchy",findMatchesCount(s3,s4,true),1);
+
+ String s5 = "import java.util.List;\n" +
+ "class A { { List l = new List(); l.add(\"1\"); } }";
+ String s5_2 = "import java.awt.List;\n" +
+ "class A { { List l = new List(); l.add(\"1\"); } }";
+ String s6 = "'a:[exprtype( java\\.util\\.List )]";
+ String s6_2 = "'a:[exprtype( *java\\.util\\.Collection )]";
+ String s6_3 = "java.util.List '_a = '_b?;";
+
+ assertEquals("Matches for qualified expr type",findMatchesCount(s5,s6,true), 2);
+ assertEquals("No matches for qualified expr type",findMatchesCount(s5_2,s6,true),0);
+ assertEquals("Matches for qualified expr type in hierarchy",findMatchesCount(s5,s6_2,true), 2);
+
+ assertEquals("Matches for qualified var type in pattern",findMatchesCount(s5,s6_3,true),1);
+ assertEquals("No matches for qualified var type in pattern",findMatchesCount(s5_2,s6_3,true),0);
+
+ String s7 = "import java.util.List;\n" +
+ "class A extends List { }";
+ String s7_2 = "import java.awt.List;\n" +
+ "class A extends List {}";
+
+ String s8 = "class 'a extends java.util.List {}";
+
+ assertEquals("Matches for qualified type in pattern",findMatchesCount(s7,s8,true),1);
+ assertEquals("No matches for qualified type in pattern",findMatchesCount(s7_2,s8,true),0);
+
+ String s9 = "String.intern(\"1\");\n" +
+ "java.util.Collections.sort(null);" +
+ "java.util.Collections.sort(null);";
+ String s10 = "java.lang.String.'_method ( '_params* )";
+ assertEquals("FQN in class name",1,findMatchesCount(s9,s10,false));
+ }
+
+ public void testAnnotations() throws Exception {
+ String s1 = "@MyBean(\"\")\n" +
+ "@MyBean2(\"\")\n" +
+ "public class TestBean {}\n" +
+ "@MyBean2(\"\")\n" +
+ "@MyBean(\"\")\n" +
+ "public class TestBean2 {}\n" +
+ "public class TestBean3 {}\n";
+ String s2 = "@MyBean(\"\")\n" +
+ "@MyBean2(\"\")\n" +
+ "public class $a$ {}\n";
+
+ assertEquals("Simple find annotated class",2,findMatchesCount(s1,s2,false));
+
+ String s3 = "@VisualBean(\"????????? ?????????? ? ??\")\n" +
+ "public class TestBean\n" +
+ "{\n" +
+ " @VisualBeanField(\n" +
+ " name = \"??? ????????????\",\n" +
+ " initialValue = \"?????????????\"\n" +
+ " )\n" +
+ " public String user;\n" +
+ "\n" +
+ " @VisualBeanField(\n" +
+ " name = \"??????\",\n" +
+ " initialValue = \"\",\n" +
+ " fieldType = FieldTypeEnum.PASSWORD_FIELD\n" +
+ " )\n" +
+ " public String password;\n" +
+ "\n" +
+ " @VisualBeanField(\n" +
+ " initialValue = \"User\",\n" +
+ " name = \"????? ???????\",\n" +
+ " name = \"Second name\",\n" +
+ " fieldType = FieldTypeEnum.COMBOBOX_FIELD,\n" +
+ " comboValues = {\n" +
+ " @ComboFieldValue(\"Administrator\"),\n" +
+ " @ComboFieldValue(\"User\"),\n" +
+ " @ComboFieldValue(\"Guest\")}\n" +
+ " ) \n" +
+ " public String accessRights;\n" +
+ " \n" +
+ " public String otherField;\n" +
+ "}";
+ String s4 = "class '_a {\n" +
+ " @'_Annotation+ ( 'AnnotationMember*:name = '_AnnotationValue* )\n" +
+ " String '_field* ;\n" +
+ "}";
+ String s4_2 = "class '_a {\n" +
+ " @'_Annotation+ ()\n" +
+ " String 'field* ;\n" +
+ "}";
+
+ assertEquals("Find annotation members of annotated field class",4,findMatchesCount(s3,s4,false));
+ assertEquals("Find annotation fields",3,findMatchesCount(s3,s4_2,false));
+
+ String s5 = "class A {" +
+ " @NotNull private static Collection<PsiElement> resolveElements(final PsiReference reference, final Project project) {}\n" +
+ " @NotNull private static Collection resolveElements2(final PsiReference reference, final Project project) {}\n" +
+ "}";
+ String s6 = "class '_c {@NotNull '_rt 'method* ('_pt* '_p*){ '_inst*; } }";
+ String s6_2 = "class '_c {@'_:NotNull '_rt 'method* ('_pt* '_p*){ '_inst*; } }";
+
+ assertEquals("Find annotated methods",2,findMatchesCount(s5,s6));
+ assertEquals("Find annotated methods, 2",2,findMatchesCount(s5,s6_2));
+
+ String s7 = "class A { void message(@NonNls String msg); }\n" +
+ "class B { void message2(String msg); }\n" +
+ "class C { void message2(String msg); }";
+ String s8 = "class '_A { void 'b( @'_Ann{0,0}:NonNls String '_); }";
+ assertEquals("Find not annotated methods",2,findMatchesCount(s7,s8));
+
+ String s9 = "class A {\n" +
+ " Object[] method1() {}\n" +
+ " Object method1_2() {}\n" +
+ " Object method1_3() {}\n" +
+ " Object method1_4() {}\n" +
+ " @MyAnnotation Object[] method2(int a) {}\n" +
+ " @NonNls Object[] method3() {}\n" +
+ "}";
+ String s10 = "class '_A { @'_Ann{0,0}:NonNls '_Type:Object\\[\\] 'b+( '_pt* '_p* ); }";
+ String s10_2 = "class '_A { @'_Ann{0,0}:NonNls '_Type [] 'b+( '_pt* '_p* ); }";
+ String s10_3 = "class '_A { @'_Ann{0,0}:NonNls '_Type:Object [] 'b+( '_pt* '_p* ); }";
+ assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10));
+ assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10_2));
+ assertEquals("Find not annotated methods, 2",2,findMatchesCount(s9,s10_3));
+
+ String s11 = "class A {\n" +
+ "@Foo(value=baz) int a;\n" +
+ "@Foo(value=baz2) int a2;\n" +
+ "@Foo(value=baz2) int a3;\n" +
+ "@Foo(value2=baz3) int a3;\n" +
+ "@Foo(value2=baz3) int a3;\n" +
+ "@Foo(value2=baz3) int a3;\n" +
+ "@Foo(value2=baz4) int a3;\n" +
+ "}";
+ String s12 = "@Foo(value=baz) int 'a;)";
+ String s12_2 = "@Foo(value='baz:baz2 ) int 'a;)";
+ String s12_3 = "@Foo('value:value2 = baz3 ) int 'a;)";
+ String s12_4 = "@Foo('value:value2 = 'baz3:baz3 ) int 'a;)";
+ String s12_5 = "@Foo('value:value2 = 'baz3:baz ) int 'a;)";
+ String s12_6 = "@Foo('value:value2 = 'baz3 ) int 'a;)";
+
+ assertEquals("Find anno parameter value",1,findMatchesCount(s11,s12));
+ assertEquals("Find anno parameter value",2,findMatchesCount(s11,s12_2));
+ assertEquals("Find anno parameter value",3,findMatchesCount(s11,s12_3));
+ assertEquals("Find anno parameter value",3,findMatchesCount(s11,s12_4));
+ assertEquals("Find anno parameter value",0,findMatchesCount(s11,s12_5));
+ assertEquals("Find anno parameter value",4,findMatchesCount(s11,s12_6));
+ }
+
+ public void testBoxingAndUnboxing() {
+ String s1 = " class A { void b(Integer i); void b2(int i); void c(int d); void c2(Integer d); }\n" +
+ "A a;\n" +
+ "a.b2(1)\n;" +
+ "a.b2(1)\n;" +
+ "a.b(1)\n;" +
+ "a.b( new Integer(0) )\n;" +
+ "a.b( new Integer(0) )\n;" +
+ "a.c(new Integer(2));\n" +
+ "a.c(new Integer(3));\n" +
+ "a.c2(new Integer(3));\n" +
+ "a.c(3);";
+ String s2 = "a.'b('_Params:[formal( Integer ) && exprtype( int ) ])";
+ String s2_2 = "a.c('_Params:[formal( int ) && exprtype( Integer ) ])";
+
+ assertEquals("Find boxing in method call",1,findMatchesCount(s1,s2,false));
+ assertEquals("Find unboxing in method call",2,findMatchesCount(s1,s2_2,false));
+ }
+
+ public void testCommentsInDclSearch() {
+ String s1 = "class A {\n" +
+ " int a; // comment\n" +
+ " char b;\n" +
+ " int c; // comment2\n" +
+ "}";
+ String s1_2 = "class A {\n" +
+ " // comment\n" +
+ " int a;\n" +
+ " char b;\n" +
+ " // comment2\n" +
+ " int c;\n" +
+ "}";
+
+ String s2 = "'_Type '_Variable = '_Value?; //'Comment";
+ String s2_2 = "//'Comment\n" +
+ "'_Type '_Variable = '_Value?;";
+
+ assertEquals("Find field by dcl with comment",2,findMatchesCount(s1,s2));
+ assertEquals("Find field by dcl with comment 2",2,findMatchesCount(s1_2,s2_2));
+ }
+
+ public void testSearchingEmptyModifiers() {
+
+ String s1 = "class A {\n" +
+ " int a;\n" +
+ " private char b;\n" +
+ " private char b2;\n" +
+ " public int c;\n" +
+ " public int c2;\n" +
+ "}";
+ String s2 = "@Modifier(\"packageLocal\") '_Type '_Variable = '_Value?;";
+ String s2_2 = "@Modifier({\"packageLocal\",\"private\"}) '_Type '_Variable = '_Value?;";
+ String s2_3 = "@Modifier({\"PackageLocal\",\"private\"}) '_Type '_Variable = '_Value?;";
+
+ assertEquals("Finding package local dcls",1,findMatchesCount(s1,s2));
+ assertEquals("Finding package local dcls",3,findMatchesCount(s1,s2_2));
+
+ try {
+ findMatchesCount(s1,s2_3);
+ assertTrue("Finding package local dcls",false);
+ } catch(MalformedPatternException ex) {
+
+ }
+
+ String s3 = "class A {\n" +
+ " int a;\n" +
+ " static char b;\n" +
+ " static char b2;\n" +
+ "}";
+ String s4 = "@Modifier(\"Instance\") '_Type '_Variable = '_Value?;";
+ String s4_2 = "@Modifier({\"static\",\"Instance\"}) '_Type '_Variable = '_Value?;";
+ assertEquals("Finding instance fields",1,findMatchesCount(s3,s4));
+ assertEquals("Finding all fields",3,findMatchesCount(s3,s4_2));
+
+ String s5 = "class A {}\n" +
+ "abstract class B {}\n" +
+ "final class C {}\n" +
+ "class D {}";
+ String s6 = "@Modifier(\"Instance\") class 'Type {}";
+ String s6_2 = "@Modifier({\"abstract\",\"final\",\"Instance\"}) class 'Type {}";
+ assertEquals("Finding instance classes",3,findMatchesCount(s5,s6));
+ assertEquals("Finding all classes",4,findMatchesCount(s5,s6_2));
+ }
+
+ public void testSearchTransientFieldsWithModifier() {
+ String source =
+ "public class TestClass {\n" +
+ " transient private String field1;\n" +
+ " transient String field2;\n" +
+ " String field3;\n" +
+ "}";
+
+ String template = "transient @Modifier(\"packageLocal\") '_Type '_Variable = '_Value?;";
+
+ assertEquals("Finding package-local transient fields", 1, findMatchesCount(source, template));
+ }
+
+ public void test() {
+ String s1 = "if (LOG.isDebugEnabled()) {\n" +
+ " int a = 1;\n" +
+ " int a = 1;\n" +
+ "}";
+ String s2 = "if ('_Log.isDebugEnabled()) {\n" +
+ " '_ThenStatement;\n" +
+ " '_ThenStatement;\n" +
+ "}";
+ assertEquals("Comparing declarations",1,findMatchesCount(s1,s2));
+ }
+
+ public void testFindStaticMethodsWithinHierarchy() {
+ String s1 = "class A {}\n" +
+ "class B extends A { static void foo(); }\n" +
+ "class B2 extends A { static void foo(int a); }\n" +
+ "class B3 extends A { static void foo(int a, int b); }\n" +
+ "class C { static void foo(); }\n" +
+ "B.foo();\n" +
+ "B2.foo(1);\n" +
+ "B3.foo(2,3);\n" +
+ "C.foo();";
+ String s2 = "'_Instance:[regex( *A )].'_Method:[regex( foo )] ( '_Params* )";
+ assertEquals("Find static methods within expr type hierarchy", 3, findMatchesCount(s1,s2));
+ }
+
+ public void testFindClassesWithinHierarchy() {
+ String s1 = "class A implements I {}\n" +
+ "interface I {}\n" +
+ "class B extends A implements I { }\n" +
+ "class B2 implements I { }\n" +
+ "class B3 extends A { }\n" +
+ "class C extends B2 { static void foo(); }\n";
+ String s2 = "class '_ extends '_Extends:[!regex( *A )] implements '_Implements:[regex( I )] {}";
+ String s2_2 = "class '_ extends '_Extends:[!regex( *A )]{}";
+ assertEquals("Find class within type hierarchy with not", 1, findMatchesCount(s1,s2));
+ assertEquals("Find class within type hierarchy with not, 2", 1, findMatchesCount(s1,s2_2));
+ }
+
+ public void testFindTryWithoutProperFinally() {
+ String s1 = "try {\n" +
+ " conn = 1;\n" +
+ "} finally {\n" +
+ " conn.close();\n" +
+ "}\n" +
+ "try {\n" +
+ " conn = 1;\n" +
+ "} finally {\n" +
+ " int a = 1;\n" +
+ "}\n" +
+ "try {\n" +
+ " conn = 1;\n" +
+ "} finally {\n" +
+ " int a = 1;\n" +
+ "}";
+ String s2 = "try { '_StatementBefore*; '_Dcl:[regex( conn = 1 )]; '_StatementAfter*; } finally { '_Finally*:[!regex( .*conn.* ) ]; }";
+ assertEquals("FindTryWithoutProperFinally", 2, findMatchesCount(s1,s2));
+ }
+
+ public void testBug() {
+ String s1 = "public class DiallingNumber extends DataGroup\n" + "{\n" + " protected static byte [] CLEAR = { };\n" + "\n" +
+ " private static DataItemTemplate template;\n" + "\n" + "\tprotected DataTemplate createDefaultTemplate()\n" + "\t{\n" +
+ " return null;\n" + " }\n" + "}";
+ String s2 = "class '_Class {\n" + " static '_FieldType '_FieldName:.*template.* = '_FieldInitial?;\n" +
+ " '_RetType createDefaultTemplate() { '_Statements*; }\n" + "\t'_Content*\n" + "}";
+ assertEquals("Bug in class matching", 1, findMatchesCount(s1,s2));
+ }
+
+ //public void testFindFieldUsageByQName() {
+ // String s1 = "{ class A { int b; { b = 1; } } class B extends A { { this.b = 2} } { B i; i.b = 3; } }";
+ // String s2 = "A.b";
+ // assertEquals( 3, findMatchesCount(s1,s2));
+ //}
+ //
+ //public void testFindMethodUsageByQName() {
+ // String s1 = "{ class A { void b(int a) {} { b(1); } } class B extends A { { this.b(2); } } { B i; i.b(3); } }";
+ // String s2 = "A.b";
+ // assertEquals( 3, findMatchesCount(s1,s2));
+ //}
+
+ public void _testStaticInstanceInitializers() {
+ String s1 = "public class DiallingNumber {\n static { int a = 1; } static { int b = 1; } { int c = 2; }}";
+ String s2 = "class '_Class {\n" + " static { 't*; } }";
+ String s2_2 = "class '_Class {\n" + " { 't*; } }";
+ String s2_3 = "class '_Class {\n" + " @Modifier(\"Instance\") { 't*; } }";
+ assertEquals("Static / instance initializers", 2, findMatchesCount(s1,s2));
+ assertEquals("Static / instance initializers", 1, findMatchesCount(s1,s2_3));
+ assertEquals("Static / instance initializers", 3, findMatchesCount(s1,s2_2));
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("structuralsearch") + "/testData/java/";
+ }
+
+ public void testDoNotFindReturn() throws IOException {
+ String s1 = loadFile(getTestName(false) + ".java");
+ String s2 = "ApplicationManager.getApplication().runReadAction(new Runnable() {\n" +
+ " public void run() {\n" +
+ " 't*:[ !regex( .*return.* ) ];\n" +
+ " }});";
+ assertEquals(0, findMatchesCount(s1,s2));
+ }
+
+ public void testDownUpMatch() {
+ String s1 = "class A {\n" +
+ " int bbb(int c, int ddd, int eee) {\n" +
+ " int a = 1;\n" +
+ " try { int b = 1; } catch(Type t) { a = 2; } catch(Type2 t2) { a = 3; }\n" +
+ " }\n" +
+ "}";
+ String s2 = "try { '_st*; } catch('_Type 't+) { '_st2*; }";
+
+ final List<PsiVariable> vars = new ArrayList<PsiVariable>();
+ final PsiFile file = PsiFileFactory.getInstance(getProject()).createFileFromText("_.java", s1);
+
+ file.acceptChildren(new JavaRecursiveElementWalkingVisitor() {
+ @Override public void visitVariable(final PsiVariable variable) {
+ super.visitVariable(variable);
+ vars.add(variable);
+ }
+ });
+
+ assertEquals(7, vars.size());
+ List<MatchResult> results = new ArrayList<MatchResult>();
+
+ Matcher testMatcher = new Matcher(getProject());
+ MatchOptions options = new MatchOptions();
+ options.setSearchPattern(s2);
+ MatcherImplUtil.transform(options);
+ options.setFileType(StdFileTypes.JAVA);
+
+ for(PsiVariable var:vars) {
+ final MatchResult matchResult = testMatcher.isMatchedByDownUp(var, options);
+ if (matchResult != null) results.add(matchResult);
+ assertTrue(
+ (var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection && matchResult != null) ||
+ matchResult == null
+ );
+ }
+
+ assertEquals(2, results.size());
+ MatchResult result = results.get(0);
+ assertEquals("t", result.getMatchImage());
+
+ result = results.get(1);
+ assertEquals("t2", result.getMatchImage());
+
+ results.clear();
+ String s2_2 = "try { '_st*; } catch('Type:Type2 '_t) { '_st2*; }";
+
+ options.clearVariableConstraints();
+ options.setSearchPattern(s2_2);
+ MatcherImplUtil.transform(options);
+
+ for(PsiVariable var:vars) {
+ final PsiTypeElement typeElement = var.getTypeElement();
+ final MatchResult matchResult = testMatcher.isMatchedByDownUp(typeElement, options);
+ if (matchResult != null) results.add(matchResult);
+ assertTrue(
+ (var instanceof PsiParameter && var.getParent() instanceof PsiCatchSection && matchResult != null) ||
+ matchResult == null
+ );
+ }
+
+ assertEquals(1, results.size());
+
+ result = results.get(0);
+ assertEquals("Type2", result.getMatchImage());
+ }
+
+ @Bombed(day = 28, description = "support it", month = Calendar.JULY, user = "maxim.mossienko")
+ public void _testContainsPredicate() {
+ String s1 = "{{\n" +
+ " int a;\n" +
+ " a = 1;\n" +
+ "}\n" +
+ "{\n" +
+ " int b = 1;\n" +
+ " b = 1;\n" +
+ "}\n" +
+ "{\n" +
+ " int c = 2;\n" +
+ " c = 2;\n" +
+ "}}";
+ String s2 = "{\n" +
+ " '_a*:[contains( \"'type $a$ = $b$;\" )];\n" +
+ "}";
+
+ String s2_2 = "{\n" +
+ " '_a*:[!contains( \"$type$ $a$ = $b$;\" )];\n" +
+ "}";
+
+ assertEquals(2, findMatchesCount(s1, s2));
+ assertEquals(1, findMatchesCount(s1, s2_2));
+ }
+
+ public void testWithinPredicate() {
+ String s1 = "if (true) {\n" +
+ " int a = 1;\n" +
+ "}\n" +
+ "if (true) {\n" +
+ " int b = 1;\n" +
+ "}\n" +
+ "while(true) {\n" +
+ " int c = 2;\n" +
+ "}";
+ String s2 = "'_type 'a:[within( \"if ('_a) { '_st*; }\" )] = '_b;";
+ String s2_2 = "'_type 'a:[!within( \"if ('_a) { '_st*; }\" )] = '_b;";
+
+ assertEquals(2,findMatchesCount(s1, s2));
+ assertEquals(1,findMatchesCount(s1, s2_2));
+
+ // TODO: xxx
+ //String s3 = "if (true) {\n" +
+ // " if (true) return;\n" +
+ // " int a = 1;\n" +
+ // "}\n else if (true) {\n" +
+ // " return;\n" +
+ // "}";
+ //assertEquals(2,findMatchesCount(s3, s2));
+ //assertEquals(1,findMatchesCount(s3, s2_2));
+ }
+
+ public void testWithinPredicate2() {
+ String s3 = "class C {\n" +
+ " void aaa() {\n" +
+ " LOG.debug(true);\n" +
+ " LOG.debug(true);\n" +
+ " LOG.debug(true);\n" +
+ " LOG.debug(true);\n" +
+ " LOG.debug(true);\n" +
+ " if (true) {\n" +
+ " LOG.debug(true);\n" +
+ " }\n" +
+ " if (true) LOG.debug(true);\n" +
+ " if (true) { int 1 = 1; } else { LOG.debug(true); }\n" +
+ " }" +
+ "}";
+ String s4 = "LOG.debug('_params*:[!within( \"if('_a) { 'st*; }\" )]);";
+
+ assertEquals(6,findMatchesCount(s3, s4));
+ }
+
+ public void testMultiStatementPatternWithTypedVariable() throws Exception {
+ String s = "Integer i;\ni.valueOf();";
+ String s_2 = "Integer i;\nint a = 1;\ni.valueOf();";
+ String s2 = "Integer '_i;\n'_i.valueOf();";
+ String s2_2 = "Integer '_i;\n'_st; '_i.valueOf();";
+ String s2_3 = "Integer '_i;\n'_st*; '_i.valueOf();";
+
+ assertEquals(1, findMatchesCount(s,s2));
+ assertEquals(1, findMatchesCount(s_2,s2_2));
+ assertEquals(1, findMatchesCount(s_2,s2_3));
+ assertEquals(1, findMatchesCount(s,s2_3));
+ }
+
+ public void testFindAnnotationDeclarations() throws Exception {
+ String s = "interface Foo {} interface Bar {} @interface X {}";
+ String s2 = "@interface 'x {}";
+
+ assertEquals(1, findMatchesCount(s,s2));
+ }
+
+ public void testFindEnums() throws Exception {
+ String s = "class Foo {} class Bar {} enum X {}";
+ String s2 = "enum 'x {}";
+
+ assertEquals(1, findMatchesCount(s,s2));
+ }
+
+ public void testFindDeclaration() throws Exception {
+ String s = "public class F {\n" +
+ " static Category cat = Category.getInstance(F.class.getName());\n" +
+ " Category cat2 = Category.getInstance(F.class.getName());\n" +
+ " Category cat3 = Category.getInstance(F.class.getName());\n" +
+ "}";
+ String s2 = "static $Category$ $cat$ = $Category$.getInstance($Arg$);";
+
+ assertEquals(1, findMatchesCount(s,s2));
+ }
+
+ public void testFindMethodCallWithTwoOrThreeParameters() {
+ String source = "{ String.format(\"\"); String.format(\"\", 1); String.format(\"\", 1, 2); String.format(\"\", 1, 2, 3); }";
+ String pattern = "'_Instance.'_MethodCall('_Parameter{2,3})";
+
+ assertEquals(2, findMatchesCount(source, pattern));
+ }
+
+ public void testFindMethodWithCountedExceptionsInThrows() {
+ String source = "class A {" +
+ " void a() {}" +
+ " void b() throws E1 {}" +
+ " void c() throws E1, E2{}" +
+ " void d() throws E1, E2, E3 {}" +
+ "}";
+
+ String pattern1 = "class '_A {" +
+ " '_type+ 'method+ () throws '_E{0,0}" +
+ "}";
+ assertEquals(1, findMatchesCount(source, pattern1));
+
+ String pattern2 = "class '_A {" +
+ " '_type+ 'method+ () throws '_E{1,2}" +
+ "}";
+ assertEquals(2, findMatchesCount(source, pattern2));
+
+ String pattern3 = "class '_A {" +
+ " '_type+ 'method+ () throws '_E{2,2}" +
+ "}";
+ assertEquals(1, findMatchesCount(source, pattern3));
+
+ String pattern4 = "class '_A {" +
+ " '_type+ 'method+ () throws '_E{0,0}:[ regex( E2 )]" +
+ "}";
+ assertEquals(2, findMatchesCount(source, pattern4));
+ }
+
+ public void testFindMethodsCalledWithinClass() {
+ String source = "class A {" +
+ " void a() {}" +
+ " static void b() {}" +
+ " void c() {" +
+ " a();" +
+ " b();" +
+ " }" +
+ "}" +
+ "class B extends A {" +
+ " void d() {" +
+ " a();" +
+ " b();" +
+ " }" +
+ "}";
+ String pattern1 = "this.a()";
+ assertEquals(2, findMatchesCount(source, pattern1));
+ }
+
+ public void testFindReferenceWithParentheses() {
+ String source = "class A {" +
+ " String value;" +
+ " A(String v) {" +
+ " value = (value);" +
+ " System.out.println(((2)));" +
+ " System.out.println(2);" +
+ " }" +
+ "}";
+
+ String pattern1 = "'_value='_value";
+ assertEquals(1, findMatchesCount(source, pattern1));
+
+ String pattern2 = "System.out.println('_v);" +
+ "System.out.println('_v);";
+ assertEquals(1, findMatchesCount(source, pattern2));
+ }
+
+ public void testFindSelfAssignment() {
+ String source = "class A {" +
+ " protected String s;" +
+ " A(String t) {" +
+ " this.s = s;" +
+ " t = t;" +
+ " s = this.s;" +
+ " }" +
+ //"}" +
+ //"class B {" +
+ //" B(String t) {" +
+ //" super.s = s;" + // would be nice if found also
+ //" }" +
+ "}";
+
+ String pattern = "'_var='_var";
+ assertEquals(3, findMatchesCount(source, pattern));
+ }
+
+ public void testFindLambdas() {
+ String source = "public interface IntFunction<R> {" +
+ " R apply(int value);" +
+ "}" +
+ "public interface Function<T, R> {" +
+ " R apply(T t);" +
+ "}" +
+ "class A {" +
+ " void m() {" +
+ " Runnable q = () -> { /*comment*/ };" +
+ " Runnable r = () -> { System.out.println(); };" +
+ " IntFunction<String> f = a -> \"hello\";" +
+ " Function<String, String> g = a -> \"world\";" +
+ " }" +
+ "}";
+
+ String pattern1 = "() ->";
+ assertEquals("should find lamdas", 4, findMatchesCount(source, pattern1));
+
+ String pattern2 = "(int '_a) -> {}";
+ assertEquals("should find lambdas with specific parameter type", 1, findMatchesCount(source, pattern2));
+
+ String pattern3 = "('_a{0,0})->{}";
+ assertEquals("should find lambdas without any parameters", 2, findMatchesCount(source, pattern3));
+
+ String pattern4 = "()->System.out.println()";
+ assertEquals("should find lambdas with matching body", 1, findMatchesCount(source, pattern4));
+
+ String pattern5 = "()->{/*comment*/}";
+ assertEquals("should find lambdas with comment body", 1, findMatchesCount(source, pattern5));
+ }
+
+ public void testFindDefaultMethods() {
+ String source = "interface XYZ {" +
+ " default void m() {" +
+ " System.out.println();" +
+ " }" +
+ " void f();" +
+ " void g();" +
+ "}" +
+ "interface ABC {" +
+ " void m();" +
+ "}";
+
+ String pattern1 = "interface '_Class { default '_ReturnType+ 'MethodName+('_ParameterType* '_Parameter*);}";
+ assertEquals("should find default method", 1, findMatchesCount(source, pattern1));
+
+ String pattern2 = "interface 'Class { default '_ReturnType+ '_MethodName{0,0}('_ParameterType* '_Parameter*);}";
+ assertEquals("should find interface without default methods", 1, findMatchesCount(source, pattern2));
+ }
+
+ public void testFindMethodReferences() {
+ String source = "class A {" +
+ " Runnable r = System.out::println;" +
+ " Runnable s = this::hashCode;" +
+ " Runnable t = this::new;" +
+ " static {" +
+ " System.out.println();" +
+ " }" +
+ "}";
+
+ String pattern1 = "System . out :: println";
+ assertEquals("should find method reference", 1, findMatchesCount(source, pattern1));
+
+ String pattern2 = "this::'_a";
+ assertEquals("should find method reference 2", 2, findMatchesCount(source, pattern2));
+
+ String pattern3 = "'_a::'_b";
+ assertEquals("should find all method references", 3, findMatchesCount(source, pattern3));
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java
new file mode 100644
index 000000000000..6b8aceaba590
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTestCase.java
@@ -0,0 +1,98 @@
+package com.intellij.structuralsearch;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.structuralsearch.impl.matcher.MatcherImpl;
+import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+abstract class StructuralSearchTestCase extends LightQuickFixTestCase {
+ protected MatchOptions options;
+ protected Matcher testMatcher;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ StructuralSearchUtil.ourUseUniversalMatchingAlgorithm = false;
+ testMatcher = new Matcher(getProject());
+ options = new MatchOptions();
+ options.setLooseMatching(true);
+ options.setRecursiveSearch(true);
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ testMatcher = null;
+ options = null;
+ super.tearDown();
+ }
+
+ protected int findMatchesCount(String in, String pattern, boolean filePattern, FileType fileType) {
+ return findMatches(in,pattern,filePattern, fileType).size();
+ }
+
+ protected List<MatchResult> findMatches(String in,
+ String pattern,
+ boolean filePattern,
+ FileType patternFileType,
+ Language patternLanugage,
+ FileType sourceFileType,
+ String sourceExtension,
+ boolean physicalSourceFile) {
+ return findMatches(in, pattern, filePattern, patternFileType, patternLanugage, sourceFileType, sourceExtension, physicalSourceFile,
+ true);
+ }
+
+ protected List<MatchResult> findMatches(String in,
+ String pattern,
+ boolean filePattern,
+ FileType patternFileType,
+ Language patternLanugage,
+ FileType sourceFileType,
+ String sourceExtension,
+ boolean physicalSourceFile,
+ boolean transform) {
+ options.clearVariableConstraints();
+ options.setSearchPattern(pattern);
+ if (transform) {
+ MatcherImplUtil.transform(options);
+ }
+ pattern = options.getSearchPattern();
+ options.setFileType(patternFileType);
+ options.setDialect(patternLanugage);
+
+ MatcherImpl.validate(getProject(), options);
+ return testMatcher.testFindMatches(in, pattern, options, filePattern, sourceFileType, sourceExtension, physicalSourceFile);
+ }
+
+ protected List<MatchResult> findMatches(String in, String pattern, boolean filePattern, FileType patternFileType) {
+ return findMatches(in, pattern, filePattern, patternFileType, null, patternFileType, null, false);
+ }
+
+ protected int findMatchesCount(String in, String pattern, boolean filePattern) {
+ return findMatchesCount(in, pattern,filePattern, StdFileTypes.JAVA);
+ }
+
+ protected int findMatchesCount(String in, String pattern) {
+ return findMatchesCount(in,pattern,false);
+ }
+
+ protected List<MatchResult> findMatches(String in, String pattern) {
+ return findMatches(in,pattern,false, StdFileTypes.JAVA);
+ }
+
+ protected String loadFile(String fileName) throws IOException {
+ return FileUtilRt.loadFile(new File(getTestDataPath() + fileName), CharsetToolkit.UTF8, true);
+ }
+}
diff --git a/plugins/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java
new file mode 100644
index 000000000000..dc1cbc5802f2
--- /dev/null
+++ b/plugins/structuralsearch/testSource/com/intellij/structuralsearch/impl/matcher/compiler/StringToConstraintsTransformerTest.java
@@ -0,0 +1,128 @@
+package com.intellij.structuralsearch.impl.matcher.compiler;
+
+import com.intellij.structuralsearch.MalformedPatternException;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.MatchVariableConstraint;
+import com.intellij.structuralsearch.UnsupportedPatternException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class StringToConstraintsTransformerTest {
+
+ private MatchOptions myOptions;
+
+ @Before
+ public void setUp() throws Exception {
+ myOptions = new MatchOptions();
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testCharacterExpectedAfterQuote() {
+ test("' asdf");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testUnexpectedEndOfPattern() {
+ test("'_a{");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testDigitExpected() {
+ test("'a{a");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testDigitExpected2() {
+ test("'a{1,a}");
+ }
+
+ @Test
+ public void testZeroOccurs() {
+ test("'a{,}");
+ final MatchVariableConstraint constraint = myOptions.getVariableConstraint("a");
+ assertEquals(0, constraint.getMinCount());
+ assertEquals(0, constraint.getMaxCount());
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testOverflow() {
+ test("'a{2147483648}");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testMissingBrace() {
+ test("'a{1,3");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testNoOptions() {
+ test("'a:");
+ }
+
+ @Test
+ public void testColon() {
+ test("for('_t 'a : '_b) {}");
+ assertEquals("for($t$ $a$ : $b$) {}", myOptions.getSearchPattern());
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testNoOptions2() {
+ test("'a:+");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testUnclosedCondition() {
+ test("'a:[");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testClosedCondition() {
+ test("'a:[]");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testEmptyNegated() {
+ test("'a:[!]");
+ }
+
+ @Test(expected = UnsupportedPatternException.class)
+ public void testCondition() {
+ test("'a:[aap()]");
+ }
+
+ @Test(expected = UnsupportedPatternException.class)
+ public void testIncompleteCondition() {
+ test("'a:[regex(]");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testIncompleteCondition2() {
+ test("'a:[regex()]");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testIncompleteMultipleCondition() {
+ test("'a:[regex( a ) &&]");
+ }
+
+ @Test(expected = MalformedPatternException.class)
+ public void testInvalidRegularExpression() {
+ test("'a:x!(");
+ }
+
+ @Test
+ public void testMethodReference() {
+ test("'_a::'_b");
+ assertEquals("$a$::$b$", myOptions.getSearchPattern());
+ }
+
+ private void test(String pattern) {
+ myOptions.setSearchPattern(pattern);
+ StringToConstraintsTransformer.transformOldPattern(myOptions);
+ }
+}
diff --git a/plugins/svn4idea/lib/JAVAHL-LICENSE b/plugins/svn4idea/lib/JAVAHL-LICENSE
deleted file mode 100644
index 9c3e114d766c..000000000000
--- a/plugins/svn4idea/lib/JAVAHL-LICENSE
+++ /dev/null
@@ -1,55 +0,0 @@
-This license applies to all portions of Subversion which are not
-externally-maintained libraries (e.g. apr/, apr-util/, and neon/).
-Such libraries have their own licenses; we recommend you read them, as
-their terms may differ from the terms below.
-
-This is version 1 of this license. It is also available online at
-http://subversion.tigris.org/license-1.html. If newer versions of
-this license are posted there (the same URL, but with the version
-number incremented: .../license-2.html, .../license-3.html, and so
-on), you may use a newer version instead, at your option.
-
-====================================================================
-Copyright (c) 2000-2005 CollabNet. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-3. The end-user documentation included with the redistribution, if
-any, must include the following acknowledgment: "This product includes
-software developed by CollabNet (http://www.Collab.Net/)."
-Alternately, this acknowledgment may appear in the software itself, if
-and wherever such third-party acknowledgments normally appear.
-
-4. The hosted project names must not be used to endorse or promote
-products derived from this software without prior written
-permission. For written permission, please contact info@collab.net.
-
-5. Products derived from this software may not use the "Tigris" name
-nor may "Tigris" appear in their names without prior written
-permission of CollabNet.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-====================================================================
-
-This software consists of voluntary contributions made by many
-individuals on behalf of CollabNet.
-
diff --git a/plugins/svn4idea/lib/javahl.jar b/plugins/svn4idea/lib/javahl.jar
deleted file mode 100644
index a0c5370065af..000000000000
--- a/plugins/svn4idea/lib/javahl.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/lib/javahlsrc.zip b/plugins/svn4idea/lib/javahlsrc.zip
deleted file mode 100644
index 9c50118203b7..000000000000
--- a/plugins/svn4idea/lib/javahlsrc.zip
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
index 96c8d6e2e4de..57c835daef2f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/auth/SvnAuthenticationNotifier.java
@@ -19,7 +19,6 @@ import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -128,11 +127,12 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
}
};
- final ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication();
+ final Application application = ApplicationManager.getApplication();
// also do not show auth if thread does not have progress indicator
- if (application.holdsReadLock() || application.isDispatchThread() || ! ProgressManager.getInstance().hasProgressIndicator()) {
+ if (application.isReadAccessAllowed() || !ProgressManager.getInstance().hasProgressIndicator()) {
application.executeOnPooledThread(checker);
- } else {
+ }
+ else {
checker.run();
return resultRef.get();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java
index 9764c4666a61..762f4449b897 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java
@@ -50,6 +50,7 @@ import com.intellij.util.continuation.Continuation;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.history.SvnChangeList;
import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
@@ -629,6 +630,7 @@ public class MergeFromTheirsResolver {
return true;
}
+ @NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.ask");
diff --git a/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java b/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
index e243402b14c0..fd4975f83d95 100644
--- a/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
+++ b/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
@@ -177,7 +177,7 @@ public class JqlCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
LOG.debug(DebugUtil.psiToString(parameters.getOriginalFile(), true));
super.fillCompletionVariants(parameters, result);
}
diff --git a/plugins/tasks/tasks-core/src/META-INF/plugin.xml b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
index 2eb5ff101c4a..36268b408073 100644
--- a/plugins/tasks/tasks-core/src/META-INF/plugin.xml
+++ b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
@@ -134,6 +134,7 @@
<tasks.repositoryType implementation="com.intellij.tasks.generic.GenericRepositoryType"/>
<tasks.repositoryType implementation="com.intellij.tasks.trello.TrelloRepositoryType"/>
<tasks.repositoryType implementation="com.intellij.tasks.gitlab.GitlabRepositoryType"/>
+ <tasks.repositoryType implementation="com.intellij.tasks.bugzilla.BugzillaRepositoryType"/>
<!-- JQL support -->
<fileTypeFactory implementation="com.intellij.tasks.jira.jql.JqlFileTypeFactory"/>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java
index 1f53dbfc4889..63bff938a26f 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java
@@ -20,8 +20,6 @@ import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
-import static com.intellij.tasks.actions.TaskSearchSupport.getRepositoriesTasks;
-
/**
* @author Mikhail Golubev
*/
@@ -59,10 +57,14 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable {
GotoTaskAction.CREATE_NEW_TASK_ACTION.setTaskName(pattern);
if (!consumer.process(GotoTaskAction.CREATE_NEW_TASK_ACTION)) return false;
- List<Task> cachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(myProject), pattern, everywhere);
- if (!processTasks(cachedAndLocalTasks, consumer, cancelled)) return false;
+ TaskManager taskManager = TaskManager.getManager(myProject);
+
+ List<Task> allCachedAndLocalTasks = ContainerUtil.concat(taskManager.getCachedIssues(), taskManager.getLocalTasks());
+ List<Task> filteredCachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(taskManager, pattern, everywhere);
- if (cachedAndLocalTasks.size() >= base.getMaximumListSizeLimit()) {
+ if (!processTasks(filteredCachedAndLocalTasks, consumer, cancelled)) return false;
+
+ if (filteredCachedAndLocalTasks.size() >= base.getMaximumListSizeLimit()) {
return true;
}
@@ -80,15 +82,22 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable {
oldFeature.cancel(true);
}
- if (!myAlarm.isDisposed()) {
- myAlarm.addRequest(future, DELAY_PERIOD);
+ if (myAlarm.isDisposed()) {
return false;
}
+ myAlarm.addRequest(future, DELAY_PERIOD);
try {
List<Task> tasks = future.get();
myFutureReference.compareAndSet(future, null);
- tasks.removeAll(cachedAndLocalTasks);
+
+ // Exclude *all* cached and local issues, not only those returned by TaskSearchSupport.getLocalAndCachedTasks().
+ // Previously used approach might lead to the following strange behavior. Local task excluded by getLocalAndCachedTasks()
+ // as "locally closed" (i.e. having no associated change list) was indeed *included* in popup because it
+ // was contained in server response (as not remotely closed). Moreover on next request with pagination when the
+ // same issues was not returned again by server it was *excluded* from popup (thus subsequent update reduced total
+ // number of items shown).
+ tasks.removeAll(allCachedAndLocalTasks);
return processTasks(tasks, consumer, cancelled);
}
catch (InterruptedException interrupted) {
@@ -138,7 +147,8 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable {
limit = GotoTaskAction.PAGE_SIZE;
myCurrentOffset += GotoTaskAction.PAGE_SIZE;
}
- List<Task> tasks = getRepositoriesTasks(TaskManager.getManager(myProject), pattern, offset, limit, true, everywhere, cancelled);
+ List<Task> tasks = TaskSearchSupport.getRepositoriesTasks(TaskManager.getManager(myProject),
+ pattern, offset, limit, true, everywhere, cancelled);
myOldEverywhere = everywhere;
myOldPattern = pattern;
return tasks;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java
new file mode 100644
index 000000000000..f583be334cfc
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java
@@ -0,0 +1,382 @@
+package com.intellij.tasks.bugzilla;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Version;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.tasks.LocalTask;
+import com.intellij.tasks.Task;
+import com.intellij.tasks.TaskRepositoryType;
+import com.intellij.tasks.TaskState;
+import com.intellij.tasks.impl.BaseRepository;
+import com.intellij.tasks.impl.BaseRepositoryImpl;
+import com.intellij.tasks.impl.RequestFailedException;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.apache.xmlrpc.CommonsXmlRpcTransport;
+import org.apache.xmlrpc.XmlRpcClient;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.XmlRpcRequest;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Mikhail Golubev
+ */
+@SuppressWarnings({"UseOfObsoleteCollectionType", "unchecked"})
+@Tag("Bugzilla")
+public class BugzillaRepository extends BaseRepositoryImpl {
+
+ private static final Logger LOG = Logger.getInstance(BugzillaRepository.class);
+
+ // Copied from SendTimeTrackingInformationDialog
+ public static final Pattern TIME_SPENT_PATTERN = Pattern.compile("([0-9]+)d ([0-9]+)h ([0-9]+)m");
+
+ private Version myVersion;
+
+ private boolean myAuthenticated;
+ private String myAuthenticationToken;
+
+ private String myProductName = "";
+ private String myComponentName = "";
+
+ /**
+ * Serialization constructor
+ */
+ @SuppressWarnings("UnusedDeclaration")
+ public BugzillaRepository() {
+ // empty
+ }
+
+ /**
+ * Normal instantiation constructor
+ */
+ public BugzillaRepository(TaskRepositoryType type) {
+ super(type);
+ setUseHttpAuthentication(false);
+ setUrl("http://myserver.com/xmlrpc.cgi");
+ }
+
+ /**
+ * Cloning constructor
+ */
+ public BugzillaRepository(BugzillaRepository other) {
+ super(other);
+ myProductName = other.myProductName;
+ myComponentName = other.myComponentName;
+ }
+
+ @NotNull
+ @Override
+ public BaseRepository clone() {
+ return new BugzillaRepository(this);
+ }
+
+ @Override
+ public Task[] getIssues(@Nullable String query, int offset, int limit, boolean withClosed, @NotNull ProgressIndicator cancelled)
+ throws Exception {
+ // Method search appeared in Bugzilla 3.4, ensureVersionDiscovered() checks minimal
+ // supported version requirement.
+ Hashtable<String, Object> response = createIssueSearchRequest(query, offset, limit, withClosed).execute();
+
+ Vector<Hashtable<String, Object>> bugs = (Vector<Hashtable<String, Object>>)response.get("bugs");
+ return ContainerUtil.map2Array(bugs, BugzillaTask.class, new Function<Hashtable<String, Object>, BugzillaTask>() {
+ @Override
+ public BugzillaTask fun(Hashtable<String, Object> hashTable) {
+ return new BugzillaTask(hashTable, BugzillaRepository.this);
+ }
+ });
+ }
+
+ private BugzillaXmlRpcRequest createIssueSearchRequest(String query, int offset, int limit, boolean withClosed) throws Exception {
+ // Method search appeared in Bugzilla 3.4, ensureVersionDiscovered() checks minimal
+ // supported version requirement.
+ return new BugzillaXmlRpcRequest("Bug.search")
+ .requireAuthentication(true)
+ .withParameter("summary", StringUtil.isNotEmpty(query) ? newVector(query.split("\\s+")) : null)
+ .withParameter("product", StringUtil.nullize(myProductName))
+ // Bugzilla's API allows to specify component even without parental project
+ .withParameter("component", StringUtil.nullize(myComponentName))
+ .withParameter("offset", offset)
+ .withParameter("limit", limit)
+ .withParameter("assigned_to", getUsername())
+ .withParameter("resolution", !withClosed ? "" : null);
+ }
+
+ @Nullable
+ @Override
+ public Task findTask(@NotNull String id) throws Exception {
+ Hashtable<String, Object> response;
+ try {
+ // In Bugzilla 3.0 this method is called "get_bugs".
+ response = new BugzillaXmlRpcRequest("Bug.get").requireAuthentication(true).withParameter("ids", newVector(id)).execute();
+ }
+ catch (XmlRpcException e) {
+ if (e.code == 101 && e.getMessage().contains("does not exist")) {
+ return null;
+ }
+ throw e;
+ }
+ Vector<Hashtable<String, Object>> bugs = (Vector<Hashtable<String, Object>>)response.get("bugs");
+ if (bugs == null || bugs.isEmpty()) {
+ return null;
+ }
+ return new BugzillaTask(bugs.get(0), this);
+ }
+
+ private void ensureVersionDiscovered() throws Exception {
+ if (myVersion == null) {
+ Hashtable<String, Object> result = new BugzillaXmlRpcRequest("Bugzilla.version").execute();
+ String version = (String)result.get("version");
+ String[] parts = version.split("\\.", 3);
+ myVersion = new Version(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
+ if (myVersion.lessThan(3, 4)) {
+ throw new RequestFailedException("Bugzilla before 3.4 is not supported");
+ }
+ }
+ }
+
+ private void ensureUserAuthenticated() throws Exception {
+ ensureVersionDiscovered();
+ if (!myAuthenticated) {
+ Hashtable<String, Object> response = new BugzillaXmlRpcRequest("User.login")
+ .withParameter("login", getUsername())
+ .withParameter("password", getPassword())
+ .execute();
+ myAuthenticated = true;
+ // Not available in Bugzilla before 4.4
+ myAuthenticationToken = (String)response.get("token");
+ }
+ }
+
+ @Override
+ public void setTaskState(@NotNull Task task, @NotNull TaskState state) throws Exception {
+ BugzillaXmlRpcRequest request = new BugzillaXmlRpcRequest("Bug.update")
+ .requireAuthentication(true)
+ .withParameter("ids", newVector(task.getId()));
+
+ switch (state) {
+ case IN_PROGRESS:
+ request.withParameter("status", "IN_PROGRESS");
+ break;
+ case RESOLVED:
+ request.withParameter("status", "RESOLVED").withParameter("resolution", "FIXED");
+ break;
+ default:
+ return;
+ }
+
+ request.execute();
+ }
+
+ @Override
+ public void updateTimeSpent(@NotNull LocalTask task, @NotNull String timeSpent, @NotNull String comment) throws Exception {
+ LOG.debug(String.format("Last post: %s, time spent from last: %s, time spent: %s",
+ task.getLastPost(), task.getTimeSpentFromLastPost(), timeSpent));
+ Matcher matcher = TIME_SPENT_PATTERN.matcher(timeSpent);
+ if (matcher.find()) {
+ int days = Integer.valueOf(matcher.group(1));
+ int hours = Integer.valueOf(matcher.group(2));
+ int minutes = Integer.valueOf(matcher.group(3));
+ BugzillaXmlRpcRequest request = new BugzillaXmlRpcRequest("Bug.update")
+ .requireAuthentication(true)
+ .withParameter("ids", newVector(task.getId()))
+ // the number of hours worked on the bug as double
+ .withParameter("work_time", days * 24 + hours + minutes / 60.0);
+ if (!StringUtil.isEmptyOrSpaces(comment)) {
+ request.withParameter("comment", newHashTable("body", comment, "is_private", false));
+ }
+ request.execute();
+ } else {
+ LOG.error("Illegal time spent format: " + timeSpent);
+ }
+ }
+
+ /**
+ * @return pair where first element is list of project names and second is list of component names (will be empty for Bugzilla < 4.2)
+ */
+ @NotNull
+ public Pair<List<String>, List<String>> fetchProductAndComponentNames() throws Exception {
+ Hashtable<String, Vector<Integer>> productIdsResponse = new BugzillaXmlRpcRequest("Product.get_selectable_products")
+ .requireAuthentication(true)
+ .execute();
+
+ Hashtable<String, Object> productInfoResponse = new BugzillaXmlRpcRequest("Product.get")
+ .requireAuthentication(true)
+ .withParameter("ids", productIdsResponse.get("ids"))
+ .execute();
+
+ List<String> productNames = new ArrayList<String>();
+ List<String> componentNames = new ArrayList<String>();
+
+ for (Hashtable<String, Object> info : (Vector<Hashtable<String, Object>>)productInfoResponse.get("products")) {
+ productNames.add((String)info.get("name"));
+ if (myVersion != null && myVersion.isOrGreaterThan(4, 2)) {
+ for (Hashtable<String, Object> component : (Vector<Hashtable<String, Object>>)info.get("components")) {
+ componentNames.add((String)component.get("name"));
+ }
+ }
+ }
+ return Pair.create(productNames, componentNames);
+ }
+
+ @Nullable
+ @Override
+ public CancellableConnection createCancellableConnection() {
+ return new CancellableConnection() {
+
+ BugzillaXmlRpcRequest myRequest;
+
+ @Override
+ protected void doTest() throws Exception {
+ // Reset information about server.
+ myVersion = null;
+ myAuthenticated = false;
+ myAuthenticationToken = null;
+
+ myRequest = createIssueSearchRequest(null, 0, 1, true);
+ myRequest.execute();
+ }
+
+ @Override
+ public void cancel() {
+ myRequest.cancel();
+ }
+ };
+ }
+
+ private static <T> Vector<T> newVector(T... elements) {
+ return new Vector<T>(Arrays.asList(elements));
+ }
+
+ private static <K, V> Hashtable<K, V> newHashTable(Object... pairs) {
+ assert pairs.length % 2 == 0;
+ Hashtable<K, V> table = new Hashtable<K, V>();
+ for (int i = 0; i < pairs.length; i += 2) {
+ // Null values are not allowed, because Bugzilla reacts unexpectedly on them.
+ if (pairs[i + 1] != null) {
+ table.put((K)pairs[i], (V)pairs[i + 1]);
+ }
+ }
+ return table;
+ }
+
+ @Nullable
+ @Override
+ public String extractId(@NotNull String taskName) {
+ String id = taskName.trim();
+ return id.matches("\\d+") ? id : null;
+ }
+
+ @Override
+ public boolean isConfigured() {
+ return super.isConfigured() && StringUtil.isNotEmpty(getUsername()) && StringUtil.isNotEmpty(getPassword());
+ }
+
+ @Override
+ protected int getFeatures() {
+ int features = super.getFeatures();
+ // Status and work time updates are available through Bug.update method which is available only in Bugzilla 4.0+
+ if (myVersion != null && myVersion.isOrGreaterThan(4, 0)) {
+ return features | STATE_UPDATING | TIME_MANAGEMENT;
+ }
+ return features;
+ }
+
+ private class BugzillaXmlRpcRequest {
+ // Copied from Trac repository
+ private class Transport extends CommonsXmlRpcTransport {
+ public Transport() throws MalformedURLException {
+ super(new URL(getUrl()), getHttpClient());
+ }
+
+ public void cancel() {
+ method.abort();
+ }
+ }
+
+ private final String myMethodName;
+ private boolean myRequireAuthentication;
+ private final HashMap<String, Object> myParameters = new HashMap<String, Object>();
+ private final Transport myTransport;
+
+ public BugzillaXmlRpcRequest(@NotNull String methodName) throws MalformedURLException {
+ myMethodName = methodName;
+ myTransport = new Transport();
+ }
+
+ public BugzillaXmlRpcRequest withParameter(@NotNull String name, @Nullable Object value) {
+ if (value != null) {
+ myParameters.put(name, value);
+ }
+ return this;
+ }
+
+ public BugzillaXmlRpcRequest requireAuthentication(boolean require) {
+ myRequireAuthentication = require;
+ return this;
+ }
+
+ public void cancel() {
+ myTransport.cancel();
+ }
+
+ public <T> T execute() throws Exception {
+ if (myRequireAuthentication) {
+ ensureUserAuthenticated();
+ // Bugzilla [3.0, 4.4) uses cookies authentication.
+ // Bugzilla [3.6, ...) allows to send login ("Bugzilla_login") and password ("Bugzilla_password")
+ // with every requests for automatic authentication (not used here).
+ // Bugzilla [4.4, ...) also allows to send token ("Bugzilla_token") returned by call to User.login
+ // with any request to its API.
+ if (myVersion.isOrGreaterThan(4, 4) && myAuthenticationToken != null) {
+ myParameters.put("Bugzilla_token", myAuthenticationToken);
+ }
+ }
+ Vector<Hashtable<String, Object>> parameters = new Vector<Hashtable<String, Object>>();
+ parameters.add(new Hashtable<String, Object>(myParameters));
+ return (T)new XmlRpcClient(getUrl()).execute(new XmlRpcRequest(myMethodName, parameters), myTransport);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!super.equals(o)) return false;
+
+ if (!(o instanceof BugzillaRepository)) return false;
+ BugzillaRepository repository = (BugzillaRepository)o;
+
+ if (!Comparing.equal(myProductName, repository.getProductName())) return false;
+ if (!Comparing.equal(myComponentName, repository.getComponentName())) return false;
+
+ return true;
+ }
+
+ @NotNull
+ public String getProductName() {
+ return myProductName;
+ }
+
+ public void setProductName(@NotNull String productName) {
+ myProductName = productName;
+ }
+
+ @NotNull
+ public String getComponentName() {
+ return myComponentName;
+ }
+
+ public void setComponentName(@NotNull String componentName) {
+ myComponentName = componentName;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryEditor.java
new file mode 100644
index 000000000000..2ae56e9bbac3
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryEditor.java
@@ -0,0 +1,101 @@
+package com.intellij.tasks.bugzilla;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.tasks.config.BaseRepositoryEditor;
+import com.intellij.ui.TextFieldWithAutoCompletion;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.util.Consumer;
+import com.intellij.util.ui.FormBuilder;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class BugzillaRepositoryEditor extends BaseRepositoryEditor<BugzillaRepository> {
+ private static final Logger LOG = Logger.getInstance(BugzillaRepository.class);
+
+ private JBLabel myProductLabel;
+ private TextFieldWithAutoCompletion<String> myProductInput;
+
+ private JBLabel myComponentLabel;
+ private TextFieldWithAutoCompletion<String> myComponentInput;
+
+ public BugzillaRepositoryEditor(Project project,
+ BugzillaRepository repository,
+ Consumer<BugzillaRepository> changeListener) {
+ super(project, repository, changeListener);
+
+ myUseHttpAuthenticationCheckBox.setVisible(false);
+
+ installListener(myProductInput);
+ installListener(myComponentInput);
+
+ myTestButton.setEnabled(myRepository.isConfigured());
+
+ if (myRepository.isConfigured()) {
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ installProductAndComponentCompletion();
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void afterTestConnection(boolean connectionSuccessful) {
+ super.afterTestConnection(connectionSuccessful);
+ if (connectionSuccessful) {
+ installProductAndComponentCompletion();
+ }
+ }
+
+ @Override
+ public void apply() {
+ super.apply();
+ myRepository.setProductName(myProductInput.getText());
+ myRepository.setComponentName(myComponentInput.getText());
+
+ myTestButton.setEnabled(myRepository.isConfigured());
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCustomPanel() {
+ myProductLabel = new JBLabel("Product:", SwingConstants.RIGHT);
+ myProductInput = TextFieldWithAutoCompletion.create(myProject, Collections.<String>emptyList(), true,
+ myRepository.getProductName());
+ myComponentLabel = new JBLabel("Component:", SwingConstants.RIGHT);
+ myComponentInput = TextFieldWithAutoCompletion.create(myProject, Collections.<String>emptyList(), false,
+ myRepository.getComponentName());
+ return FormBuilder.createFormBuilder()
+ .addLabeledComponent(myProductLabel, myProductInput)
+ .addLabeledComponent(myComponentLabel, myComponentInput)
+ .getPanel();
+ }
+
+ private void installProductAndComponentCompletion() {
+ try {
+ Pair<List<String>, List<String>> pair = myRepository.fetchProductAndComponentNames();
+ myProductInput.setVariants(pair.getFirst());
+ myComponentInput.setVariants(pair.getSecond());
+ }
+ catch (Exception e) {
+ LOG.warn(e);
+ }
+ }
+
+ @Override
+ public void setAnchor(@Nullable JComponent anchor) {
+ super.setAnchor(anchor);
+ myProductLabel.setAnchor(anchor);
+ myComponentLabel.setAnchor(anchor);
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryType.java
new file mode 100644
index 000000000000..693488757cc3
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepositoryType.java
@@ -0,0 +1,54 @@
+package com.intellij.tasks.bugzilla;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.tasks.TaskRepository;
+import com.intellij.tasks.TaskRepositoryType;
+import com.intellij.tasks.TaskState;
+import com.intellij.tasks.config.TaskRepositoryEditor;
+import com.intellij.util.Consumer;
+import icons.TasksIcons;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.EnumSet;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class BugzillaRepositoryType extends TaskRepositoryType<BugzillaRepository> {
+ @NotNull
+ @Override
+ public String getName() {
+ return "Bugzilla";
+ }
+
+ @NotNull
+ @Override
+ public Icon getIcon() {
+ return TasksIcons.Bugzilla;
+ }
+
+ @NotNull
+ @Override
+ public TaskRepositoryEditor createEditor(BugzillaRepository repository, Project project, Consumer<BugzillaRepository> changeListener) {
+ return new BugzillaRepositoryEditor(project, repository, changeListener);
+ }
+
+ @NotNull
+ @Override
+ public TaskRepository createRepository() {
+ return new BugzillaRepository(this);
+ }
+
+ @Override
+ public Class<BugzillaRepository> getRepositoryClass() {
+ return BugzillaRepository.class;
+ }
+
+ @Override
+ public EnumSet<TaskState> getPossibleTaskStates() {
+ // UNCONFIRMED, CONFIRMED, IN_PROGRESS, RESOLVED (resolution=FIXED)
+ return EnumSet.of(TaskState.SUBMITTED, TaskState.OPEN, TaskState.IN_PROGRESS, TaskState.RESOLVED);
+ }
+}
+
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaTask.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaTask.java
new file mode 100644
index 000000000000..5c94ad2edf0a
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaTask.java
@@ -0,0 +1,102 @@
+package com.intellij.tasks.bugzilla;
+
+import com.intellij.tasks.Comment;
+import com.intellij.tasks.Task;
+import com.intellij.tasks.TaskRepository;
+import com.intellij.tasks.TaskType;
+import icons.TasksIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Date;
+import java.util.Hashtable;
+
+/**
+ * @author Mikhail Golubev
+ */
+@SuppressWarnings("UseOfObsoleteCollectionType")
+public class BugzillaTask extends Task {
+ private final Hashtable<String, Object> myResponse;
+ private final BugzillaRepository myRepository;
+
+ public BugzillaTask(@NotNull Hashtable<String, Object> xmlRpcResponse, @NotNull BugzillaRepository repository) {
+ myResponse = xmlRpcResponse;
+ myRepository = repository;
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return String.valueOf(myResponse.get("id"));
+ }
+
+ @NotNull
+ @Override
+ public String getSummary() {
+ return (String)myResponse.get("summary");
+ }
+
+ @Nullable
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public Comment[] getComments() {
+ return Comment.EMPTY_ARRAY;
+ }
+
+ @NotNull
+ @Override
+ public Icon getIcon() {
+ return TasksIcons.Bugzilla;
+ }
+
+ @NotNull
+ @Override
+ public TaskType getType() {
+ String severity = (String)myResponse.get("severity");
+ return severity.equalsIgnoreCase("enhancement")? TaskType.FEATURE : TaskType.BUG;
+ }
+
+ @Nullable
+ @Override
+ public Date getUpdated() {
+ return (Date)myResponse.get("last_change_time");
+ }
+
+ @Nullable
+ @Override
+ public Date getCreated() {
+ return (Date)myResponse.get("creation_time");
+ }
+
+ @Override
+ public boolean isClosed() {
+ return !(Boolean)myResponse.get("is_open");
+ }
+
+ @Override
+ public boolean isIssue() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public String getIssueUrl() {
+ String repositoryUrl = myRepository.getUrl();
+ if (repositoryUrl.endsWith("xmlrpc.cgi")) {
+ repositoryUrl = repositoryUrl.substring(0, repositoryUrl.length() - "xmlrpc.cgi".length());
+ }
+ return repositoryUrl + "/show_bug.cgi?id=" + getId();
+ }
+
+ @Nullable
+ @Override
+ public TaskRepository getRepository() {
+ return myRepository;
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
index 5dadcdfb0e8f..e63b2b365e60 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
@@ -48,6 +49,12 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
return "-- from all projects --";
}
+ @Nullable
+ @Override
+ public String getIdentifier() {
+ return getName();
+ }
+
@Override
public int getId() {
return -1;
@@ -108,7 +115,11 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
// /users/current.json. Unfortunately this endpoint may be unavailable on some old servers (see IDEA-122845)
// and in this case we have to come back to requesting issues in this case to test anything at all.
HttpClient client = getHttpClient();
- HttpResponse response = client.execute(new HttpGet(getRestApiUrl("users", "current.json")));
+ URIBuilder uriBuilder = new URIBuilder(getRestApiUrl("users", "current.json"));
+ if (isUseApiKeyAuthentication()) {
+ uriBuilder.addParameter("key", getAPIKey());
+ }
+ HttpResponse response = client.execute(new HttpGet(uriBuilder.build()));
//TaskUtil.prettyFormatResponseToLog(LOG, response);
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_NOT_FOUND) {
@@ -144,9 +155,9 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
// builder.addParameter("fields[]", "subject").addParameter("operators[subject]", "~").addParameter("values[subject][]", query);
//}
// If project was not chosen, all available issues still fetched. Such behavior may seems strange to user.
- if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) {
- builder.addParameter("project_id", String.valueOf(myCurrentProject.getId()));
- }
+ //if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) {
+ // builder.addParameter("project_id", String.valueOf(myCurrentProject.getId()));
+ //}
if (isUseApiKeyAuthentication()) {
builder.addParameter("key", myAPIKey);
}
@@ -157,14 +168,27 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
}
public List<RedmineProject> fetchProjects() throws Exception {
- URIBuilder builder = new URIBuilder(getRestApiUrl("projects.json"));
- if (isUseApiKeyAuthentication()) {
- builder.addParameter("key", myAPIKey);
- }
HttpClient client = getHttpClient();
- HttpGet method = new HttpGet(builder.toString());
- ProjectsWrapper wrapper = client.execute(method, new GsonSingleObjectDeserializer<ProjectsWrapper>(GSON, ProjectsWrapper.class));
- myProjects = wrapper.getProjects();
+ // Download projects with pagination (IDEA-125056, IDEA-125157)
+ List<RedmineProject> allProjects = new ArrayList<RedmineProject>();
+ int offset = 0;
+ ProjectsWrapper wrapper;
+ do {
+ URIBuilder builder = new URIBuilder(getRestApiUrl("projects.json"));
+ builder.addParameter("offset", String.valueOf(offset));
+ builder.addParameter("limit", "50");
+ if (isUseApiKeyAuthentication()) {
+ builder.addParameter("key", myAPIKey);
+ }
+
+ HttpGet method = new HttpGet(builder.toString());
+ wrapper = client.execute(method, new GsonSingleObjectDeserializer<ProjectsWrapper>(GSON, ProjectsWrapper.class));
+ offset += wrapper.getProjects().size();
+ allProjects.addAll(wrapper.getProjects());
+ }
+ while (wrapper.getTotalCount() > allProjects.size() || wrapper.getProjects().isEmpty());
+
+ myProjects = allProjects;
return Collections.unmodifiableList(myProjects);
}
@@ -189,7 +213,7 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
}
private boolean isUseApiKeyAuthentication() {
- return !StringUtil.isEmptyOrSpaces(myAPIKey) && !isUseHttpAuthentication();
+ return !isUseHttpAuthentication() && StringUtil.isNotEmpty(myAPIKey);
}
@Override
@@ -203,17 +227,17 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
@Override
public boolean isConfigured() {
- if (!super.isConfigured() || StringUtil.isEmpty(myUsername)) return false;
+ if (!super.isConfigured()) return false;
if (isUseHttpAuthentication()) {
- return StringUtil.isNotEmpty(myPassword);
+ return StringUtil.isNotEmpty(myPassword) && StringUtil.isNotEmpty(myUsername);
}
- return !StringUtil.isEmptyOrSpaces(myAPIKey);
+ return StringUtil.isNotEmpty(myAPIKey);
}
@Nullable
@Override
public String extractId(@NotNull String taskName) {
- return ID_PATTERN.matcher(taskName).matches()? taskName : null;
+ return ID_PATTERN.matcher(taskName).matches() ? taskName : null;
}
@Override
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepositoryEditor.java
index 46ee77a9ac7d..1ca2971d2be0 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepositoryEditor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepositoryEditor.java
@@ -6,14 +6,17 @@ import com.intellij.openapi.ui.ComboBox;
import com.intellij.tasks.config.BaseRepositoryEditor;
import com.intellij.tasks.impl.TaskUiUtil;
import com.intellij.tasks.redmine.model.RedmineProject;
+import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Consumer;
+import com.intellij.util.containers.Stack;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -35,6 +38,8 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
installListener(myProjectCombo);
installListener(myAPIKey);
+ toggleCredentialsVisibility();
+
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
@@ -48,6 +53,9 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
if (connectionSuccessful) {
new FetchProjectsTask().queue();
}
+ else {
+ myProjectCombo.removeAllItems();
+ }
}
private void initialize() {
@@ -55,14 +63,30 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
if (currentProject != null && myRepository.isConfigured()) {
new FetchProjectsTask().queue();
}
+ else {
+ myProjectCombo.removeAllItems();
+ }
}
@Override
public void apply() {
super.apply();
- myRepository.setCurrentProject((RedmineProject)myProjectCombo.getSelectedItem());
+ RedmineProjectItem selected = (RedmineProjectItem)myProjectCombo.getSelectedItem();
+ myRepository.setCurrentProject(selected != null ? selected.myProject : null);
myRepository.setAPIKey(myAPIKey.getText().trim());
myTestButton.setEnabled(myRepository.isConfigured());
+ toggleCredentialsVisibility();
+ }
+
+ private void toggleCredentialsVisibility() {
+ myPasswordLabel.setVisible(myRepository.isUseHttpAuthentication());
+ myPasswordText.setVisible(myRepository.isUseHttpAuthentication());
+
+ myUsernameLabel.setVisible(myRepository.isUseHttpAuthentication());
+ myUserNameText.setVisible(myRepository.isUseHttpAuthentication());
+
+ myAPIKeyLabel.setVisible(!myRepository.isUseHttpAuthentication());
+ myAPIKey.setVisible(!myRepository.isUseHttpAuthentication());
}
@Nullable
@@ -70,9 +94,35 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
protected JComponent createCustomPanel() {
myProjectLabel = new JBLabel("Project:", SwingConstants.RIGHT);
myProjectCombo = new ComboBox(300);
- myProjectCombo.setRenderer(new TaskUiUtil.SimpleComboBoxRenderer("Set URL and password/token first"));
+ //myProjectCombo.setRenderer(new TaskUiUtil.SimpleComboBoxRenderer("Set URL and password/token first"));
+ myProjectCombo.setRenderer(new ListCellRendererWrapper<RedmineProjectItem>() {
+ @Override
+ public void customize(JList list, RedmineProjectItem value, int index, boolean selected, boolean hasFocus) {
+ if (value == null) {
+ setText("Set URL and password/token first");
+ }
+ else {
+ if (myProjectCombo.isPopupVisible()) {
+ //if (value.myLevel == 0 && value.myProject != RedmineRepository.UNSPECIFIED_PROJECT) {
+ //setFont(UIUtil.getListFont().deriveFont(Font.BOLD));
+ //}
+ StringBuilder builder = new StringBuilder();
+ if (value.myLevel != 0) {
+ for (int i = 0; i < value.myLevel; i++) {
+ builder.append(" ");
+ }
+ }
+ setText(builder.append(value.myProject.getIdentifier()).toString());
+ }
+ else {
+ setText(value.myProject.getIdentifier());
+ }
+ }
+ }
+ });
+
myAPIKeyLabel = new JBLabel("API Token:", SwingConstants.RIGHT);
- myAPIKey = new JTextField();
+ myAPIKey = new JPasswordField();
return FormBuilder.createFormBuilder()
.addLabeledComponent(myAPIKeyLabel, myAPIKey)
.addLabeledComponent(myProjectLabel, myProjectCombo)
@@ -86,26 +136,74 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
myAPIKeyLabel.setAnchor(anchor);
}
- private class FetchProjectsTask extends TaskUiUtil.ComboBoxUpdater<RedmineProject> {
+ private static class RedmineProjectItem {
+ public final RedmineProject myProject;
+ public final int myLevel;
+
+ public RedmineProjectItem(@NotNull RedmineProject project, int level) {
+ myProject = project;
+ myLevel = level;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+
+ if (o instanceof RedmineProject) {
+ return myProject.equals(o);
+ }
+ else if (o instanceof RedmineProjectItem) {
+ return myProject.equals(((RedmineProjectItem)o).myProject);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return myProject.hashCode();
+ }
+ }
+
+ private class FetchProjectsTask extends TaskUiUtil.ComboBoxUpdater<RedmineProjectItem> {
private FetchProjectsTask() {
super(RedmineRepositoryEditor.this.myProject, "Downloading Redmine projects...", myProjectCombo);
}
@Override
- public RedmineProject getExtraItem() {
- return RedmineRepository.UNSPECIFIED_PROJECT;
+ public RedmineProjectItem getExtraItem() {
+ return new RedmineProjectItem(RedmineRepository.UNSPECIFIED_PROJECT, 0);
}
@Nullable
@Override
- public RedmineProject getSelectedItem() {
- return myRepository.getCurrentProject();
+ public RedmineProjectItem getSelectedItem() {
+ RedmineProject currentProject = myRepository.getCurrentProject();
+ return currentProject != null ? new RedmineProjectItem(currentProject, -1) : null;
}
@NotNull
@Override
- protected List<RedmineProject> fetch(@NotNull ProgressIndicator indicator) throws Exception {
- return myRepository.fetchProjects();
+ protected List<RedmineProjectItem> fetch(@NotNull ProgressIndicator indicator) throws Exception {
+ // Seems that Redmine always return its project hierarchy in DFS order.
+ // So it's easy to find level of each project using stack of parents.
+ Stack<RedmineProject> parents = new Stack<RedmineProject>();
+ List<RedmineProjectItem> items = new ArrayList<RedmineProjectItem>();
+ for (RedmineProject project : myRepository.fetchProjects()) {
+ RedmineProject parentProject = project.getParent();
+ if (parentProject == null) {
+ items.add(new RedmineProjectItem(project, 0));
+ parents.clear();
+ }
+ else {
+ while (!parents.isEmpty() && !parents.peek().equals(parentProject)) {
+ parents.pop();
+ }
+ items.add(new RedmineProjectItem(project, parents.size()));
+ }
+ parents.push(project);
+ }
+ return items;
}
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/model/RedmineProject.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/model/RedmineProject.java
index 164c5d169068..bee3d35dbeb9 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/model/RedmineProject.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/model/RedmineProject.java
@@ -17,6 +17,8 @@ public class RedmineProject {
private String name;
// Missing in Project information sent as part of issue
private String identifier;
+ // Available only for subprojects
+ private RedmineProject parent;
@Override
public final boolean equals(Object o) {
@@ -63,6 +65,11 @@ public class RedmineProject {
this.identifier = identifier;
}
+ @Nullable
+ public RedmineProject getParent() {
+ return parent;
+ }
+
@Override
public final String toString() {
return getName();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java
index 67b95abdb4aa..81326b9a1fe3 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/lang/codeinsight/YouTrackCompletionContributor.java
@@ -34,7 +34,7 @@ public class YouTrackCompletionContributor extends CompletionContributor {
private static final InsertHandler<LookupElement> INSERT_HANDLER = new MyInsertHandler();
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (LOG.isDebugEnabled()) {
LOG.debug(DebugUtil.psiToString(parameters.getOriginalFile(), true));
}
diff --git a/plugins/tasks/tasks-core/src/icons/TasksIcons.java b/plugins/tasks/tasks-core/src/icons/TasksIcons.java
index 64d63c1a7c37..68a2e24608ea 100644
--- a/plugins/tasks/tasks-core/src/icons/TasksIcons.java
+++ b/plugins/tasks/tasks-core/src/icons/TasksIcons.java
@@ -32,6 +32,7 @@ public class TasksIcons {
public static final Icon Assembla = load("/icons/assembla.png"); // 16x16
public static final Icon AutoMode = load("/icons/autoMode.png"); // 16x16
public static final Icon Bug = load("/icons/bug.png"); // 16x16
+ public static final Icon Bugzilla = load("/icons/bugzilla.png"); // 16x16
public static final Icon Clock = load("/icons/clock.png"); // 13x13
public static final Icon Exception = load("/icons/exception.png"); // 16x16
public static final Icon Feature = load("/icons/feature.png"); // 16x16
diff --git a/plugins/tasks/tasks-core/src/icons/bugzilla.png b/plugins/tasks/tasks-core/src/icons/bugzilla.png
new file mode 100644
index 000000000000..b06da57f512e
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/icons/bugzilla.png
Binary files differ
diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
index b61c451ffa70..0a9acf231499 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -54,7 +54,7 @@ public class TestNGReferenceContributor extends PsiReferenceContributor {
return PlatformPatterns.psiElement(PsiLiteralExpression.class).and(new FilterPattern(new TestAnnotationFilter(annotation)));
}
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(getElementPattern("dependsOnMethods"), new PsiReferenceProvider() {
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGSuiteReferenceContributor.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGSuiteReferenceContributor.java
index 4629f624ff05..dc592d833b81 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/TestNGSuiteReferenceContributor.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGSuiteReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.PathListReferenceProvider;
+import org.jetbrains.annotations.NotNull;
import org.testng.IMethodSelector;
import static com.intellij.patterns.XmlPatterns.*;
@@ -55,7 +56,7 @@ public class TestNGSuiteReferenceContributor extends PsiReferenceContributor {
.withParent(xmlTag().withName("suite-files")
.withParent(xmlTag().withName("suite")))));
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(ourTestClassPattern, new JavaClassReferenceProvider());
registrar.registerReferenceProvider(ourListenerClassPattern, new JavaClassReferenceProvider());
diff --git a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
index cde8dac56951..cc87a11d2e3c 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
@@ -269,7 +269,7 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
} else {
suffix = "";
}
- Set<String> patterns = new HashSet<String>();
+ Set<String> patterns = new LinkedHashSet<String>();
for (PsiClass pattern : classes) {
patterns.add(JavaExecutionUtil.getRuntimeQualifiedName(pattern) + suffix);
}
diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
index 55a6a3db11b5..b40ab4c3ef03 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
@@ -57,7 +57,7 @@ public class TestData implements Cloneable
public List<String> TEST_LISTENERS = new ArrayList<String>();
public boolean USE_DEFAULT_REPORTERS = false;
public String PROPERTIES_FILE;
- private Set<String> myPatterns = new HashSet<String>();
+ private Set<String> myPatterns = new LinkedHashSet<String>();
public TestData() {
TEST_OBJECT = TestType.CLASS.getType();
diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java
index 322306d4f89c..1aae7cdf4e5a 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestNGConsoleProperties.java
@@ -40,6 +40,6 @@ public class TestNGConsoleProperties extends JavaAwareTestConsoleProperties {
@Override
protected GlobalSearchScope initScope() {
- return myConfiguration.getPersistantData().getScope().getSourceScope(myConfiguration).getLibrariesScope();
+ return myConfiguration.getPersistantData().getScope().getSourceScope(myConfiguration).getGlobalSearchScope();
}
}
diff --git a/plugins/typeMigration/src/META-INF/plugin.xml b/plugins/typeMigration/src/META-INF/plugin.xml
new file mode 100644
index 000000000000..93ad2032892c
--- /dev/null
+++ b/plugins/typeMigration/src/META-INF/plugin.xml
@@ -0,0 +1,39 @@
+<idea-plugin>
+ <name>Type Migration</name>
+ <description>
+ <![CDATA[
+ This plugin adds the type migration refactoring.
+ The following features are available:
+ <ul>
+ <li>Dedicated Refactoring Dialog. (Refactor | Type Migration)</li>
+ <li>Ability to review type migration results. (Refactor | Migration | Preview)</li>
+ <li>Ability to automatically change a member type or data flow dependent type entries.</li>
+ <li>Ability to convert variable or method return type between arrays and collections.</li>
+ </ul>
+ ]]>
+ </description>
+ <vendor>JetBrains</vendor>
+ <extensions defaultExtensionNs="com.intellij">
+ <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+ <codeInsight.changeVariableTypeQuickFixProvider
+ implementation="com.intellij.refactoring.typeMigration.TypeMigrationVariableTypeFixProvider"/>
+ <conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ListArrayConversionRule"/>
+ <conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.AtomicConversionRule"/>
+ <conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.BoxingTypeConversionRule"/>
+ <conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ElementToArrayConversionRule"/>
+ <conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule"/>
+ <intentionAction>
+ <className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention</className>
+ <category>Concurrency</category>
+ </intentionAction>
+ <intentionAction>
+ <className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToThreadLocalIntention</className>
+ <category>Concurrency</category>
+ </intentionAction>
+ <intentionAction>
+ <className>com.intellij.refactoring.typeMigration.intentions.ChangeClassParametersIntention</className>
+ <category>Declaration</category>
+ </intentionAction>
+ </extensions>
+ <depends>Structural Search</depends>
+</idea-plugin>
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java
new file mode 100644
index 000000000000..d116c3ce30fe
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java
@@ -0,0 +1,101 @@
+package com.intellij.refactoring.typeMigration;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.structuralsearch.MatchOptions;
+import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
+import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Sep 28, 2004
+ * Time: 7:13:53 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
+ private static final Logger LOG = Logger.getInstance("#" + TypeConversionDescriptor.class.getName());
+
+ private String myStringToReplace = null;
+ private String myReplaceByString = "$";
+ private PsiExpression myExpression;
+
+ public TypeConversionDescriptor(@NonNls final String stringToReplace, @NonNls final String replaceByString) {
+ myStringToReplace = stringToReplace;
+ myReplaceByString = replaceByString;
+ }
+
+ public TypeConversionDescriptor(@NonNls final String stringToReplace, @NonNls final String replaceByString, final PsiExpression expression) {
+ myStringToReplace = stringToReplace;
+ myReplaceByString = replaceByString;
+ myExpression = expression;
+ }
+
+ public void setStringToReplace(String stringToReplace) {
+ myStringToReplace = stringToReplace;
+ }
+
+ public void setReplaceByString(String replaceByString) {
+ myReplaceByString = replaceByString;
+ }
+
+ public String getStringToReplace() {
+ return myStringToReplace;
+ }
+
+ public String getReplaceByString() {
+ return myReplaceByString;
+ }
+
+ public PsiExpression getExpression() {
+ return myExpression;
+ }
+
+ public void setExpression(final PsiExpression expression) {
+ myExpression = expression;
+ }
+
+ @Override
+ public void replace(PsiExpression expression) {
+ if (getExpression() != null) expression = getExpression();
+ final Project project = expression.getProject();
+ final ReplaceOptions options = new ReplaceOptions();
+ options.setMatchOptions(new MatchOptions());
+ final Replacer replacer = new Replacer(project, null);
+ try {
+ final String replacement = replacer.testReplace(expression.getText(), getStringToReplace(), getReplaceByString(), options);
+ try {
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(expression.replace(
+ JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(replacement, expression)));
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ if (myReplaceByString != null) {
+ buf.append(myReplaceByString);
+ }
+ if (myStringToReplace != null) {
+ if (buf.length() > 0) buf.append(" ");
+ buf.append(myStringToReplace);
+ }
+ if (myExpression != null) {
+ if (buf.length() > 0) buf.append(" ");
+ buf.append(myExpression.getText());
+ }
+ return buf.toString();
+ }
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java
new file mode 100644
index 000000000000..d84320e4cd08
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java
@@ -0,0 +1,61 @@
+/*
+ * User: anna
+ * Date: 27-Aug-2009
+ */
+package com.intellij.refactoring.typeMigration;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
+import com.intellij.openapi.command.undo.UndoUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class TypeMigrationVariableTypeFixProvider implements ChangeVariableTypeQuickFixProvider {
+ private static final Logger LOG1 = Logger.getInstance("#" + TypeMigrationVariableTypeFixProvider.class.getName());
+
+ @NotNull
+ public IntentionAction[] getFixes(@NotNull PsiVariable variable, @NotNull PsiType toReturn) {
+ return new IntentionAction[]{new VariableTypeFix(variable, toReturn) {
+ @NotNull
+ @Override
+ public String getText() {
+ return "Migrate \'" + myName + "\' type to \'" + getReturnType().getCanonicalText() + "\'";
+ }
+
+ @Override
+ public void invoke(@NotNull Project project,
+ @NotNull PsiFile file,
+ @Nullable("is null when called from inspection") Editor editor,
+ @NotNull PsiElement startElement,
+ @NotNull PsiElement endElement) {
+ final PsiVariable myVariable = (PsiVariable)startElement;
+
+ if (!FileModificationService.getInstance().prepareFileForWrite(myVariable.getContainingFile())) return;
+ try {
+ myVariable.normalizeDeclaration();
+ final TypeMigrationRules rules = new TypeMigrationRules(TypeMigrationLabeler.getElementType(myVariable));
+ rules.setMigrationRootType(getReturnType());
+ rules.setBoundScope(GlobalSearchScope.projectScope(project));
+ TypeMigrationProcessor.runHighlightingTypeMigration(project, editor, rules, myVariable);
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(myVariable);
+ UndoUtil.markPsiFileForUndo(file);
+ }
+ catch (IncorrectOperationException e) {
+ LOG1.error(e);
+ }
+ }
+ }};
+ }
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java
new file mode 100644
index 000000000000..9571807cd229
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ChangeClassParametersIntention.java
@@ -0,0 +1,124 @@
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.codeInsight.intention.impl.TypeExpression;
+import com.intellij.codeInsight.template.*;
+import com.intellij.codeInsight.template.impl.TemplateState;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author anna
+ */
+public class ChangeClassParametersIntention extends PsiElementBaseIntentionAction {
+
+ private static final Logger LOG = Logger.getInstance("#" + ChangeClassParametersIntention.class);
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return "Change class type parameter";
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ final PsiTypeElement typeElement = PsiTreeUtil.getTopmostParentOfType(element, PsiTypeElement.class);
+ final PsiElement parent = typeElement != null ? typeElement.getParent() : null;
+ final PsiReferenceParameterList parameterList = parent instanceof PsiReferenceParameterList ? (PsiReferenceParameterList)parent : null;
+ if (parameterList != null && parameterList.getTypeArguments().length > 0) {
+ final PsiMember member = PsiTreeUtil.getParentOfType(parameterList, PsiMember.class);
+ if (member instanceof PsiAnonymousClass) {
+ final PsiClassType.ClassResolveResult result = ((PsiAnonymousClass)member).getBaseClassType().resolveGenerics();
+ return result.getElement() != null && ((PsiAnonymousClass)member).getBaseClassReference().getParameterList() == parameterList;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException {
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) return;
+
+ final PsiTypeElement typeElement = PsiTreeUtil.getTopmostParentOfType(element, PsiTypeElement.class);
+ final PsiReferenceParameterList parameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
+ if (parameterList != null && typeElement != null) {
+ final PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
+ if (aClass instanceof PsiAnonymousClass) {
+ editor.getCaretModel().moveToOffset(aClass.getTextOffset());
+ final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
+ final int changeIdx = ArrayUtil.find(typeElements, typeElement);
+
+ final PsiClassType.ClassResolveResult result = ((PsiAnonymousClass)aClass).getBaseClassType().resolveGenerics();
+ final PsiClass baseClass = result.getElement();
+ LOG.assertTrue(baseClass != null);
+ final PsiTypeParameter typeParameter = baseClass.getTypeParameters()[changeIdx];
+
+ final TemplateBuilderImpl templateBuilder = (TemplateBuilderImpl)TemplateBuilderFactory.getInstance().createTemplateBuilder(aClass);
+
+ final String oldTypeText = typeElement.getText();
+ final String varName = "param";
+ templateBuilder.replaceElement(typeElement, varName, new TypeExpression(project, new PsiType[]{typeElement.getType()}), true);
+
+ final Template template = templateBuilder.buildInlineTemplate();
+ TemplateManager.getInstance(project).startTemplate(editor, template, false, null, new TemplateEditingAdapter() {
+ private String myNewType;
+
+ @Override
+ public void beforeTemplateFinished(TemplateState state, Template template) {
+ final TextResult value = state.getVariableValue(varName);
+ myNewType = value != null ? value.getText() : "";
+ final int segmentsCount = state.getSegmentsCount();
+ final Document document = state.getEditor().getDocument();
+ for (int i = 0; i < segmentsCount; i++) {
+ final TextRange segmentRange = state.getSegmentRange(i);
+ document.replaceString(segmentRange.getStartOffset(), segmentRange.getEndOffset(), oldTypeText);
+ }
+ }
+
+ @Override
+ public void templateFinished(Template template, boolean brokenOff) {
+ if (!brokenOff) {
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
+ try {
+ final PsiType targetParam = elementFactory.createTypeFromText(myNewType, aClass);
+ final TypeMigrationRules myRules = new TypeMigrationRules(((PsiAnonymousClass)aClass).getBaseClassType());
+ final PsiSubstitutor substitutor = result.getSubstitutor().put(typeParameter, targetParam);
+ final PsiType targetClassType = elementFactory.createType(baseClass, substitutor);
+ myRules.setMigrationRootType(targetClassType);
+ myRules.setBoundScope(new LocalSearchScope(aClass));
+ new TypeMigrationProcessor(project, ((PsiAnonymousClass)aClass).getBaseClassReference().getParameterList(), myRules).run();
+ }
+ catch (IncorrectOperationException e) {
+ HintManager.getInstance().showErrorHint(editor, "Incorrect type");
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
new file mode 100644
index 000000000000..d794d59f9943
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToAtomicIntention.java
@@ -0,0 +1,218 @@
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.impl.AllowedApiFilterExtension;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
+import com.intellij.refactoring.typeMigration.rules.AtomicConversionRule;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Query;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.*;
+
+import static com.intellij.psi.util.TypeConversionUtil.isBinaryOperatorApplicable;
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+/**
+ * @author anna
+ * @since 26-Aug-2009
+ */
+public class ConvertFieldToAtomicIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
+ private static final Logger LOG = Logger.getInstance("#" + ConvertFieldToAtomicIntention.class.getName());
+
+ private final Map<PsiType, String> myFromToMap = ContainerUtil.newHashMap();
+ {
+ myFromToMap.put(PsiType.INT, AtomicInteger.class.getName());
+ myFromToMap.put(PsiType.LONG, AtomicLong.class.getName());
+ myFromToMap.put(PsiType.BOOLEAN, AtomicBoolean.class.getName());
+ myFromToMap.put(PsiType.INT.createArrayType(), AtomicIntegerArray.class.getName());
+ myFromToMap.put(PsiType.LONG.createArrayType(), AtomicLongArray.class.getName());
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return "Convert to atomic";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ PsiVariable psiVariable = getVariable(element);
+ if (psiVariable == null || psiVariable instanceof PsiResourceVariable) return false;
+ if (psiVariable.getLanguage() != JavaLanguage.INSTANCE) return false;
+ if (psiVariable.getTypeElement() == null) return false;
+ if (!PsiUtil.isLanguageLevel5OrHigher(psiVariable)) return false;
+ final PsiType psiType = psiVariable.getType();
+ final PsiClass psiTypeClass = PsiUtil.resolveClassInType(psiType);
+ if (psiTypeClass != null) {
+ final String qualifiedName = psiTypeClass.getQualifiedName();
+ if (qualifiedName != null) { //is already atomic
+ if (myFromToMap.values().contains(qualifiedName) ||
+ qualifiedName.equals(AtomicReference.class.getName()) ||
+ qualifiedName.equals(AtomicReferenceArray.class.getName())) {
+ return false;
+ }
+ }
+ }
+ else if (!myFromToMap.containsKey(psiType)) {
+ return false;
+ }
+ return AllowedApiFilterExtension.isClassAllowed(AtomicReference.class.getName(), element);
+ }
+
+ private static PsiVariable getVariable(PsiElement element) {
+ if (element instanceof PsiIdentifier) {
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiLocalVariable || parent instanceof PsiField) {
+ return (PsiVariable)parent;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+ final PsiVariable psiVariable = getVariable(element);
+ LOG.assertTrue(psiVariable != null);
+
+ final Query<PsiReference> refs = ReferencesSearch.search(psiVariable);
+
+ final Set<PsiElement> elements = new HashSet<PsiElement>();
+ elements.add(element);
+ for (PsiReference reference : refs) {
+ elements.add(reference.getElement());
+ }
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) return;
+
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final PsiType fromType = psiVariable.getType();
+ PsiClassType toType;
+ final String atomicQualifiedName = myFromToMap.get(fromType);
+ if (atomicQualifiedName != null) {
+ final PsiClass atomicClass = psiFacade.findClass(atomicQualifiedName, GlobalSearchScope.allScope(project));
+ if (atomicClass == null) {//show warning
+ return;
+ }
+ toType = factory.createType(atomicClass);
+ }
+ else if (fromType instanceof PsiArrayType) {
+ final PsiClass atomicReferenceArrayClass =
+ psiFacade.findClass(AtomicReferenceArray.class.getName(), GlobalSearchScope.allScope(project));
+ if (atomicReferenceArrayClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = atomicReferenceArrayClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType componentType = ((PsiArrayType)fromType).getComponentType();
+ if (componentType instanceof PsiPrimitiveType) componentType = ((PsiPrimitiveType)componentType).getBoxedType(element);
+ substitutor.put(typeParameters[0], componentType);
+ }
+ toType = factory.createType(atomicReferenceArrayClass, factory.createSubstitutor(substitutor));
+ }
+ else {
+ final PsiClass atomicReferenceClass = psiFacade.findClass(AtomicReference.class.getName(), GlobalSearchScope.allScope(project));
+ if (atomicReferenceClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = atomicReferenceClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType type = fromType;
+ if (type instanceof PsiPrimitiveType) type = ((PsiPrimitiveType)fromType).getBoxedType(element);
+ substitutor.put(typeParameters[0], type);
+ }
+ toType = factory.createType(atomicReferenceClass, factory.createSubstitutor(substitutor));
+ }
+
+ try {
+ for (PsiReference reference : refs) {
+ PsiElement psiElement = reference.getElement();
+ if (psiElement instanceof PsiExpression) {
+ final PsiElement parent = psiElement.getParent();
+ if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
+ psiElement = parent;
+ }
+ if (psiElement instanceof PsiBinaryExpression) {
+ PsiBinaryExpression binary = (PsiBinaryExpression)psiElement;
+ if (isBinaryOperatorApplicable(binary.getOperationTokenType(), binary.getLOperand(), binary.getROperand(), true)) {
+ continue;
+ }
+ }
+ else if (psiElement instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignment = (PsiAssignmentExpression)psiElement;
+ final IElementType opSign = TypeConversionUtil.convertEQtoOperation(assignment.getOperationTokenType());
+ if (opSign != null && isBinaryOperatorApplicable(opSign, assignment.getLExpression(), assignment.getRExpression(), true)) {
+ continue;
+ }
+ }
+ final TypeConversionDescriptor directConversion = AtomicConversionRule.findDirectConversion(psiElement, toType, fromType);
+ if (directConversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression((PsiExpression)psiElement, project, directConversion);
+ }
+ }
+ }
+
+ final PsiExpression initializer = psiVariable.getInitializer();
+ if (initializer != null) {
+ final TypeConversionDescriptor directConversion = AtomicConversionRule.wrapWithNewExpression(toType, fromType, null, element);
+ if (directConversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression(initializer, project, directConversion);
+ }
+ }
+ else if (!assertNotNull(psiVariable.getModifierList()).hasModifierProperty(PsiModifier.FINAL)) {
+ final PsiExpression newInitializer = factory.createExpressionFromText("new " + toType.getCanonicalText() + "()", psiVariable);
+ if (psiVariable instanceof PsiLocalVariable) {
+ ((PsiLocalVariable)psiVariable).setInitializer(newInitializer);
+ }
+ else if (psiVariable instanceof PsiField) {
+ ((PsiField)psiVariable).setInitializer(newInitializer);
+ }
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiVariable.getInitializer());
+ }
+
+ PsiElement replaced = assertNotNull(psiVariable.getTypeElement()).replace(factory.createTypeElement(toType));
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
+
+ if (psiVariable instanceof PsiField || CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS) {
+ final PsiModifierList modifierList = assertNotNull(psiVariable.getModifierList());
+ modifierList.setModifierProperty(PsiModifier.FINAL, true);
+ modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
+ }
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
new file mode 100644
index 000000000000..e01aaadae7d8
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/intentions/ConvertFieldToThreadLocalIntention.java
@@ -0,0 +1,145 @@
+/*
+ * User: anna
+ * Date: 26-Aug-2009
+ */
+package com.intellij.refactoring.typeMigration.intentions;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.AllowedApiFilterExtension;
+import com.intellij.psi.impl.PsiDiamondTypeUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import com.intellij.refactoring.typeMigration.TypeMigrationReplacementUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.Query;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.intellij.util.ObjectUtils.assertNotNull;
+
+public class ConvertFieldToThreadLocalIntention extends PsiElementBaseIntentionAction implements LowPriorityAction {
+ private static final Logger LOG = Logger.getInstance("#" + ConvertFieldToThreadLocalIntention.class.getName());
+
+ @NotNull
+ @Override
+ public String getText() {
+ return "Convert to ThreadLocal";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getText();
+ }
+
+ @Override
+ public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
+ if (!(element instanceof PsiIdentifier)) return false;
+ final PsiField psiField = PsiTreeUtil.getParentOfType(element, PsiField.class);
+ if (psiField == null) return false;
+ if (psiField.getLanguage() != JavaLanguage.INSTANCE) return false;
+ if (psiField.getTypeElement() == null) return false;
+ final PsiType fieldType = psiField.getType();
+ final PsiClass fieldTypeClass = PsiUtil.resolveClassInType(fieldType);
+ if (fieldType instanceof PsiPrimitiveType || fieldType instanceof PsiArrayType) return true;
+ return fieldTypeClass != null && !Comparing.strEqual(fieldTypeClass.getQualifiedName(), ThreadLocal.class.getName())
+ && AllowedApiFilterExtension.isClassAllowed(ThreadLocal.class.getName(), element);
+ }
+
+ @Override
+ public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
+ final PsiField psiField = PsiTreeUtil.getParentOfType(element, PsiField.class);
+ LOG.assertTrue(psiField != null);
+ final Query<PsiReference> refs = ReferencesSearch.search(psiField);
+
+ final Set<PsiElement> elements = new HashSet<PsiElement>();
+ elements.add(element);
+ for (PsiReference reference : refs) {
+ elements.add(reference.getElement());
+ }
+ if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) return;
+
+ final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final PsiType fromType = psiField.getType();
+
+ final PsiClass threadLocalClass = psiFacade.findClass(ThreadLocal.class.getName(), GlobalSearchScope.allScope(project));
+ if (threadLocalClass == null) {//show warning
+ return;
+ }
+ final Map<PsiTypeParameter, PsiType> substitutor = ContainerUtil.newHashMap();
+ final PsiTypeParameter[] typeParameters = threadLocalClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ PsiType type = fromType;
+ if (fromType instanceof PsiPrimitiveType) type = ((PsiPrimitiveType)fromType).getBoxedType(element);
+ substitutor.put(typeParameters[0], type);
+ }
+ final PsiClassType toType = factory.createType(threadLocalClass, factory.createSubstitutor(substitutor));
+
+ try {
+ final TypeMigrationRules rules = new TypeMigrationRules(fromType);
+ rules.setMigrationRootType(toType);
+ rules.setBoundScope(GlobalSearchScope.fileScope(element.getContainingFile()));
+ final TypeMigrationLabeler labeler = new TypeMigrationLabeler(rules);
+ labeler.getMigratedUsages(false, psiField);
+ for (PsiReference reference : refs) {
+ PsiElement psiElement = reference.getElement();
+ if (psiElement instanceof PsiExpression) {
+ final PsiElement parent = psiElement.getParent();
+ if (parent instanceof PsiExpression && !(parent instanceof PsiReferenceExpression || parent instanceof PsiPolyadicExpression)) {
+ psiElement = parent;
+ }
+ final TypeConversionDescriptor conversion = ThreadLocalConversionRule.findDirectConversion(psiElement, toType, fromType, labeler);
+ if (conversion != null) {
+ TypeMigrationReplacementUtil.replaceExpression((PsiExpression)psiElement, project, conversion);
+ }
+ }
+ }
+
+ final PsiExpression initializer = psiField.getInitializer();
+ if (initializer != null) {
+ final TypeConversionDescriptor conversion = ThreadLocalConversionRule.wrapWithNewExpression(toType, fromType, initializer);
+ TypeMigrationReplacementUtil.replaceExpression(initializer, project, conversion);
+ CodeStyleManager.getInstance(project).reformat(psiField);
+ }
+ else if (!assertNotNull(psiField.getModifierList()).hasModifierProperty(PsiModifier.FINAL)) {
+ final String text = "new " + PsiDiamondTypeUtil.getCollapsedType(toType, psiField) + "()";
+ final PsiExpression newInitializer = factory.createExpressionFromText(text, psiField);
+ psiField.setInitializer(newInitializer);
+ }
+
+ assertNotNull(psiField.getTypeElement()).replace(factory.createTypeElement(toType));
+
+ final PsiModifierList modifierList = assertNotNull(psiField.getModifierList());
+ modifierList.setModifierProperty(PsiModifier.FINAL, true);
+ modifierList.setModifierProperty(PsiModifier.VOLATILE, false);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return true;
+ }
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/AtomicConversionRule.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/AtomicConversionRule.java
new file mode 100644
index 000000000000..a4ec46e44838
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/AtomicConversionRule.java
@@ -0,0 +1,420 @@
+/*
+ * User: anna
+ * Date: 18-Aug-2009
+ */
+package com.intellij.refactoring.typeMigration.rules;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiDiamondTypeUtil;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.concurrent.atomic.*;
+
+public class AtomicConversionRule extends TypeConversionRule {
+ private static final Logger LOG = Logger.getInstance("#" + AtomicConversionRule.class.getName());
+
+
+ @Override
+ public TypeConversionDescriptorBase findConversion(PsiType from,
+ PsiType to,
+ PsiMember member,
+ PsiExpression context,
+ TypeMigrationLabeler labeler) {
+ if (to instanceof PsiClassType && isAtomicTypeMigration(from, (PsiClassType)to, context)) {
+ return findDirectConversion(context, to, from);
+ }
+ else if (from instanceof PsiClassType && isAtomicTypeMigration(to, (PsiClassType)from, context)) {
+ return findReverseConversion(context);
+ }
+ return null;
+ }
+
+ private static boolean isAtomicTypeMigration(PsiType from, PsiClassType to, PsiExpression context) {
+ if (from == PsiType.INT && to.getCanonicalText().equals(AtomicInteger.class.getName())) {
+ return true;
+ }
+ if (from.equals(PsiType.INT.createArrayType()) && to.getCanonicalText().equals(AtomicIntegerArray.class.getName())) {
+ return true;
+ }
+ if (from == PsiType.LONG && to.getCanonicalText().equals(AtomicLong.class.getName())) {
+ return true;
+ }
+ if (from.equals(PsiType.LONG.createArrayType()) && to.getCanonicalText().equals(AtomicLongArray.class.getName())) {
+ return true;
+ }
+ if (from == PsiType.BOOLEAN && to.getCanonicalText().equals(AtomicBoolean.class.getName())) {
+ return true;
+ }
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to);
+ final PsiClass atomicClass = resolveResult.getElement();
+
+ if (atomicClass != null) {
+ final String typeQualifiedName = atomicClass.getQualifiedName();
+ if (!Comparing.strEqual(typeQualifiedName, AtomicReference.class.getName()) &&
+ !Comparing.strEqual(typeQualifiedName, AtomicReferenceArray.class.getName())) {
+ return false;
+ }
+ final PsiTypeParameter[] typeParameters = atomicClass.getTypeParameters();
+ if (typeParameters.length != 1) return false;
+ final PsiType toTypeParameterValue = resolveResult.getSubstitutor().substitute(typeParameters[0]);
+ if (toTypeParameterValue != null) {
+ if (from.getDeepComponentType() instanceof PsiPrimitiveType) {
+ final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(toTypeParameterValue);
+ if (unboxedInitialType != null) {
+ return TypeConversionUtil.areTypesConvertible(from.getDeepComponentType(), unboxedInitialType);
+ }
+ }
+ else {
+ return TypeConversionUtil.isAssignable(from.getDeepComponentType(), PsiUtil.captureToplevelWildcards(toTypeParameterValue, context));
+ }
+ }
+ }
+ return false;
+ }
+
+ @Nullable
+ public static TypeConversionDescriptor findDirectConversion(PsiElement context, PsiType to, PsiType from) {
+ final PsiClass toTypeClass = PsiUtil.resolveClassInType(to);
+ LOG.assertTrue(toTypeClass != null);
+ final String qualifiedName = toTypeClass.getQualifiedName();
+ if (qualifiedName != null) {
+ if (qualifiedName.equals(AtomicInteger.class.getName()) || qualifiedName.equals(AtomicLong.class.getName())) {
+
+ if (context instanceof PsiPostfixExpression) {
+ final IElementType operationSign = ((PsiPostfixExpression)context).getOperationTokenType();
+ if (operationSign == JavaTokenType.MINUSMINUS) {
+ return new TypeConversionDescriptor("$qualifier$--", "$qualifier$.getAndDecrement()");
+ }
+ if (operationSign == JavaTokenType.PLUSPLUS) {
+ return new TypeConversionDescriptor("$qualifier$++", "$qualifier$.getAndIncrement()");
+ }
+
+ }
+ else if (context instanceof PsiPrefixExpression) {
+ final IElementType operationSign = ((PsiPrefixExpression)context).getOperationTokenType();
+ if (operationSign == JavaTokenType.MINUSMINUS) {
+ return new TypeConversionDescriptor("--$qualifier$", "$qualifier$.decrementAndGet()");
+ }
+ if (operationSign == JavaTokenType.PLUSPLUS) {
+ return new TypeConversionDescriptor("++$qualifier$", "$qualifier$.incrementAndGet()");
+ }
+
+ }
+ else if (context instanceof PsiAssignmentExpression) {
+ final PsiJavaToken signToken = ((PsiAssignmentExpression)context).getOperationSign();
+ final IElementType operationSign = signToken.getTokenType();
+ final String sign = signToken.getText();
+ if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
+ return new TypeConversionDescriptor("$qualifier$ " + sign + " $val$", "$qualifier$.getAndAdd(" +
+ (operationSign == JavaTokenType.MINUSEQ ? "-" : "") +
+ "($val$))");
+ }
+ }
+ }
+ else if (qualifiedName.equals(AtomicIntegerArray.class.getName()) || qualifiedName.equals(AtomicLongArray.class.getName())) {
+ PsiElement parentExpression = context.getParent();
+ if (parentExpression instanceof PsiPostfixExpression) {
+ final IElementType operationSign = ((PsiPostfixExpression)parentExpression).getOperationTokenType();
+ if (operationSign == JavaTokenType.MINUSMINUS) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$]--", "$qualifier$.getAndDecrement($idx$)",
+ (PsiExpression)parentExpression);
+ }
+ if (operationSign == JavaTokenType.PLUSPLUS) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$]++", "$qualifier$.getAndIncrement($idx$)",
+ (PsiExpression)parentExpression);
+ }
+
+ }
+ else if (parentExpression instanceof PsiPrefixExpression) {
+ final IElementType operationSign = ((PsiPrefixExpression)parentExpression).getOperationTokenType();
+ if (operationSign == JavaTokenType.MINUSMINUS) {
+ return new TypeConversionDescriptor("--$qualifier$[$idx$]", "$qualifier$.decrementAndGet($idx$)",
+ (PsiExpression)parentExpression);
+ }
+ if (operationSign == JavaTokenType.PLUSPLUS) {
+ return new TypeConversionDescriptor("++$qualifier$[$idx$]", "$qualifier$.incrementAndGet($idx$)",
+ (PsiExpression)parentExpression);
+ }
+
+ }
+ else if (parentExpression instanceof PsiAssignmentExpression) {
+ final PsiJavaToken signToken = ((PsiAssignmentExpression)parentExpression).getOperationSign();
+ final IElementType operationSign = signToken.getTokenType();
+ final String sign = signToken.getText();
+ if (operationSign == JavaTokenType.PLUSEQ || operationSign == JavaTokenType.MINUSEQ) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$] " + sign + " $val$", "$qualifier$.getAndAdd($idx$, " +
+ (operationSign == JavaTokenType.MINUSEQ
+ ? "-"
+ : "") +
+ "($val$))", (PsiExpression)parentExpression);
+ }
+ }
+ }
+ }
+ return from instanceof PsiArrayType
+ ? findDirectConversionForAtomicReferenceArray(context, to, from)
+ : findDirectConversionForAtomicReference(context, to, from);
+ }
+
+ @Nullable
+ private static TypeConversionDescriptor findDirectConversionForAtomicReference(PsiElement context, PsiType to, PsiType from) {
+ final PsiElement parent = context.getParent();
+ if (parent instanceof PsiAssignmentExpression) {
+ final IElementType operationSign = ((PsiAssignmentExpression)parent).getOperationTokenType();
+ if (operationSign == JavaTokenType.EQ) {
+ return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)", (PsiAssignmentExpression)parent);
+ }
+ }
+
+ if (context instanceof PsiReferenceExpression) {
+ final PsiExpression qualifierExpression = ((PsiReferenceExpression)context).getQualifierExpression();
+ final PsiExpression expression = context.getParent() instanceof PsiMethodCallExpression && qualifierExpression != null
+ ? qualifierExpression
+ : (PsiExpression)context;
+ return new TypeConversionDescriptor("$qualifier$", "$qualifier$.get()", expression);
+ }
+ else if (context instanceof PsiAssignmentExpression) {
+ final PsiJavaToken signToken = ((PsiAssignmentExpression)context).getOperationSign();
+ final IElementType operationSign = signToken.getTokenType();
+ final String sign = signToken.getText();
+ if (parent instanceof PsiExpressionStatement) {
+ if (operationSign == JavaTokenType.EQ) {
+ final PsiExpression lExpression = ((PsiAssignmentExpression)context).getLExpression();
+ if (lExpression instanceof PsiReferenceExpression) {
+ final PsiElement element = ((PsiReferenceExpression)lExpression).resolve();
+ if (element instanceof PsiVariable && ((PsiVariable)element).hasModifierProperty(PsiModifier.FINAL)) {
+ return wrapWithNewExpression(to, from, ((PsiAssignmentExpression)context).getRExpression(), element);
+ }
+ }
+ return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set($val$)");
+ }
+ else {
+ return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" +
+ getBoxedWrapper(from, to, "$qualifier$.get() " +
+ sign.charAt(0) +
+ " $val$") +
+ ")");
+ }
+ } //else should be a conflict
+ }
+ else if (context instanceof PsiPostfixExpression) {
+ final String sign = ((PsiPostfixExpression)context).getOperationSign().getText();
+ return new TypeConversionDescriptor("$qualifier$" + sign, "$qualifier$.getAndSet(" +
+ getBoxedWrapper(from, to, "$qualifier$.get() " + sign.charAt(0) + " 1") +
+ ")");
+ }
+ else if (context instanceof PsiPrefixExpression) {
+ final PsiJavaToken operationSign = ((PsiPrefixExpression)context).getOperationSign();
+ if (operationSign.getTokenType() == JavaTokenType.EXCL) {
+ return new TypeConversionDescriptor("!$qualifier$", "!$qualifier$.get()");
+ }
+ final String sign = operationSign.getText();
+ return new TypeConversionDescriptor(sign + "$qualifier$", "$qualifier$.set(" + //todo reject?
+ getBoxedWrapper(from, to, "$qualifier$.get() " + sign.charAt(0) + " 1") +
+ ")");
+ } else if (context instanceof PsiBinaryExpression) {
+ final String sign = ((PsiBinaryExpression)context).getOperationSign().getText();
+ return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.get() " + sign + " $val$");
+ }
+
+ if (parent instanceof PsiVariable) {
+ return wrapWithNewExpression(to, from, null, parent);
+ }
+ return null;
+ }
+
+ public static TypeConversionDescriptor wrapWithNewExpression(PsiType to, PsiType from, @Nullable PsiExpression expression, PsiElement context) {
+ final String typeText = PsiDiamondTypeUtil.getCollapsedType(to, context);
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to);
+ final PsiClass atomicClass = resolveResult.getElement();
+ LOG.assertTrue(atomicClass != null);
+ final PsiTypeParameter[] typeParameters = atomicClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ final PsiType initial = resolveResult.getSubstitutor().substitute(typeParameters[0]);
+ final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(initial);
+ if (unboxedInitialType != null) {
+ LOG.assertTrue(initial != null);
+ if (from instanceof PsiPrimitiveType) {
+ final PsiClassType boxedFromType = ((PsiPrimitiveType)from).getBoxedType(atomicClass);
+ LOG.assertTrue(boxedFromType != null);
+ if (!TypeConversionUtil.isAssignable(initial, boxedFromType)) {
+ return new TypeConversionDescriptor("$val$", "new " + typeText + "((" + unboxedInitialType.getCanonicalText() + ")$val$)", expression);
+ }
+ }
+ }
+ }
+ return new TypeConversionDescriptor("$val$", "new " + typeText + "($val$)", expression);
+ }
+
+ @Nullable
+ private static TypeConversionDescriptor findDirectConversionForAtomicReferenceArray(PsiElement context, PsiType to, PsiType from) {
+ LOG.assertTrue(from instanceof PsiArrayType);
+ from = ((PsiArrayType)from).getComponentType();
+ final PsiElement parent = context.getParent();
+ final PsiElement parentParent = parent.getParent();
+
+ if (parent instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+ final IElementType operationSign = assignmentExpression.getOperationTokenType();
+ final String sign = assignmentExpression.getOperationSign().getText();
+ if (context instanceof PsiArrayAccessExpression) {
+ if (parentParent instanceof PsiExpressionStatement) {
+ if (assignmentExpression.getLExpression() == context) {
+ if (operationSign == JavaTokenType.EQ) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$] = $val$", "$qualifier$.set($idx$, $val$)", assignmentExpression);
+ }
+ else {
+ return new TypeConversionDescriptor("$qualifier$[$idx$]" + sign + "$val$",
+ "$qualifier$.set($idx$, " + getBoxedWrapper(from, to, "$qualifier$.get($idx$) " + sign.charAt(0) + " $val$") + ")",
+ assignmentExpression);
+ }
+ }
+ } //else should be a conflict
+ }
+ else {
+ final PsiExpression rExpression = assignmentExpression.getRExpression();
+ if (rExpression == context && operationSign == JavaTokenType.EQ) { //array = new T[l];
+ return wrapWithNewExpression(to, from, rExpression, context);
+ }
+ }
+ } else if (parent instanceof PsiVariable) {
+ if (((PsiVariable)parent).getInitializer() == context) {
+ return wrapWithNewExpression(to, from, (PsiExpression)context, context);
+ }
+ }
+
+ if (parentParent instanceof PsiExpressionStatement) {
+ if (parent instanceof PsiPostfixExpression) {
+ final String sign = ((PsiPostfixExpression)parent).getOperationSign().getText();
+ return new TypeConversionDescriptor("$qualifier$[$idx$]" + sign, "$qualifier$.getAndSet($idx$, " +
+ getBoxedWrapper(from, to,
+ "$qualifier$.get($idx$) " + sign.charAt(0) + " 1") +
+ ")", (PsiExpression)parent);
+ }
+ else if (parent instanceof PsiPrefixExpression) {
+ final String sign = ((PsiPrefixExpression)parent).getOperationSign().getText();
+ return new TypeConversionDescriptor(sign + "$qualifier$[$idx$]", "$qualifier$.set($idx$, " +
+ getBoxedWrapper(from, to,
+ "$qualifier$.get($idx$) " + sign.charAt(0) + " 1") +
+ ")", (PsiExpression)parent);
+ }
+ else if (parent instanceof PsiBinaryExpression) {
+ final String sign = ((PsiBinaryExpression)parent).getOperationSign().getText();
+ return new TypeConversionDescriptor("$qualifier$[$idx$]" + sign + "$val$", "$qualifier$.set($idx$, " +
+ getBoxedWrapper(from, to, "$qualifier$.get($idx$) " +
+ sign +
+ " $val$)") +
+ ")", (PsiExpression)parent);
+ }
+ }
+
+ if (context instanceof PsiArrayAccessExpression) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$]", "$qualifier$.get($idx$)", (PsiExpression)context);
+ }
+ return null;
+ }
+
+ private static String getBoxedWrapper(final PsiType from, final PsiType to, @NotNull String arg) {
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to);
+ final PsiClass atomicClass = resolveResult.getElement();
+ LOG.assertTrue(atomicClass != null);
+ final PsiTypeParameter[] typeParameters = atomicClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
+ LOG.assertTrue(substitutor.isValid());
+ final PsiType initial = substitutor.substitute(typeParameters[0]);
+ final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(initial);
+ if (unboxedInitialType != null) {
+ LOG.assertTrue(initial != null);
+ if (from instanceof PsiPrimitiveType) {
+ final PsiClassType boxedFromType = ((PsiPrimitiveType)from).getBoxedType(atomicClass);
+ LOG.assertTrue(boxedFromType != null);
+ return "new " + initial.getPresentableText() + "((" + unboxedInitialType.getCanonicalText() + ")(" + arg + "))";
+ }
+ }
+ }
+ return arg;
+ }
+
+ @Nullable
+ private static TypeConversionDescriptor findReverseConversion(PsiElement context) {
+ if (context instanceof PsiReferenceExpression) {
+ if (context.getParent() instanceof PsiMethodCallExpression) {
+ return findReverseConversionForMethodCall(context);
+ }
+ }
+ else if (context instanceof PsiNewExpression) {
+ return new TypeConversionDescriptor("new $type$($qualifier$)", "$qualifier$");
+ }
+ else if (context instanceof PsiMethodCallExpression) {
+ return findReverseConversionForMethodCall(((PsiMethodCallExpression)context).getMethodExpression());
+ }
+ return null;
+ }
+
+ @Nullable
+ private static TypeConversionDescriptor findReverseConversionForMethodCall(PsiElement context) {
+ final PsiElement resolved = ((PsiReferenceExpression)context).resolve();
+ if (resolved instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)resolved;
+ final int parametersCount = method.getParameterList().getParametersCount();
+ final String resolvedName = method.getName();
+ if (Comparing.strEqual(resolvedName, "get")) {
+ return parametersCount == 0 ?
+ new TypeConversionDescriptor("$qualifier$.get()", "$qualifier$") :
+ new TypeConversionDescriptor("$qualifier$.get($idx$)", "$qualifier$[$idx$]");
+ }
+ else if (Comparing.strEqual(resolvedName, "set")) {
+ return parametersCount == 1 ?
+ new TypeConversionDescriptor("$qualifier$.set($val$)", "$qualifier$ = $val$") :
+ new TypeConversionDescriptor("$qualifier$.set($idx$, $val$)", "$qualifier$[$idx$] = $val$");
+ }
+ else if (Comparing.strEqual(resolvedName, "addAndGet")) {
+ return parametersCount == 1 ?
+ new TypeConversionDescriptor("$qualifier$.addAndGet($delta$)", "$qualifier$ + $delta$") :
+ new TypeConversionDescriptor("$qualifier$.addAndGet($idx$, $delta$)", "$qualifier$[$idx$] + $delta$");
+ }
+ else if (Comparing.strEqual(resolvedName, "incrementAndGet")) {
+ return parametersCount == 0 ?
+ new TypeConversionDescriptor("$qualifier$.incrementAndGet()", "++$qualifier$") :
+ new TypeConversionDescriptor("$qualifier$.incrementAndGet($idx$)", "++$qualifier$[$idx$]");
+ }
+ else if (Comparing.strEqual(resolvedName, "decrementAndGet")) {
+ return parametersCount == 0 ?
+ new TypeConversionDescriptor("$qualifier$.decrementAndGet()", "--$qualifier$") :
+ new TypeConversionDescriptor("$qualifier$.decrementAndGet($idx$)", "--$qualifier$[$idx$]");
+ }
+ else if (Comparing.strEqual(resolvedName, "getAndIncrement")) {
+ return parametersCount == 0 ?
+ new TypeConversionDescriptor("$qualifier$.getAndIncrement()", "$qualifier$++") :
+ new TypeConversionDescriptor("$qualifier$.getAndIncrement($idx$)", "$qualifier$[$idx$]++");
+ }
+ else if (Comparing.strEqual(resolvedName, "getAndDecrement")) {
+ return parametersCount == 0 ?
+ new TypeConversionDescriptor("$qualifier$.getAndDecrement()", "$qualifier$--") :
+ new TypeConversionDescriptor("$qualifier$.getAndDecrement($idx$)", "$qualifier$[$idx$]--");
+ }
+ else if (Comparing.strEqual(resolvedName, "getAndAdd")) {
+ return parametersCount == 1?
+ new TypeConversionDescriptor("$qualifier$.getAndAdd($val$)", "$qualifier$ += $val$") :
+ new TypeConversionDescriptor("$qualifier$.getAndAdd($idx$, $val$)", "$qualifier$[$idx$] += $val$");
+ }
+ else if (Comparing.strEqual(resolvedName, "getAndSet")) {
+ return parametersCount == 1 ?
+ new TypeConversionDescriptor("$qualifier$.getAndSet($val$)", "$qualifier$ = $val$") :
+ new TypeConversionDescriptor("$qualifier$.getAndSet($idx$, $val$)", "$qualifier$[$idx$] = $val$");
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/BoxingTypeConversionRule.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/BoxingTypeConversionRule.java
new file mode 100644
index 000000000000..4353bf602e04
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/BoxingTypeConversionRule.java
@@ -0,0 +1,36 @@
+/*
+ * User: anna
+ * Date: 08-Aug-2008
+ */
+package com.intellij.refactoring.typeMigration.rules;
+
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+
+public class BoxingTypeConversionRule extends TypeConversionRule {
+
+ public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context,
+ final TypeMigrationLabeler labeler) {
+ if (to instanceof PsiClassType && from instanceof PsiPrimitiveType) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(context)) {
+ final String boxedTypeName = ((PsiPrimitiveType)from).getBoxedTypeName();
+ if (Comparing.strEqual(boxedTypeName, to.getCanonicalText())) {
+ return new TypeConversionDescriptor("$qualifier$", boxedTypeName + ".valueOf($qualifier$)");
+ }
+ }
+ }
+ else if (from instanceof PsiClassType && to instanceof PsiPrimitiveType) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(context)) {
+ final String boxedTypeName = ((PsiPrimitiveType)to).getBoxedTypeName();
+ if (Comparing.strEqual(boxedTypeName, from.getCanonicalText())) {
+ return new TypeConversionDescriptor("$qualifier$", "($qualifier$)." + to.getCanonicalText() + "Value()");
+ }
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ElementToArrayConversionRule.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ElementToArrayConversionRule.java
new file mode 100644
index 000000000000..0d25df778bcc
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ElementToArrayConversionRule.java
@@ -0,0 +1,36 @@
+/*
+ * User: anna
+ * Date: 25-Aug-2008
+ */
+package com.intellij.refactoring.typeMigration.rules;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+
+public class ElementToArrayConversionRule extends TypeConversionRule{
+ public TypeConversionDescriptorBase findConversion(final PsiType from, final PsiType to, final PsiMember member, final PsiExpression context,
+ final TypeMigrationLabeler labeler) {
+ if (member == null && to instanceof PsiArrayType && TypeConversionUtil.isAssignable(((PsiArrayType)to).getComponentType(), from)) {
+ TypeConversionDescriptor wrapDescription =
+ new TypeConversionDescriptor("$qualifier$", "new " + from.getCanonicalText() + "[]{$qualifier$}", context);
+ if (((PsiArrayType)to).getComponentType() instanceof PsiClassType && from instanceof PsiPrimitiveType) {
+ final String boxedTypeName = ((PsiPrimitiveType)from).getBoxedTypeName();
+ final String normalizedArrayInitializer =
+ PsiUtil.isLanguageLevel5OrHigher(context) ? "$qualifier$" : boxedTypeName + ".valueOf($qualifier$)";
+ wrapDescription = new TypeConversionDescriptor("$qualifier$", "new " + boxedTypeName + "[]{" + normalizedArrayInitializer + "}", context);
+ }
+ final PsiElement parent = context.getParent();
+ if ((context instanceof PsiLiteralExpression || context instanceof PsiReferenceExpression) && parent instanceof PsiStatement) {
+ return wrapDescription;
+ }
+ if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getRExpression() == context) {
+ return wrapDescription;
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ListArrayConversionRule.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ListArrayConversionRule.java
new file mode 100644
index 000000000000..0aa639ba28cb
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ListArrayConversionRule.java
@@ -0,0 +1,177 @@
+/*
+ * User: anna
+ * Date: 08-Aug-2008
+ */
+package com.intellij.refactoring.typeMigration.rules;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class ListArrayConversionRule extends TypeConversionRule {
+ public TypeConversionDescriptorBase findConversion(final PsiType from,
+ final PsiType to,
+ PsiMember member,
+ final PsiExpression context,
+ final TypeMigrationLabeler labeler) {
+ PsiExpression expression = context;
+ PsiClassType classType = from instanceof PsiClassType ? (PsiClassType)from : to instanceof PsiClassType ? (PsiClassType)to : null;
+ PsiArrayType arrayType = from instanceof PsiArrayType ? (PsiArrayType)from : to instanceof PsiArrayType ? (PsiArrayType)to : null;
+
+ if (classType == null || arrayType == null) return null;
+ final PsiType collectionType = evaluateCollectionsType(classType, expression);
+ if (collectionType == null) return null;
+
+ if (member == null) {
+ final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(context, PsiMethodCallExpression.class);
+ if (callExpression != null) {
+ member = callExpression.resolveMethod();
+ expression = callExpression;
+ }
+ }
+ if (member instanceof PsiMethod) {
+ TypeConversionDescriptor descriptor = changeCollectionCallsToArray((PsiMethod)member, context, collectionType, arrayType);
+ if (descriptor != null) return descriptor;
+
+ @NonNls final String memberName = member.getName();
+ assert memberName != null;
+ if (memberName.equals("sort")) {
+ if (((PsiMethod)member).getParameterList().getParametersCount() == 1) {
+ descriptor = new TypeConversionDescriptor("Arrays.sort($qualifier$)", "Collections.sort($qualifier$)", expression);
+ }
+ else {
+ descriptor =
+ new TypeConversionDescriptor("Arrays.sort($qualifier$, $expr$)", "Collections.sort($qualifier$, $expr$)", expression);
+ }
+ }
+ else if (memberName.equals("binarySearch")) {
+ if (((PsiMethod)member).getParameterList().getParametersCount() == 2) {
+ descriptor =
+ new TypeConversionDescriptor("Arrays.binarySearch($qualifier$, $key$)", "Collections.binarySearch($qualifier$, $key$)",
+ expression);
+ }
+ else {
+ descriptor = new TypeConversionDescriptor("Arrays.binarySearch($qualifier$, $key$, $comparator$)",
+ "Collections.binarySearch($qualifier$, $key$, $comparator$)", expression);
+ }
+ }
+ else if (memberName.equals("asList")) {
+ if (((PsiMethod)member).getParameterList().getParametersCount() == 1) {
+ descriptor =
+ new TypeConversionDescriptor("Arrays.asList($qualifier$)", "$qualifier$", expression);
+ }
+ }
+ else if (memberName.equals("fill")) {
+ descriptor = new TypeConversionDescriptor("Arrays.fill($qualifier$, $filler$)", "Collections.fill($qualifier$, $filler$)", expression);
+ }
+ if (descriptor != null) {
+ return from instanceof PsiClassType
+ ? new TypeConversionDescriptor(descriptor.getReplaceByString(), descriptor.getStringToReplace(), descriptor.getExpression())
+ : descriptor;
+ }
+ }
+
+ if (member instanceof PsiField && member.getName().equals("length")) {
+ return new TypeConversionDescriptor("$qualifier$.length", "$qualifier$.size()");
+ }
+
+ final PsiElement parent = context.getParent();
+ if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getLExpression() == context) {
+ if (TypeConversionUtil.isAssignable(collectionType, arrayType.getComponentType())) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$] = $expr$", "$qualifier$.set($idx$, $expr$)",
+ (PsiExpression)parent);
+ }
+ }
+ else if (context instanceof PsiArrayAccessExpression && TypeConversionUtil.isAssignable(arrayType.getComponentType(), collectionType)) {
+ return new TypeConversionDescriptor("$qualifier$[$idx$]", "$qualifier$.get($idx$)");
+ }
+
+ return null;
+ }
+
+ @Nullable
+ public static PsiType evaluateCollectionsType(PsiClassType classType, PsiExpression expression) {
+ final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(classType);
+ if (classResolveResult != null) {
+ final PsiClass psiClass = classResolveResult.getElement();
+ if (psiClass != null) {
+ final GlobalSearchScope allScope = GlobalSearchScope.allScope(psiClass.getProject());
+ final PsiClass collectionClass =
+ JavaPsiFacade.getInstance(psiClass.getProject()).findClass(CommonClassNames.JAVA_UTIL_LIST, allScope);
+ if (collectionClass != null && InheritanceUtil.isInheritorOrSelf(psiClass, collectionClass, true)) {
+ final PsiSubstitutor derivedSubstitutor = classResolveResult.getSubstitutor();
+ if (PsiUtil.isRawSubstitutor(psiClass, derivedSubstitutor)) return null;
+ final PsiSubstitutor substitutor =
+ TypeConversionUtil.getClassSubstitutor(collectionClass, psiClass, derivedSubstitutor);
+ assert substitutor != null;
+ final PsiType type = substitutor.substitute(collectionClass.getTypeParameters()[0]);
+ assert type != null;
+ return PsiImplUtil.normalizeWildcardTypeByPosition(type, expression);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Pair<PsiType, PsiType> bindTypeParameters(final PsiType from,
+ final PsiType to,
+ final PsiMethod method,
+ final PsiExpression context,
+ final TypeMigrationLabeler labeler) {
+ if (findConversion(from, to, method, context, labeler) == null) return null;
+ if (from instanceof PsiArrayType && to instanceof PsiClassType) {
+ final PsiType collectionType = evaluateCollectionsType((PsiClassType)to, context);
+ if (collectionType != null) {
+ return Pair.create(((PsiArrayType)from).getComponentType(), collectionType);
+ }
+ }
+ if (to instanceof PsiArrayType && from instanceof PsiClassType) {
+ final PsiType collectionType = evaluateCollectionsType((PsiClassType)from, context);
+ if (collectionType != null) {
+ return Pair.create(collectionType, ((PsiArrayType)to).getComponentType());
+
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static TypeConversionDescriptor changeCollectionCallsToArray(final PsiMethod method,
+ final PsiElement context,
+ PsiType collectionType,
+ PsiArrayType arrayType) {
+ @NonNls final String methodName = method.getName();
+ if (methodName.equals("toArray")) {
+ if (method.getParameterList().getParameters().length == 0) {
+ return new TypeConversionDescriptor("$qualifier$.toArray()", "$qualifier$");
+ }
+ return new TypeConversionDescriptor("$qualifier$.toArray($expr$)", "$qualifier$");
+ }
+ else if (methodName.equals("size")) {
+ return new TypeConversionDescriptor("$qualifier$.size()", "$qualifier$.length");
+ }
+ else if (methodName.equals("get")) {
+ if (TypeConversionUtil.isAssignable(collectionType, arrayType.getComponentType())) {
+ return new TypeConversionDescriptor("$qualifier$.get($i$)", "$qualifier$[$i$]", PsiTreeUtil.getParentOfType(context, PsiMethodCallExpression.class));
+ }
+ }
+ else if (methodName.equals("set")) {
+ if (TypeConversionUtil.isAssignable(arrayType.getComponentType(), collectionType)) {
+ return new TypeConversionDescriptor("$qualifier$.set($i$, $val$)", "$qualifier$[$i$] = $val$");
+ }
+ }
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ThreadLocalConversionRule.java b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ThreadLocalConversionRule.java
new file mode 100644
index 000000000000..2fb305147d02
--- /dev/null
+++ b/plugins/typeMigration/src/com/intellij/refactoring/typeMigration/rules/ThreadLocalConversionRule.java
@@ -0,0 +1,231 @@
+/*
+ * User: anna
+ * Date: 18-Aug-2009
+ */
+package com.intellij.refactoring.typeMigration.rules;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiDiamondTypeUtil;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptor;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class ThreadLocalConversionRule extends TypeConversionRule {
+ private static final Logger LOG = Logger.getInstance("#" + ThreadLocalConversionRule.class.getName());
+
+
+ @Override
+ public TypeConversionDescriptorBase findConversion(PsiType from,
+ PsiType to,
+ PsiMember member,
+ PsiExpression context,
+ TypeMigrationLabeler labeler) {
+ if (to instanceof PsiClassType && isThreadLocalTypeMigration(from, (PsiClassType)to, context)) {
+ return findDirectConversion(context, to, from, labeler);
+ }
+ return null;
+ }
+
+ private static boolean isThreadLocalTypeMigration(PsiType from, PsiClassType to, PsiExpression context) {
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to);
+ final PsiClass threadLocalClass = resolveResult.getElement();
+
+ if (threadLocalClass != null) {
+ final String typeQualifiedName = threadLocalClass.getQualifiedName();
+ if (!Comparing.strEqual(typeQualifiedName, ThreadLocal.class.getName())) {
+ return false;
+ }
+ final PsiTypeParameter[] typeParameters = threadLocalClass.getTypeParameters();
+ if (typeParameters.length != 1) return !PsiUtil.isLanguageLevel5OrHigher(context);
+ final PsiType toTypeParameterValue = resolveResult.getSubstitutor().substitute(typeParameters[0]);
+ if (toTypeParameterValue != null) {
+ if (from instanceof PsiPrimitiveType) {
+ final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(toTypeParameterValue);
+ if (unboxedInitialType != null) {
+ return TypeConversionUtil.areTypesConvertible(from, unboxedInitialType);
+ }
+ }
+ else {
+ return TypeConversionUtil.isAssignable(from, PsiUtil.captureToplevelWildcards(toTypeParameterValue, context));
+ }
+ }
+ return !PsiUtil.isLanguageLevel5OrHigher(context);
+ }
+ return false;
+ }
+
+ @Nullable
+ public static TypeConversionDescriptor findDirectConversion(PsiElement context, PsiType to, PsiType from, TypeMigrationLabeler labeler) {
+ final PsiClass toTypeClass = PsiUtil.resolveClassInType(to);
+ LOG.assertTrue(toTypeClass != null);
+
+ if (context instanceof PsiArrayAccessExpression) {
+ return new TypeConversionDescriptor("$qualifier$[$val$]", "$qualifier$.get()[$val$]");
+ }
+ final PsiElement parent = context.getParent();
+ if (parent instanceof PsiAssignmentExpression) {
+ final IElementType operationSign = ((PsiAssignmentExpression)parent).getOperationTokenType();
+ if (operationSign == JavaTokenType.EQ) {
+ return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set(" + toBoxed("$val$", from, context)+")", (PsiAssignmentExpression)parent);
+ }
+ }
+
+ if (context instanceof PsiReferenceExpression) {
+ final PsiExpression qualifierExpression = ((PsiReferenceExpression)context).getQualifierExpression();
+ final PsiExpression expression = context.getParent() instanceof PsiMethodCallExpression && qualifierExpression != null
+ ? qualifierExpression
+ : (PsiExpression)context;
+ return new TypeConversionDescriptor("$qualifier$", toPrimitive("$qualifier$.get()", from, context), expression);
+ }
+ else if (context instanceof PsiBinaryExpression) {
+ final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)context;
+ final String sign = binaryExpression.getOperationSign().getText();
+ return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", toPrimitive("$qualifier$.get()", from, context) + " " + sign + " $val$");
+ }
+
+ if (parent instanceof PsiExpressionStatement) {
+ if (context instanceof PsiPostfixExpression) {
+ final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)context;
+ final String sign = postfixExpression.getOperationSign().getText();
+
+ return new TypeConversionDescriptor("$qualifier$" + sign, "$qualifier$.set(" +
+ getBoxedWrapper(from, to, toPrimitive("$qualifier$.get()", from, context) + " " + sign.charAt(0) + " 1",
+ labeler, context, postfixExpression.getOperand().getText() +
+ sign.charAt(0) +
+ " 1") +
+ ")");
+ }
+ else if (context instanceof PsiPrefixExpression) {
+ final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)context;
+ final PsiJavaToken operationSign = ((PsiPrefixExpression)context).getOperationSign();
+ if (operationSign.getTokenType() == JavaTokenType.EXCL) {
+ return new TypeConversionDescriptor("!$qualifier$", "!$qualifier$.get()");
+ }
+ final String sign = operationSign.getText();
+ final PsiExpression operand = prefixExpression.getOperand();
+ return new TypeConversionDescriptor(sign + "$qualifier$", "$qualifier$.set(" +
+ getBoxedWrapper(from, to, toPrimitive("$qualifier$.get()", from, context) + " " + sign.charAt(0) + " 1",
+ labeler, context, operand != null ? operand.getText() +
+ sign.charAt(0) +
+ " 1" : null) +
+ ")");
+ }
+ else if (context instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)context;
+ final PsiJavaToken signToken = assignmentExpression.getOperationSign();
+ final IElementType operationSign = signToken.getTokenType();
+ final String sign = signToken.getText();
+ final PsiExpression lExpression = assignmentExpression.getLExpression();
+ if (operationSign == JavaTokenType.EQ) {
+ if (lExpression instanceof PsiReferenceExpression) {
+ final PsiElement element = ((PsiReferenceExpression)lExpression).resolve();
+ if (element instanceof PsiVariable && ((PsiVariable)element).hasModifierProperty(PsiModifier.FINAL)) {
+ return wrapWithNewExpression(to, from, ((PsiAssignmentExpression)context).getRExpression());
+ }
+ }
+ return new TypeConversionDescriptor("$qualifier$ = $val$", "$qualifier$.set(" +
+ toBoxed("$val$", from, context) +
+ ")");
+ }
+ else {
+ final PsiExpression rExpression = assignmentExpression.getRExpression();
+ return new TypeConversionDescriptor("$qualifier$" + sign + "$val$", "$qualifier$.set(" +
+ getBoxedWrapper(from, to, toPrimitive("$qualifier$.get()", from, context) +
+ " " + sign.charAt(0) +
+ " $val$", labeler, context,
+ rExpression != null
+ ? lExpression
+ .getText() +
+ sign.charAt(0) +
+ rExpression.getText()
+ : null) +
+ ")");
+ }
+ }
+ }
+ return null;
+ }
+
+ public static TypeConversionDescriptor wrapWithNewExpression(PsiType to, PsiType from, PsiExpression initializer) {
+ final String boxedTypeName = from instanceof PsiPrimitiveType ? ((PsiPrimitiveType)from).getBoxedTypeName() : from.getCanonicalText();
+ return new TypeConversionDescriptor("$qualifier$", "new " +
+ to.getCanonicalText() +
+ "() {\n" +
+ "@Override \n" +
+ "protected " +
+ boxedTypeName +
+ " initialValue() {\n" +
+ " return " +
+ (PsiUtil.isLanguageLevel5OrHigher(initializer)
+ ? initializer.getText()
+ : (from instanceof PsiPrimitiveType ? "new " +
+ ((PsiPrimitiveType)from).getBoxedTypeName() +
+ "(" +
+ initializer.getText() +
+ ")" : initializer.getText())) +
+ ";\n" +
+ "}\n" +
+ "}", initializer);
+ }
+
+ private static String toPrimitive(String replaceByArg, PsiType from, PsiElement context) {
+ return PsiUtil.isLanguageLevel5OrHigher(context)
+ ? replaceByArg
+ : from instanceof PsiPrimitiveType ? "((" +
+ ((PsiPrimitiveType)from).getBoxedTypeName() +
+ ")" +
+ replaceByArg +
+ ")." +
+ from.getCanonicalText() +
+ "Value()" : "((" + from.getCanonicalText() + ")" + replaceByArg + ")";
+ }
+
+ private static String toBoxed(String replaceByArg, PsiType from, PsiElement context) {
+ return PsiUtil.isLanguageLevel5OrHigher(context)
+ ? replaceByArg
+ : from instanceof PsiPrimitiveType ? "new " + ((PsiPrimitiveType)from).getBoxedTypeName() +
+ "(" +
+ replaceByArg +
+ ")"
+ : replaceByArg;
+ }
+
+ private static String getBoxedWrapper(final PsiType from,
+ final PsiType to,
+ @NotNull String arg,
+ TypeMigrationLabeler labeler,
+ PsiElement context,
+ @Nullable String tryType) {
+ if (from instanceof PsiPrimitiveType) {
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(to);
+ final PsiClass threadLocalClass = resolveResult.getElement();
+ LOG.assertTrue(threadLocalClass != null);
+ final PsiTypeParameter[] typeParameters = threadLocalClass.getTypeParameters();
+ if (typeParameters.length == 1) {
+ final PsiType initial = resolveResult.getSubstitutor().substitute(typeParameters[0]);
+ final PsiPrimitiveType unboxedInitialType = PsiPrimitiveType.getUnboxedType(initial);
+ if (unboxedInitialType != null) {
+ LOG.assertTrue(initial != null);
+ if (tryType != null) {
+ final PsiType exprType = labeler.getTypeEvaluator().evaluateType(
+ JavaPsiFacade.getElementFactory(threadLocalClass.getProject()).createExpressionFromText(tryType, context));
+ if (exprType != null && unboxedInitialType.isAssignableFrom(exprType)) {
+ return toBoxed(arg, from, context);
+ }
+ }
+ return "new " + initial.getCanonicalText() + "((" + unboxedInitialType.getCanonicalText() + ")(" + arg + "))";
+ }
+ }
+ }
+ return toBoxed(arg, from, context);
+ }
+
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/after.java.template b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/after.java.template
new file mode 100644
index 000000000000..413db792c422
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/after.java.template
@@ -0,0 +1,10 @@
+public class X {
+ {
+ new Comparable<String>() {
+ @Override
+ public int compareTo(String o) {
+ return 0;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/before.java.template b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/before.java.template
new file mode 100644
index 000000000000..96eb1b46dbd2
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/before.java.template
@@ -0,0 +1,10 @@
+public class X {
+ {
+ new Comparable<<spam>Object</spam>>() {
+ @Override
+ public int compareTo(Object o) {
+ return 0;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/description.html b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/description.html
new file mode 100644
index 000000000000..d4dc0a283bf8
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ChangeClassParametersIntention/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+Changes anonymous class type parameters in live template.
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/after.java.template b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/after.java.template
new file mode 100644
index 000000000000..53cfaf5be80c
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/after.java.template
@@ -0,0 +1,4 @@
+import java.util.concurrent.atomic.*;
+public class X {
+ AtomicInteger count = new AtomicInteger(0);
+}
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/before.java.template b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/before.java.template
new file mode 100644
index 000000000000..9e6048be8324
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/before.java.template
@@ -0,0 +1,3 @@
+public class X {
+ <spot>int count = 0;</spot>
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/description.html b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/description.html
new file mode 100644
index 000000000000..0f799f7b36a8
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToAtomicIntention/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+This intention replaces variable type with corresponding atomic type.
+</body>
+</html>
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/after.java.template b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/after.java.template
new file mode 100644
index 000000000000..377017bd41c6
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/after.java.template
@@ -0,0 +1,15 @@
+import java.text.*;
+import java.util.Date;
+
+class X {
+ private static final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
+ @Override
+ protected DateFormat initialValue() {
+ return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
+ }
+ };
+
+ public String getDateString() {
+ return dateFormat.get().format(new Date());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/before.java.template b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/before.java.template
new file mode 100644
index 000000000000..14fae704762b
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/before.java.template
@@ -0,0 +1,10 @@
+import java.text.*;
+import java.util.Date;
+
+public class X {
+ private static DateFormat <spot>dateFormat</spot> = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
+
+ public String getDateString() {
+ return dateFormat.format(new Date());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/description.html b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/description.html
new file mode 100644
index 000000000000..930467e5df1b
--- /dev/null
+++ b/plugins/typeMigration/src/intentionDescriptions/ConvertFieldToThreadLocalIntention/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+This intention replaces field type with corresponding thread local.
+</body>
+</html>
diff --git a/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToAtomicIntentionTest.java b/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToAtomicIntentionTest.java
new file mode 100644
index 000000000000..4a0b73dde767
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToAtomicIntentionTest.java
@@ -0,0 +1,30 @@
+package com.intellij.codeInsight;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+import com.intellij.openapi.application.PluginPathManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author anna
+ */
+public class ConvertToAtomicIntentionTest extends LightQuickFixParameterizedTestCase {
+ @Override
+ protected boolean shouldBeAvailableAfterExecution() {
+ return true;
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/intentions/atomic";
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("typeMigration") + "/testData";
+ }
+
+ public void test() throws Exception {
+ doAllTests();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToThreadLocalIntentionTest.java b/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToThreadLocalIntentionTest.java
new file mode 100644
index 000000000000..389ced7354af
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/codeInsight/ConvertToThreadLocalIntentionTest.java
@@ -0,0 +1,30 @@
+package com.intellij.codeInsight;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
+import com.intellij.openapi.application.PluginPathManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author anna
+ */
+public class ConvertToThreadLocalIntentionTest extends LightQuickFixParameterizedTestCase {
+ @Override
+ protected boolean shouldBeAvailableAfterExecution() {
+ return true;
+ }
+
+ @Override
+ protected String getBasePath() {
+ return "/intentions/threadLocal";
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("typeMigration") + "/testData";
+ }
+
+ public void test() throws Exception {
+ doAllTests();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/AllTypeMigrationTests.java b/plugins/typeMigration/test/com/intellij/refactoring/AllTypeMigrationTests.java
new file mode 100644
index 000000000000..2fb8d9054628
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/AllTypeMigrationTests.java
@@ -0,0 +1,26 @@
+/*
+ * User: anna
+ * Date: 04-Aug-2008
+ */
+package com.intellij.refactoring;
+
+import com.intellij.codeInsight.ConvertToAtomicIntentionTest;
+import com.intellij.codeInsight.ConvertToThreadLocalIntentionTest;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTypeMigrationTests {
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static Test suite() {
+ final TestSuite suite = new TestSuite();
+ suite.addTestSuite(TypeMigrationTest.class);
+ suite.addTestSuite(TypeMigrationByAtomicRuleTest.class);
+ suite.addTestSuite(TypeMigrationByThreadLocalRuleTest.class);
+ suite.addTestSuite(MigrateTypeSignatureTest.class);
+ suite.addTestSuite(ChangeTypeSignatureTest.class);
+ suite.addTestSuite(WildcardTypeMigrationTest.class);
+ suite.addTestSuite(ConvertToAtomicIntentionTest.class);
+ suite.addTestSuite(ConvertToThreadLocalIntentionTest.class);
+ return suite;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/ChangeTypeSignatureTest.java b/plugins/typeMigration/test/com/intellij/refactoring/ChangeTypeSignatureTest.java
new file mode 100644
index 000000000000..e85b2f79fd30
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/ChangeTypeSignatureTest.java
@@ -0,0 +1,148 @@
+/*
+ * User: anna
+ * Date: 18-Mar-2008
+ */
+package com.intellij.refactoring;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PsiImmediateClassType;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import org.jetbrains.annotations.NotNull;
+
+public class ChangeTypeSignatureTest extends LightCodeInsightTestCase {
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("typeMigration") + "/testData";
+ }
+
+ private void doTest(boolean success, String migrationTypeText) throws Exception {
+ String dataPath = "/refactoring/changeTypeSignature/";
+ configureByFile(dataPath + getTestName(false) + ".java");
+ final PsiFile file = getFile();
+ final PsiElement element = file.findElementAt(getEditor().getCaretModel().getOffset());
+ final PsiReferenceParameterList parameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
+ assert parameterList != null;
+ final PsiClass superClass = (PsiClass)((PsiJavaCodeReferenceElement)parameterList.getParent()).resolve();
+ assert superClass != null;
+
+ PsiType migrationType = getJavaFacade().getElementFactory().createTypeFromText(migrationTypeText, null);
+
+ try {
+ final TypeMigrationRules rules = new TypeMigrationRules(TypeMigrationLabeler.getElementType(parameterList));
+ rules.setMigrationRootType(PsiSubstitutor.EMPTY.put(superClass.getTypeParameters()[0], migrationType).substitute(new PsiImmediateClassType(superClass, PsiSubstitutor.EMPTY)));
+ rules.setBoundScope(GlobalSearchScope.projectScope(getProject()));
+ new TypeMigrationProcessor(getProject(), parameterList, rules).run();
+ if (success) {
+ checkResultByFile(dataPath + getTestName(false) + ".java.after");
+ } else {
+ fail("Conflicts should be detected");
+ }
+ }
+ catch (RuntimeException e) {
+ if (success) {
+ e.printStackTrace();
+ fail("Conflicts should not appear");
+ }
+ }
+ }
+
+ private void doTest(boolean success) throws Exception {
+ doTest(success, CommonClassNames.JAVA_LANG_OBJECT);
+ }
+
+ public void testListTypeArguments() throws Exception {
+ doTest(true);
+ }
+
+ public void testFieldUsage() throws Exception {
+ doTest(true);
+ }
+
+ public void testFieldUsage1() throws Exception {
+ doTest(true);
+ }
+
+ public void testReturnType() throws Exception {
+ doTest(true);
+ }
+
+ public void testReturnType1() throws Exception {
+ doTest(true);
+ }
+
+ public void testReturnType2() throws Exception {
+ doTest(true);
+ }
+
+ public void testPassedParameter() throws Exception {
+ doTest(true);
+ }
+
+ public void testPassedParameter1() throws Exception {
+ doTest(true, "java.lang.Integer");
+ }
+
+ public void testPassedParameter2() throws Exception {
+ doTest(true);
+ }
+
+ public void testUsedInSuper() throws Exception {
+ doTest(true);
+ }
+
+ public void testCompositeReturnType() throws Exception {
+ doTest(true);
+ }
+
+ public void testTypeHierarchy() throws Exception {
+ doTest(true);
+ }
+
+ public void testTypeHierarchy1() throws Exception {
+ doTest(true);
+ }
+
+ public void testTypeHierarchy2() throws Exception {
+ doTest(true);
+ }
+
+ public void testTypeHierarchyFieldUsage() throws Exception {
+ doTest(true);
+ }
+
+ public void testTypeHierarchyFieldUsageConflict() throws Exception {
+ doTest(true);
+ }
+
+ public void testParameterMigration() throws Exception {
+ doTest(true);
+ }
+
+ public void testParameterMigration1() throws Exception {
+ doTest(true, "java.lang.Integer");
+ }
+
+ public void testParameterMigration2() throws Exception {
+ doTest(true, "java.lang.Integer");
+ }
+
+ public void testFieldTypeMigration() throws Exception {
+ doTest(true, "java.lang.String");
+ }
+
+ public void testMethodReturnTypeMigration() throws Exception {
+ doTest(true, "java.lang.Integer");
+ }
+
+ @Override
+ protected boolean isRunInWriteAction() {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/MigrateTypeSignatureTest.java b/plugins/typeMigration/test/com/intellij/refactoring/MigrateTypeSignatureTest.java
new file mode 100644
index 000000000000..7889306ed6f0
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/MigrateTypeSignatureTest.java
@@ -0,0 +1,561 @@
+/*
+ * User: anna
+ * Date: 30-Apr-2008
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.CommonClassNames;
+import com.intellij.psi.PsiEllipsisType;
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+public class MigrateTypeSignatureTest extends TypeMigrationTestBase {
+ @NotNull
+ @Override
+ public String getTestRoot() {
+ return "/refactoring/migrateTypeSignature/";
+ }
+
+ public void testExprAccess2Lvalue() throws Exception {
+ doTestFieldType("myForAccess", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null));
+ }
+
+ public void testExprAccess2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassGrandChild", null));
+ }
+
+ public void testExprAccessParent2Lvalue() throws Exception {
+ doTestFieldType("myForSuperAccess", "Ession",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null));
+ }
+
+ public void testExprAccessParent2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassGrandChild", null));
+ }
+
+ public void testExprArrayAccessNegative() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT, PsiType.DOUBLE);
+ }
+
+ public void testExprArrayAccessPositive() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT, PsiType.CHAR);
+ }
+
+ public void testExprCalcBooleanBoolean() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.BOOLEAN, PsiType.INT);
+ }
+
+ public void testExprCalcBooleanNumeric() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testExprCalcBooleanReference() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ PsiType.DOUBLE);
+ }
+
+ public void testExprCalcNumeric2Boolean() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT, PsiType.BOOLEAN);
+ }
+
+ public void testExprCalcNumeric2Floating() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT, PsiType.FLOAT);
+ }
+
+ public void testExprCalcNumeric2Int() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT, PsiType.LONG);
+ }
+
+ public void testExprCalcNumeric2String() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprCast2LvalueNeg() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.BYTE,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprCast2LvaluePos() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.BYTE, PsiType.INT);
+ }
+
+ public void testExprConcatNumeric2Reference() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testExprConcatNumeric2String() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprConcatString2Numeric() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ PsiType.INT);
+ }
+
+ public void testExprConcatString2Reference() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testExprInstanceofNeg() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_LIST, null));
+ }
+
+ public void testExprInstanceofPos() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_MAP, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.AbstractMap", null));
+ }
+
+ public void testExprLiteralBoolean() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.BOOLEAN);
+ }
+
+ public void testExprLiteralByte() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.BYTE);
+ }
+
+ public void testExprLiteralChar() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.CHAR);
+ }
+
+ public void testExprLiteralClassExtends() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<? extends java.util.Collection[]>", null));
+ }
+
+ public void testExprLiteralClassPrimitive() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<Integer>", null));
+ }
+
+ public void testExprLiteralClassPrimitiveArray() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<int[]>", null));
+ }
+
+ public void testExprLiteralClassRaw() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class", null));
+ }
+
+ public void testExprLiteralClassReference() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<java.util.Set>", null));
+ }
+
+ public void testExprLiteralClassReferenceArray() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<java.util.Set[]>", null));
+ }
+
+ public void testExprLiteralClassSuper() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Class<? super java.util.AbstractSet[]>", null));
+ }
+
+ public void testExprLiteralDouble() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.DOUBLE);
+ }
+
+ public void testExprLiteralFloat() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.FLOAT);
+ }
+
+ public void testExprLiteralInt() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.INT);
+ }
+
+ public void testExprLiteralLong() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.LONG);
+ }
+
+ public void testExprLiteralShort() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ PsiType.SHORT);
+ }
+
+ public void testExprLiteralString() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprNewArrayArray2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null).createArrayType());
+ }
+
+ public void testExprNewArrayArray2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null).createArrayType().createArrayType().createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null).createArrayType().createArrayType().createArrayType());
+ }
+
+ public void testExprNewArrayGen2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<java.lang.Integer>", null).createArrayType());
+ }
+
+ public void testExprNewArrayPrimitive2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.BOOLEAN, PsiType.INT);
+ }
+
+ public void testExprNewArrayPrimitive2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ PsiType.BOOLEAN.createArrayType().createArrayType(),
+ PsiType.INT.createArrayType().createArrayType());
+ }
+
+ public void testExprNewArrayReftype2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null));
+ }
+
+ public void testExprNewArrayReftype2Rvalue() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null).createArrayType().createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null).createArrayType().createArrayType());
+ }
+
+ public void testExprNewGen() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<Subject>", null));
+ }
+
+ public void testExprNewGenExtends() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? extends Subject>", null));
+ }
+
+ public void testExprNewGenSuper() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? super Subject>", null));
+ }
+
+ public void testExprNewReference() throws Exception {
+ doTestFieldType("myField", "Expr",
+ myJavaFacade.getElementFactory().createTypeFromText("Expr.Ancestor", null),
+ myJavaFacade.getElementFactory().createTypeFromText("Expr.Subject", null));
+ }
+
+ public void testExprReturn2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprReturn2Rvalue() throws Exception {
+ doTestMethodType("meth", "Expr", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testExprTernary() throws Exception {
+ doTestFirstParamType("meth", "Expr", PsiType.DOUBLE,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testOverridingDown() throws Exception {
+ doTestMethodType("getInt", "Parent", PsiType.INT, PsiType.BYTE);
+ }
+
+ public void testOverridingUp() throws Exception {
+ doTestMethodType("getInt", "Child", PsiType.INT, PsiType.BYTE);
+ }
+
+ public void testSpecJavadoc() throws Exception {
+ doTestFirstParamType("meth", "Spec", PsiType.DOUBLE,
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null));
+ }
+
+ public void testSpecNotUsed() throws Exception {
+ doTestFieldType("myField", "Spec", PsiType.INT, PsiType.BOOLEAN);
+ }
+
+ public void testTypeArrayReftype2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Descendant", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("Subject", null).createArrayType());
+ }
+
+ public void testTypeArrayReftype2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Ancestor", null).createArrayType().createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("Subject", null).createArrayType().createArrayType());
+ }
+
+ public void testTypeArrayRoots2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Holder", null),
+ myJavaFacade.getElementFactory().createTypeFromText("Holder", null).createArrayType());
+ }
+
+ public void testTypeArrayVararg2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Descendant", null).createArrayType(),
+ new PsiEllipsisType(myJavaFacade.getElementFactory().createTypeFromText("Subject", null)));
+ }
+
+ public void testTypeArrayVararg2RvalueNeg() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Ancestor", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("Descendant", null).createArrayType());
+ }
+
+ public void testTypeArrayVararg2RvaluePos() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("Ancestor", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("Subject", null).createArrayType());
+ }
+
+ public void testTypeAutoboxBoolean2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BOOLEAN,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Boolean", null));
+ }
+
+ public void testTypeAutoboxBoolean2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Boolean", null),
+ PsiType.BOOLEAN);
+ }
+
+ public void testTypeAutoboxByte2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Byte", null));
+ }
+
+ public void testTypeAutoboxByte2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Byte", null),
+ PsiType.BYTE);
+ }
+
+ public void testTypeAutoboxChar2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.CHAR,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Character", null));
+ }
+
+ public void testTypeAutoboxChar2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Character", null),
+ PsiType.CHAR);
+ }
+
+ public void testTypeAutoboxDouble2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.DOUBLE,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Double", null));
+ }
+
+ public void testTypeAutoboxDouble2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Double", null),
+ PsiType.DOUBLE);
+ }
+
+ public void testTypeAutoboxFloat2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.FLOAT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Float", null));
+ }
+
+ public void testTypeAutoboxFloat2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Float", null),
+ PsiType.FLOAT);
+ }
+
+ public void testTypeAutoboxInt2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.INT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null));
+ }
+
+ public void testTypeAutoboxInt2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null),
+ PsiType.INT);
+ }
+
+ public void testTypeAutoboxLong2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.LONG,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Long", null));
+ }
+
+ public void testTypeAutoboxLong2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Long", null),
+ PsiType.LONG);
+ }
+
+ public void testTypeAutoboxShort2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.SHORT,
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Short", null));
+ }
+
+ public void testTypeAutoboxShort2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", myJavaFacade.getElementFactory().createTypeFromText("java.lang.Short", null),
+ PsiType.SHORT);
+ }
+
+ public void testTypeGenAncestor2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<Subject>", null));
+ }
+
+ public void testTypeGenAncestorWildcard2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? extends Subject>", null));
+ }
+
+ public void testTypeGenDescendant2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<Subject>", null));
+ }
+
+ public void testTypeGenDescendantWildcard2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? super Subject>", null));
+ }
+
+ public void testTypeGenRaw2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<Any>", null),
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null));
+ }
+
+ public void testTypeGenRaw2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<Any>", null),
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null));
+ }
+
+ public void testTypePrimsubBoolean2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.INT, PsiType.BOOLEAN);
+ }
+
+ public void testTypePrimsubBoolean2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.INT, PsiType.BOOLEAN);
+ }
+
+ public void testTypePrimsubByte2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.BYTE);
+ }
+
+ public void testTypePrimsubChar2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.CHAR);
+ }
+
+ public void testTypePrimsubChar2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.CHAR);
+ }
+
+ public void testTypePrimsubDouble2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.DOUBLE);
+ }
+
+ public void testTypePrimsubFloat2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.FLOAT);
+ }
+
+ public void testTypePrimsubFloat2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.FLOAT);
+ }
+
+ public void testTypePrimsubInt2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.INT);
+ }
+
+ public void testTypePrimsubInt2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.INT);
+ }
+
+ public void testTypePrimsubLong2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.LONG);
+ }
+
+ public void testTypePrimsubLong2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.LONG);
+ }
+
+ public void testTypePrimsubShort2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type", PsiType.BYTE, PsiType.SHORT);
+ }
+
+ public void testTypePrimsubShort2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type", PsiType.DOUBLE, PsiType.SHORT);
+ }
+
+ public void testTypeRefClassChild2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null));
+ }
+
+ public void testTypeRefClassParent2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null));
+ }
+
+ public void testTypeRefClassParent2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null),
+ myJavaFacade.getElementFactory().createTypeFromText("ClassParent", null));
+ }
+
+ public void testTypeRefFaceChild2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null));
+ }
+
+ public void testTypeRefFaceChild2Rvalue() throws Exception {
+ doTestFieldType("myField", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null),
+ myJavaFacade.getElementFactory().createTypeFromText("FaceChild", null));
+ }
+
+ public void testTypeRefFaceParent2Lvalue() throws Exception {
+ doTestFirstParamType("meth", "Type",
+ myJavaFacade.getElementFactory().createTypeFromText("ClassChild", null),
+ myJavaFacade.getElementFactory().createTypeFromText("FaceParent", null));
+ }
+}
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByAtomicRuleTest.java b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByAtomicRuleTest.java
new file mode 100644
index 000000000000..80658077e986
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByAtomicRuleTest.java
@@ -0,0 +1,100 @@
+/*
+ * User: anna
+ * Date: 19-Aug-2009
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+public class TypeMigrationByAtomicRuleTest extends TypeMigrationTestBase{
+ @NotNull
+ @Override
+ protected String getTestRoot() {
+ return "/refactoring/typeMigrationByAtomic/";
+ }
+
+ private void doTestDirectMigration() throws Exception {
+ doTestFieldType("i", PsiType.INT, myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicInteger", null));
+ }
+
+
+ public void testDirectIncrementDecrement() throws Exception {
+ doTestDirectMigration();
+ }
+
+ public void testDirectAssignments() throws Exception {
+ doTestDirectMigration();
+ }
+
+ public void testDirectConditions() throws Exception {
+ doTestFieldType("b", PsiType.BOOLEAN, myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicBoolean", null));
+ }
+
+
+ public void testDirectByte() throws Exception {
+ doTestFieldType("b", PsiType.BYTE, myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReference<java.lang.Byte>", null));
+ }
+
+ public void testDirectString() throws Exception {
+ doTestFieldType("s", myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReference<java.lang.String>", null));
+ }
+
+ public void testDirectForeach() throws Exception {
+ doTestFieldType("lst", myJavaFacade.getElementFactory().createTypeFromText("java.util.List<java.lang.String>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReference<java.util.List<java.lang.String>>", null));
+ }
+
+ public void testDirectStringArray() throws Exception {
+ doTestFieldType("s", myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText(AtomicReferenceArray.class.getName() + "<java.lang.String>", null));
+ }
+
+ public void testDirectIntArray() throws Exception {
+ doTestFieldType("a", PsiType.INT.createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText(AtomicIntegerArray.class.getName(), null));
+ }
+
+ private void doTestReverseMigration() throws Exception {
+ doTestFieldType("i", myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicInteger", null), PsiType.INT);
+ }
+
+
+ public void testReverseIncrementDecrement() throws Exception {
+ doTestReverseMigration();
+ }
+
+ public void testReverseAssignments() throws Exception {
+ doTestReverseMigration();
+ }
+
+ public void testReverseConditions() throws Exception {
+ doTestFieldType("b", myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicBoolean", null), PsiType.BOOLEAN);
+ }
+
+ public void testReverseByte() throws Exception {
+ doTestFieldType("b", myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReference<java.lang.Byte>", null), PsiType.BYTE);
+ }
+
+ public void testReverseString() throws Exception {
+ doTestFieldType("s",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReference<java.lang.String>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null));
+ }
+
+ public void testReverseStringArray() throws Exception {
+ doTestFieldType("s",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicReferenceArray<java.lang.String>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testReverseIntArray() throws Exception {
+ doTestFieldType("a",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.concurrent.atomic.AtomicIntegerArray", null),
+ PsiType.INT.createArrayType());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByThreadLocalRuleTest.java b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByThreadLocalRuleTest.java
new file mode 100644
index 000000000000..5d002d3fcced
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationByThreadLocalRuleTest.java
@@ -0,0 +1,44 @@
+/*
+ * User: anna
+ * Date: 19-Aug-2009
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiType;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import org.jetbrains.annotations.NotNull;
+
+public class TypeMigrationByThreadLocalRuleTest extends TypeMigrationTestBase{
+ @NotNull
+ @Override
+ protected String getTestRoot() {
+ return "/refactoring/typeMigrationByThreadLocal/";
+ }
+
+
+ public void testDirectInt() throws Exception {
+ doTestFieldType("i", PsiType.INT, myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<java.lang.Integer>", null));
+ }
+
+ public void testDirectByte() throws Exception {
+ doTestFieldType("i", PsiType.BYTE, myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<java.lang.Byte>", null));
+ }
+
+ public void testDirectString() throws Exception {
+ doTestFieldType("myS", PsiType.getJavaLangString(myPsiManager, GlobalSearchScope.allScope(myProject)), myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<java.lang.String>", null));
+ }
+
+ public void testLanguageLevel() throws Exception {
+ final LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(getProject());
+ final LanguageLevel languageLevel = extension.getLanguageLevel();
+ try {
+ extension.setLanguageLevel(LanguageLevel.JDK_1_3);
+ doTestFieldType("i", PsiType.INT, myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal", null));
+ }
+ finally {
+ extension.setLanguageLevel(languageLevel);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
new file mode 100644
index 000000000000..b3c36dca19f2
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
@@ -0,0 +1,883 @@
+package com.intellij.refactoring;
+
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author db
+ * @since 22.07.2003
+ */
+public class TypeMigrationTest extends TypeMigrationTestBase {
+ private PsiElementFactory myFactory;
+
+ @NotNull
+ @Override
+ public String getTestRoot() {
+ return "/refactoring/typeMigration/";
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST);
+ myFactory = myJavaFacade.getElementFactory();
+ }
+
+ public void testT07() {
+ doTestFieldType("f",
+ PsiType.INT.createArrayType(),
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType());
+ }
+
+ public void testT08() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT09() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT10() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ public void testT11() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Map<java.lang.Integer, java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.Map<java.lang.String, java.lang.Integer>", null));
+ }
+
+ public void testT12() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ public void testT13() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null));
+ }
+
+ public void testT14() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("B", null),
+ myFactory.createTypeFromText("A", null));
+ }
+
+ //do not touch javadoc refs etc
+ public void testT15() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("B", null),
+ myFactory.createTypeFromText("A", null));
+ }
+
+ //do not touch signature with method type parameters
+ public void testT16() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("A", null),
+ myFactory.createTypeFromText("B", null));
+ }
+
+ //change method signature inspired by call on parameters
+ public void testT17() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("A", null),
+ myFactory.createTypeFromText("B", null));
+ }
+
+ //extending iterable -> used in foreach statement
+ public void testT18() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("A", null),
+ myFactory.createTypeFromText("B", null));
+ }
+
+ public void testT19() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Map<java.lang.String, java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.HashMap<java.lang.Integer, java.lang.Integer>", null));
+ }
+
+ public void testT20() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.HashMap<java.lang.Integer, java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.Map<java.lang.String, java.lang.String>", null));
+ }
+
+ public void testT21() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Map<java.lang.String, java.util.List<java.lang.String>>",
+ null),
+ myFactory.createTypeFromText("java.util.Map<java.lang.String, java.util.Set<java.lang.String>>",
+ null)
+ );
+ }
+
+ //varargs : removed after migration?!
+ public void testT22() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.String", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ //substitution from super class: type params substitution needed
+ public void testT23() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("HashMap<java.lang.String, java.util.Set<java.lang.String>>", null),
+ myFactory.createTypeFromText("HashMap<java.lang.String, java.util.List<java.lang.String>>", null));
+ }
+
+ //check return type unchanged when it is possible
+ public void testT24() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("C", null),
+ myFactory.createTypeFromText("D", null));
+ }
+
+ public void testT25() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("C", null),
+ myFactory.createTypeFromText("D", null));
+ }
+
+ //check param type change
+ public void testT26() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("C", null),
+ myFactory.createTypeFromText("D", null));
+ }
+
+ public void testT27() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("C", null),
+ myFactory.createTypeFromText("D", null));
+ }
+
+ //list --> array
+ public void testT28() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT29() {
+ doTestMethodType("get",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ public void testT30() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+
+ public void testT31() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("Test", null),
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ //non code usages
+ public void testT32() {
+ doTestFirstParamType("bar",
+ myFactory.createTypeFromText("long", null),
+ myFactory.createTypeFromText("int", null));
+ }
+
+ //change type arguments for new expressions: l = new ArrayList<String>() -> l = new ArrayList<Integer>()
+ public void testT33() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null));
+ }
+
+ //new expression new ArrayList<String>() should be left without modifications
+ public void testT34() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.AbstractList<java.lang.String>", null));
+ }
+
+ public void testT35() {
+ doTestFieldType("myParent",
+ myFactory.createTypeFromText("Test", null),
+ myFactory.createTypeFromText("TestImpl", null));
+ }
+
+ //co-variant/contra-variant positions for primitive types 36-39
+ public void testT36() {
+ doTestFirstParamType("foo", PsiType.INT, PsiType.BYTE);
+ }
+
+ public void testT37() {
+ doTestFirstParamType("foo", PsiType.SHORT, PsiType.INT);
+ }
+
+ public void testT38() {
+ doTestFirstParamType("foo", PsiType.SHORT, PsiType.LONG);
+ }
+
+ public void testT39() {
+ doTestFirstParamType("foo", PsiType.SHORT, PsiType.BYTE);
+ }
+
+ //Set s = new HashSet() -> HashSet s = new HashSet();
+ public void testT40() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_UTIL_LIST, null),
+ myFactory.createTypeFromText("java.util.ArrayList", null));
+ }
+
+ //Set s = new HashSet<String>() -> HashSet s = new HashSet<String>();
+ public void testT41() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_UTIL_LIST, null),
+ myFactory.createTypeFromText("java.util.ArrayList", null));
+ }
+
+ //Set s = new HashSet() -> HashSet<String> s = new HashSet();
+ public void testT42() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_UTIL_LIST, null),
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.String>", null));
+ }
+
+ //long l; Object o = l -> long l; Long o = l;
+ public void testT43() {
+ doTestFieldType("o",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myFactory.createTypeFromText("java.lang.Long", null));
+ }
+
+ //long l; int i; l = i; -> long l; byte i; l = i;
+ public void testT44() {
+ doTestFieldType("i", PsiType.INT, PsiType.BYTE);
+ }
+
+ //long l; int i; l = i; -> byte l; -> byte i; l = i;
+ public void testT45() {
+ doTestFieldType("l", PsiType.LONG, PsiType.BYTE);
+ }
+
+ //byte i; long j = i; -> byte i; int j = i;
+ public void testT46() {
+ doTestFieldType("j", PsiType.LONG, PsiType.INT);
+ }
+
+ //o = null -? int o = null
+ public void testT47() {
+ doTestFieldType("o", myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null), PsiType.INT);
+ }
+
+ //co-variant/contra-variant assignments: leave types if possible change generics signature only 48-49
+ // foo(AbstractSet<String> s){Set<String> ss = s} -> foo(AbstractSet<Integer> s){Set<Integer> ss = s}
+ public void testT48() {
+ doTestFirstParamType("foo",
+ myFactory.createTypeFromText("java.util.AbstractSet<A>", null),
+ myFactory.createTypeFromText("java.util.AbstractSet<B>", null));
+ }
+
+ // Set<String> f; foo(AbstractSet<String> s){f = s} -> Set<Integer>f; foo(AbstractSet<Integer> s){f = s}
+ public void testT49() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Set<A>", null),
+ myFactory.createTypeFromText("java.util.Set<B>", null));
+ }
+
+ //captured wildcard: Set<? extends JComponent> s; Set<? extends JComponent> c1 = s; ->
+ // Set<? extends JButton> s; Set<? extends JButton> c1 = s;
+ public void testT50() {
+ doTestFieldType("c1",
+ myFactory.createTypeFromText("java.util.Set<? extends JComponent>", null),
+ myFactory.createTypeFromText("java.util.Set<? extends JButton>", null));
+ }
+
+ //array initialization: 51-52
+ public void testT51() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null).createArrayType());
+ }
+
+ public void testT52() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null).createArrayType(),
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null).createArrayType());
+ }
+
+ //generic type promotion to array initializer
+ public void testT53() {
+ doTestFieldType("f",
+ PsiType.DOUBLE.createArrayType(),
+ myFactory.createTypeFromText("java.util.Set<java.lang.String>", null).createArrayType());
+ }
+
+ //wildcard type promotion to expressions 54-55
+ public void testT54() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Set<java.lang.Object>", null),
+ myFactory.createTypeFromText("java.util.Set<? extends java.lang.Integer>", null));
+ }
+
+ public void testT55() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Set<java.lang.Object>", null),
+ myFactory.createTypeFromText("java.util.Set<?>", null));
+ }
+
+ //array index should be integer 56-57
+ public void testT56() {
+ doTestFirstParamType("foo", PsiType.INT, PsiType.DOUBLE);
+ }
+
+ public void testT57() {
+ doTestFirstParamType("foo", PsiType.INT, PsiType.BYTE);
+ }
+
+ //Arrays can be assignable to Object/Serializable/Cloneable 58-59; ~ 60 varargs
+ public void testT58() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testT59() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.lang.Cloneable", null));
+ }
+
+ public void testT60() {
+ doTestFieldType("p",
+ PsiType.INT.createArrayType(),
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ //change parameter type -> vararg; assignment changed to array
+ public void testT61() {
+ doTestFirstParamType("foo", PsiType.INT, new PsiEllipsisType(PsiType.INT));
+ }
+
+ //change field type -> change vararg parameter type due to assignment: 62-63
+ public void testT62() {
+ doTestFieldType("p", PsiType.INT.createArrayType(), myFactory.createTypeFromText(
+ CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testT63() {
+ doTestFieldType("p", PsiType.INT.createArrayType(), PsiType.DOUBLE.createArrayType());
+ }
+
+ //remove vararg type: 64-66
+ public void testT64() {
+ doTestFirstParamType("foo", new PsiEllipsisType(PsiType.INT), PsiType.INT);
+ }
+
+ public void testT65() {
+ doTestFirstParamType("foo",
+ new PsiEllipsisType(PsiType.INT),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT115() {
+ doTestFirstParamType("foo",
+ new PsiEllipsisType(myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null)),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.String", null)));
+ }
+
+ public void testT66() {
+ doTestFirstParamType("foo", new PsiEllipsisType(PsiType.INT), PsiType.INT);
+ }
+
+ public void testT67() {
+ doTestFirstParamType("methMemAcc",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT68() {
+ doTestFirstParamType("foo", PsiType.INT, PsiType.DOUBLE);
+ }
+
+ public void testT69() {
+ doTestFirstParamType("foo", PsiType.INT, PsiType.BYTE);
+ }
+
+ public void testT70() {
+ doTestFieldType("a", PsiType.INT.createArrayType().createArrayType(), PsiType.FLOAT.createArrayType().createArrayType());
+ }
+
+ public void testT71() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS, null),
+ myFactory.createTypeFromText("java.lang.Class<? extends java.lang.Number>", null));
+ }
+
+ public void testT72() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_CLASS, null),
+ myFactory.createTypeFromText("java.lang.Class<java.lang.Integer>", null));
+ }
+
+ public void testT73() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Set<javax.swing.JComponent>", null).createArrayType().createArrayType(),
+ myFactory.createTypeFromText("java.util.Set<java.awt.Component>", null).createArrayType().createArrayType());
+ }
+
+ //prefix/postfix expression; binary expressions 74-76
+ public void testT74() {
+ doTestFirstParamType("meth", PsiType.INT, PsiType.FLOAT);
+ }
+
+ public void testT75() {
+ doTestFirstParamType("meth", PsiType.INT, myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT76() {
+ doTestFirstParamType("meth", PsiType.BYTE, PsiType.FLOAT);
+ }
+
+ //+= , etc 77-78
+ public void testT77() {
+ doTestFirstParamType("meth", PsiType.INT, myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ public void testT78() {
+ doTestFirstParamType("meth", PsiType.INT, myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ //casts 79-80,83
+ public void testT79() {
+ doTestFirstParamType("meth", PsiType.INT, PsiType.BYTE);
+ }
+
+ public void testT80() {
+ doTestFirstParamType("meth", PsiType.INT, PsiType.DOUBLE);
+ }
+
+ public void testT83() {
+ doTestFirstParamType("meth", PsiType.INT, myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null));
+ }
+
+ //instanceofs 81-82
+ public void testT81() {
+ doTestFirstParamType("foo",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myFactory.createTypeFromText("A", null));
+ }
+
+ public void testT82() {
+ doTestFirstParamType("foo",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null),
+ myFactory.createTypeFromText("C", null));
+ }
+
+ public void testT84() {
+ doTestFirstParamType("meth",
+ myFactory.createTypeFromText(CommonClassNames.JAVA_UTIL_SET, null),
+ myFactory.createTypeFromText("java.util.Set<? extends java.util.Set>", null));
+ }
+
+ public void testT85() {
+ doTestFieldType("str",
+ myFactory.createTypeFromText("java.lang.String", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ //array <-> list 86-89;94;95
+ public void testT86() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ public void testT87() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT88() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ public void testT89() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT94() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ public void testT95() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+
+ public void testT90() {
+ doTestFieldType("l",
+ myFactory.createTypeFromText("java.util.List<B>", null),
+ myFactory.createTypeFromText("java.util.List<A>", null));
+ }
+
+ //element type -> element type array
+ public void testT91() {
+ doTestMethodType("foo",
+ myFactory.createTypeFromText("java.lang.String", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ //List<S>=new ArrayList<S>{}; -> List<I>=new ArrayList<I>{}; anonymous
+ public void testT92() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null));
+ }
+
+ //generics signature do not support primitives: Map<Boolean, String> - Map<boolean, String>
+ public void testT93() {
+ doTestFirstParamType("foo", myFactory.createTypeFromText("java.lang.Boolean", null), PsiType.BOOLEAN);
+ }
+
+ //field initializers procession
+ public void testT96() {
+ doTestFieldType("f1",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT97() {
+ doTestFieldType("f1", myFactory.createTypeFromText("java.lang.Integer", null).createArrayType(), PsiType.INT);
+ }
+
+ //list <-> array conversion in assignment statements
+ public void testT98() {
+ doTestMethodType("getArray",
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType(),
+ myFactory.createTypeFromText("java.util.List<java.lang.String>", null));
+ }
+
+ //escape pattern from []
+ public void testT99() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Set<java.util.List<char[]>>", null),
+ myFactory.createTypeFromText("java.util.Set<java.util.List<int[]>>", null));
+ }
+
+ //non formatted type
+ public void testT100() {
+ doTestFieldType("f",
+ myFactory.createTypeFromText("java.util.Map<java.lang.String,java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.Map<java.lang.String,java.lang.Integer>", null));
+ }
+
+ //param List -> Array[]
+ public void testT101() {
+ doTestFirstParamType("meth",
+ myFactory.createTypeFromText("java.util.List<java.util.ArrayList<java.lang.Integer>>", null),
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.Integer>[]", null));
+ }
+
+ //param Set.add() -> Array[] with conflict
+ public void testT102() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.Set<? extends java.lang.Object>", null),
+ myFactory.createTypeFromText("java.lang.Object[]", null));
+ }
+
+ //set(1, "") should be assignment-checked over String
+ public void testT103() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.String>", null),
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType());
+ }
+
+ //raw list type now should not be changed
+ public void testT104() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.ArrayList", null),
+ myFactory.createTypeFromText("java.lang.String", null).createArrayType());
+ }
+
+ //implicit type parameter change 105-107
+ public void testT105() {
+ doTestFieldType("t",
+ myFactory.createTypeFromText("T", null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+
+ public void testT106() {
+ doTestFieldType("t",
+ myFactory.createTypeFromText("T", null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT107() {
+ doTestFieldType("t",
+ myFactory.createTypeFromText("T", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ //foreach && wildcards: 108-110
+ public void testT108() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.List<? extends java.lang.Number>", null));
+ }
+
+ public void testT109() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.List<? super java.lang.Number>", null));
+ }
+
+ public void testT110() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null),
+ myFactory.createTypeFromText("java.util.List<? extends java.lang.String>", null));
+ }
+
+ //wrap with array creation only literals and refs outside of binary/unary expressions
+ public void testT111() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType());
+ }
+
+ public void testT112() {
+ doTestMethodType("method",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ myFactory.createTypeFromText("java.lang.Integer", null).createArrayType());
+ }
+
+ //varargs
+ public void testT113() {
+ doTestFirstParamType("method",
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.Integer", null)),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.Number", null)));
+ }
+
+ public void testT114() {
+ doTestFirstParamType("method",
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.Integer", null)),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.String", null)));
+ }
+
+ //varargs && ArrayList
+ public void testT118() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.Integer", null)));
+ }
+
+ //varargs && arrays
+ public void testT119() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.Integer", null)));
+ }
+
+ public void testT120() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.lang.Integer", null),
+ new PsiEllipsisType(myFactory.createTypeFromText("java.lang.String", null)));
+ }
+
+ //change parameter type in foreach statement: 116 - array, 117 - list
+ public void testT116() {
+ doTestFieldType("str",
+ myFactory.createTypeFromText("java.lang.Number", null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT117() {
+ doTestFieldType("str",
+ myFactory.createTypeFromText("java.lang.Number", null),
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+
+ public void testT121() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.Number>", null),
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.Float>", null));
+ }
+
+ public void testT122() {
+ doTestFirstParamType("method",
+ myFactory.createTypeFromText("java.util.List<java.util.ArrayList<java.lang.Integer>>", null),
+ myFactory.createTypeFromText("java.util.List<java.lang.Integer>", null).createArrayType());
+ }
+
+ public void testT123() {
+ doTestFieldType("n",
+ myFactory.createTypeFromText("java.lang.Number", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ //124,125 - do not change formal method return type
+ public void testT124() {
+ doTestFirstParamType("meth",
+ myFactory.createTypeFromText("T", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ public void testT125() {
+ doTestFirstParamType("meth",
+ myFactory.createTypeFromText("T", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ public void testT126() {
+ doTestMethodType("meth",
+ myFactory.createTypeFromText("java.lang.String", null),
+ myFactory.createTypeFromText("T", null));
+ }
+
+ // Checking preserving method parameters alignment
+ public void testT127() {
+ getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS = true;
+ getCurrentCodeStyleSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
+ doTestMethodType("test234",
+ myFactory.createTypeFromText("int", null),
+ myFactory.createTypeFromText("long", null));
+ }
+
+ // test type migration from disjunction type
+ public void testT128() {
+ doTestCatchParameter(myFactory.createTypeFromText("Test.E1 | Test.E2", null),
+ myFactory.createTypeFromText("Test.E", null));
+ }
+
+ // test type migration to disjunction type
+ public void testT129() {
+ doTestCatchParameter(myFactory.createTypeFromText("Test.E", null),
+ myFactory.createTypeFromText("Test.E1 | Test.E2", null));
+ }
+
+ // test type migration from disjunction type with interfaces
+ public void testT130() {
+ doTestCatchParameter(myFactory.createTypeFromText("Test.E1 | Test.E2", null),
+ myFactory.createTypeFromText("Test.E", null));
+ }
+
+ // test type migration between disjunction types
+ public void testT131() {
+ doTestCatchParameter(myFactory.createTypeFromText("Test.E1 | Test.E2", null),
+ myFactory.createTypeFromText("Test.E2 | Test.E1", null));
+ }
+
+ private void doTestCatchParameter(final PsiType rootType, final PsiType migrationType) {
+ start(new RulesProvider() {
+ @Override
+ public TypeMigrationRules provide() {
+ final TypeMigrationRules rules = new TypeMigrationRules(rootType);
+ rules.setMigrationRootType(migrationType);
+ return rules;
+ }
+
+ @Override
+ public PsiElement victims(final PsiClass aClass) {
+ final PsiCatchSection catchSection = PsiTreeUtil.findChildOfType(aClass, PsiCatchSection.class);
+ assert catchSection != null : aClass.getText();
+ final PsiParameter parameter = catchSection.getParameter();
+ assert parameter != null : catchSection.getText();
+ return parameter;
+ }
+ });
+ }
+
+ // IDEA-72420
+ public void testT132() {
+ doTestFirstParamType("h", "Test",
+ myFactory.createTypeFromText("J", null),
+ myFactory.createTypeFromText("I", null));
+ }
+
+ public void testT133() {
+ doTestFirstParamType("h", "Test",
+ myFactory.createTypeFromText("J", null),
+ myFactory.createTypeFromText("I", null));
+ }
+
+ public void testT134() {
+ doTestFirstParamType("buzz", "Test",
+ PsiType.INT,
+ myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT135() {
+ doTestFieldType("foo", "Test", PsiType.LONG, PsiType.INT);
+ }
+
+ public void testT136() {
+ final GlobalSearchScope scope = GlobalSearchScope.allScope(myProject);
+ doTestFirstParamType("foo", "Test",
+ myFactory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_INTEGER, scope),
+ PsiType.getJavaLangString(myPsiManager, scope));
+ }
+
+ public void testT137() {
+ doTestFirstParamType("foo", "Test", PsiType.INT, myFactory.createTypeFromText("java.lang.String", null));
+ }
+
+ public void testT138() {
+ doTestFirstParamType("foo", "Test",
+ myFactory.createTypeFromText("java.util.Set<java.lang.String>", null),
+ myFactory.createTypeFromText("java.util.Collection<java.lang.String>", null));
+ }
+
+ public void testT139() {
+ doTestForeachParameter(myFactory.createTypeFromText("java.lang.String", null),
+ myFactory.createTypeFromText("java.lang.Integer", null));
+ }
+
+ private void doTestForeachParameter(final PsiType rootType, final PsiType migrationType) {
+ start(new RulesProvider() {
+ @Override
+ public TypeMigrationRules provide() {
+ final TypeMigrationRules rules = new TypeMigrationRules(rootType);
+ rules.setMigrationRootType(migrationType);
+ return rules;
+ }
+
+ @Override
+ public PsiElement victims(final PsiClass aClass) {
+ final PsiForeachStatement foreachStatement = PsiTreeUtil.findChildOfType(aClass, PsiForeachStatement.class);
+ assert foreachStatement != null : aClass.getText();
+ return foreachStatement.getIterationParameter();
+ }
+ });
+ }
+
+
+ public void testTypeAnno() {
+ doTestFieldType("list", "Test",
+ myFactory.createTypeFromText("java.util.ArrayList<java.lang.@TA Integer>", null),
+ myFactory.createTypeFromText("java.util.Collection<java.lang.@TA Integer>", null));
+ }
+}
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTestBase.java b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTestBase.java
new file mode 100644
index 000000000000..8f75c4921a1c
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/TypeMigrationTestBase.java
@@ -0,0 +1,193 @@
+package com.intellij.refactoring;
+
+import com.intellij.openapi.application.PluginPathManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
+import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.usageView.UsageInfo;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+
+/**
+ * @author anna
+ * Date: 30-Apr-2008
+ */
+public abstract class TypeMigrationTestBase extends MultiFileTestCase {
+ @Override
+ protected String getTestDataPath() {
+ return PluginPathManager.getPluginHomePath("typeMigration") + "/testData";
+ }
+
+ protected void doTestFieldType(@NonNls String fieldName, PsiType fromType, PsiType toType) {
+ doTestFieldType(fieldName, "Test", fromType, toType);
+ }
+
+ protected void doTestFieldType(@NonNls final String fieldName, String className, final PsiType rootType, final PsiType migrationType) {
+ final RulesProvider provider = new RulesProvider() {
+ @Override
+ public TypeMigrationRules provide() throws Exception {
+ final TypeMigrationRules rules = new TypeMigrationRules(rootType);
+ rules.setMigrationRootType(migrationType);
+ return rules;
+ }
+
+ @Override
+ public PsiElement victims(PsiClass aClass) {
+ final PsiField field = aClass.findFieldByName(fieldName, false);
+ assert field != null : fieldName + " not found in " + aClass;
+ return field;
+ }
+ };
+
+ start(provider, className);
+ }
+
+ protected void doTestMethodType(@NonNls final String methodName, final PsiType rootType, final PsiType migrationType) {
+ doTestMethodType(methodName, "Test", rootType, migrationType);
+ }
+
+ protected void doTestMethodType(@NonNls final String methodName, @NonNls String className, final PsiType rootType, final PsiType migrationType) {
+ final RulesProvider provider = new RulesProvider() {
+ @Override
+ public TypeMigrationRules provide() throws Exception {
+ final TypeMigrationRules rules = new TypeMigrationRules(rootType);
+ rules.setMigrationRootType(migrationType);
+ return rules;
+ }
+
+ @Override
+ public PsiElement victims(PsiClass aClass) {
+ return aClass.findMethodsByName(methodName, false)[0];
+ }
+ };
+
+ start(provider, className);
+ }
+
+ protected void doTestFirstParamType(@NonNls final String methodName, final PsiType rootType, final PsiType migrationType) {
+ doTestFirstParamType(methodName, "Test", rootType, migrationType);
+ }
+
+ protected void doTestFirstParamType(@NonNls final String methodName, String className, final PsiType rootType, final PsiType migrationType) {
+ final RulesProvider provider = new RulesProvider() {
+ @Override
+ public TypeMigrationRules provide() throws Exception {
+ final TypeMigrationRules rules = new TypeMigrationRules(rootType);
+ rules.setMigrationRootType(migrationType);
+ return rules;
+ }
+
+ @Override
+ public PsiElement victims(PsiClass aClass) {
+ return aClass.findMethodsByName(methodName, false)[0].getParameterList().getParameters()[0];
+ }
+ };
+
+ start(provider, className);
+ }
+
+ public void start(final RulesProvider provider) {
+ start(provider, "Test");
+ }
+
+ public void start(final RulesProvider provider, final String className) {
+ doTest(new PerformAction() {
+ @Override
+ public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
+ TypeMigrationTestBase.this.performAction(className, rootDir.getName(), provider);
+ }
+ });
+ }
+
+ private void performAction(String className, String rootDir, RulesProvider provider) throws Exception {
+ PsiClass aClass = myJavaFacade.findClass(className, GlobalSearchScope.allScope(getProject()));
+
+ assertNotNull("Class " + className + " not found", aClass);
+
+ final TypeMigrationRules rules = provider.provide();
+ rules.setBoundScope(new LocalSearchScope(aClass.getContainingFile()));
+ final TestTypeMigrationProcessor pr = new TestTypeMigrationProcessor(getProject(), provider.victims(aClass), rules);
+
+ final UsageInfo[] usages = pr.findUsages();
+ final String report = pr.getLabeler().getMigrationReport();
+
+ WriteCommandAction.runWriteCommandAction(null, new Runnable() {
+ public void run() {
+ pr.performRefactoring(usages);
+ }
+ });
+
+
+ String itemName = className + ".items";
+ String patternName = getTestDataPath() + getTestRoot() + getTestName(true) + "/after/" + itemName;
+
+ File patternFile = new File(patternName);
+
+ if (!patternFile.exists()) {
+ PrintWriter writer = new PrintWriter(new FileOutputStream(patternFile));
+ try {
+ writer.print(report);
+ writer.close();
+ }
+ finally {
+ writer.close();
+ }
+
+ System.out.println("Pattern not found, file " + patternName + " created.");
+
+ LocalFileSystem.getInstance().refreshAndFindFileByIoFile(patternFile);
+ }
+
+ File graFile = new File(FileUtil.getTempDirectory() + File.separator + rootDir + File.separator + itemName);
+
+ PrintWriter writer = new PrintWriter(new FileOutputStream(graFile));
+ try {
+ writer.print(report);
+ writer.close();
+ }
+ finally {
+ writer.close();
+ }
+
+ LocalFileSystem.getInstance().refreshAndFindFileByIoFile(graFile);
+ FileDocumentManager.getInstance().saveAllDocuments();
+ }
+
+ interface RulesProvider {
+ TypeMigrationRules provide() throws Exception;
+
+ PsiElement victims(PsiClass aClass);
+ }
+
+ private static class TestTypeMigrationProcessor extends TypeMigrationProcessor {
+ public TestTypeMigrationProcessor(final Project project, final PsiElement root, final TypeMigrationRules rules) {
+ super(project, root, rules);
+ }
+
+ @NotNull
+ @Override
+ public UsageInfo[] findUsages() {
+ return super.findUsages();
+ }
+
+ @Override
+ public void performRefactoring(final UsageInfo[] usages) {
+ super.performRefactoring(usages);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/test/com/intellij/refactoring/WildcardTypeMigrationTest.java b/plugins/typeMigration/test/com/intellij/refactoring/WildcardTypeMigrationTest.java
new file mode 100644
index 000000000000..d66320623f83
--- /dev/null
+++ b/plugins/typeMigration/test/com/intellij/refactoring/WildcardTypeMigrationTest.java
@@ -0,0 +1,170 @@
+/*
+ * User: anna
+ * Date: 19-Aug-2009
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.CommonClassNames;
+import org.jetbrains.annotations.NotNull;
+
+public class WildcardTypeMigrationTest extends TypeMigrationTestBase{
+ @NotNull
+ @Override
+ protected String getTestRoot() {
+ return "/refactoring/wildcard/";
+ }
+
+ public void testProducerExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Number>", null));
+ }
+
+ public void testProducerSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Integer>", null));
+ }
+
+ public void testProducerUnbounded() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<?>", null));
+ }
+
+ public void testProducerCollectionChanged() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? super java.lang.Integer>", null));
+ }
+
+ public void testProducerExtendsCollectionChanged() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.Set<? extends java.lang.Object>", null));
+ }
+
+ public void testProducerStopAtWildcard() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<? super java.lang.Number>", null));
+ }
+
+ public void testProducerFailToStopAtWildcard() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<? super java.lang.Integer>", null));
+ }
+
+ public void testProducerExtendsFailToStopAtWildcard() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<? super java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<? extends java.lang.Number>", null));
+ }
+
+
+ public void testConsumerExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Number>", null));
+ }
+
+ public void testConsumerSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Number>", null));
+ }
+
+ public void testConsumerUnbounded() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<?>", null));
+ }
+
+ // array -> list
+ public void testAssignmentExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Integer>", null));
+ }
+
+ public void testAssignmentSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Integer>", null));
+ }
+
+ public void testAssignmentUnbounded() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<?>", null));
+ }
+
+ public void testGetExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Integer>", null));
+ }
+
+ public void testGetSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? super java.lang.Integer>", null));
+ }
+
+ public void testGetUnbounded() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<?>", null));
+
+ }
+
+ public void testLengthSize() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType(),
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<?>", null));
+
+ }
+
+ //list -> array
+ public void testGetAssignmentExtendsToType() throws Exception {
+ doTestFirstParamType("method", myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Number", null).createArrayType());
+ }
+
+ public void testGetAssignmentExtendsToSuperType() throws Exception {
+ doTestFirstParamType("method", myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, null).createArrayType());
+ }
+
+ public void testGetAssignmentExtendsToChildType() throws Exception {
+ doTestFirstParamType("method", myJavaFacade.getElementFactory().createTypeFromText("java.util.ArrayList<? extends java.lang.Number>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.Integer", null).createArrayType());
+ }
+
+ // -> threadlocal with wildcard
+ public void testThreadLocalProducerExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<java.lang.String>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<java.util.List<? extends String>>", null));
+ }
+
+ //List<? super String> is not assignable to List<String> though it is possible to pass string where ? super String was
+ public void _testThreadLocalProducerSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.util.List<java.lang.String>", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<java.util.List<? super String>>", null));
+ }
+
+ public void testThreadLocalConsumerSuper() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<? super String>", null));
+ }
+
+ public void testThreadLocalConsumerExtends() throws Exception {
+ doTestFirstParamType("method",
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.String", null),
+ myJavaFacade.getElementFactory().createTypeFromText("java.lang.ThreadLocal<? extends String>", null));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after1.java b/plugins/typeMigration/testData/intentions/atomic/after1.java
new file mode 100644
index 000000000000..853f715fd8c4
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after1.java
@@ -0,0 +1,9 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicIntegerArray field= new AtomicIntegerArray(foo());
+ int[] foo() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after10.java b/plugins/typeMigration/testData/intentions/atomic/after10.java
new file mode 100644
index 000000000000..685e3fb710e2
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after10.java
@@ -0,0 +1,10 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger o = new AtomicInteger(0);
+
+ void foo() {
+ boolean b = this.o.get() == 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after12.java b/plugins/typeMigration/testData/intentions/atomic/after12.java
new file mode 100644
index 000000000000..8accafd9fa10
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after12.java
@@ -0,0 +1,12 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+
+ {
+ AtomicInteger i = new AtomicInteger(0);
+ Integer j = 0;
+
+ assert j == i.get();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after13.java b/plugins/typeMigration/testData/intentions/atomic/after13.java
new file mode 100644
index 000000000000..dea58d02e88c
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after13.java
@@ -0,0 +1,6 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger i = new AtomicInteger(0);
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after14.java b/plugins/typeMigration/testData/intentions/atomic/after14.java
new file mode 100644
index 000000000000..6109d4106e9b
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after14.java
@@ -0,0 +1,10 @@
+import java.util.concurrent.atomic.AtomicLong;
+
+// "Convert to atomic" "true"
+class T {
+ private final AtomicLong l = new AtomicLong(10L);
+
+ public synchronized void update(long m) {
+ l.set(m);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after2.java b/plugins/typeMigration/testData/intentions/atomic/after2.java
new file mode 100644
index 000000000000..2c2ad94beeb0
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after2.java
@@ -0,0 +1,9 @@
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicReferenceArray<Object> field= new AtomicReferenceArray<>(foo());
+ Object[] foo() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after3.java b/plugins/typeMigration/testData/intentions/atomic/after3.java
new file mode 100644
index 000000000000..505349d5dc36
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after3.java
@@ -0,0 +1,7 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicIntegerArray field= new AtomicIntegerArray(new int[]{1});
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after4.java b/plugins/typeMigration/testData/intentions/atomic/after4.java
new file mode 100644
index 000000000000..e268b2604404
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after4.java
@@ -0,0 +1,9 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger i = new AtomicInteger(0);
+
+ int j = i.get() + 5;
+ String s = "i = " + i.get();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after5.java b/plugins/typeMigration/testData/intentions/atomic/after5.java
new file mode 100644
index 000000000000..82ff84c68e75
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after5.java
@@ -0,0 +1,9 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger i = new AtomicInteger(0 + 8);
+
+ int j = i.get() + 5;
+ String s = "i = " + i.get();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after6.java b/plugins/typeMigration/testData/intentions/atomic/after6.java
new file mode 100644
index 000000000000..f0120300e0f9
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after6.java
@@ -0,0 +1,6 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicIntegerArray i = new AtomicIntegerArray(new int[0]);
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after7.java b/plugins/typeMigration/testData/intentions/atomic/after7.java
new file mode 100644
index 000000000000..19336f0bc61b
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after7.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger o = new AtomicInteger(0);
+ int j = o.get();
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after8.java b/plugins/typeMigration/testData/intentions/atomic/after8.java
new file mode 100644
index 000000000000..bdfbd5b03a4d
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after8.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger o = new AtomicInteger();
+ int j = o.get();
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/after9.java b/plugins/typeMigration/testData/intentions/atomic/after9.java
new file mode 100644
index 000000000000..c462a10961d4
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/after9.java
@@ -0,0 +1,15 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicInteger o;
+ int j = o.get();
+
+ Test(int o) {
+ this.o = new AtomicInteger(o);
+ }
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/afterExcl.java b/plugins/typeMigration/testData/intentions/atomic/afterExcl.java
new file mode 100644
index 000000000000..72f91198ce3d
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/afterExcl.java
@@ -0,0 +1,9 @@
+import java.util.concurrent.atomic.AtomicBoolean;
+
+// "Convert to atomic" "true"
+class Test {
+ final AtomicBoolean field= new AtomicBoolean(false);
+ {
+ boolean b = !field.get();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/afterTA1.java b/plugins/typeMigration/testData/intentions/atomic/afterTA1.java
new file mode 100644
index 000000000000..a90ed666ea30
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/afterTA1.java
@@ -0,0 +1,10 @@
+// "Convert to atomic" "true"
+import java.lang.annotation.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { int value(); }
+
+class T {
+ final AtomicReference<@TA(42) String> v = new AtomicReference<String>();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before1.java b/plugins/typeMigration/testData/intentions/atomic/before1.java
new file mode 100644
index 000000000000..d3b926f29fb3
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before1.java
@@ -0,0 +1,7 @@
+// "Convert to atomic" "true"
+class Test {
+ int[] <caret>field=foo();
+ int[] foo() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before10.java b/plugins/typeMigration/testData/intentions/atomic/before10.java
new file mode 100644
index 000000000000..a4e7c9db6b75
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before10.java
@@ -0,0 +1,8 @@
+// "Convert to atomic" "true"
+class Test {
+ final int <caret>o = 0;
+
+ void foo() {
+ boolean b = this.o == 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before11.java b/plugins/typeMigration/testData/intentions/atomic/before11.java
new file mode 100644
index 000000000000..b1abb55f9503
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before11.java
@@ -0,0 +1,8 @@
+// "Convert to atomic" "false"
+class Test {
+ void foo() {
+ try (AutoCloseable <caret>r = null) {
+ System.out.println(r);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before12.java b/plugins/typeMigration/testData/intentions/atomic/before12.java
new file mode 100644
index 000000000000..2c634df22c2f
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before12.java
@@ -0,0 +1,10 @@
+// "Convert to atomic" "true"
+class Test {
+
+ {
+ int <caret>i = 0;
+ Integer j = 0;
+
+ assert j == i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before13.java b/plugins/typeMigration/testData/intentions/atomic/before13.java
new file mode 100644
index 000000000000..179e2b165252
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before13.java
@@ -0,0 +1,4 @@
+// "Convert to atomic" "true"
+class Test {
+ volatile int <caret>i = 0;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before14.java b/plugins/typeMigration/testData/intentions/atomic/before14.java
new file mode 100644
index 000000000000..042b4c4dd2a1
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before14.java
@@ -0,0 +1,8 @@
+// "Convert to atomic" "true"
+class T {
+ private long <caret>l = 10L;
+
+ public synchronized void update(long m) {
+ l = m;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before2.java b/plugins/typeMigration/testData/intentions/atomic/before2.java
new file mode 100644
index 000000000000..d33fffc40e20
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before2.java
@@ -0,0 +1,7 @@
+// "Convert to atomic" "true"
+class Test {
+ Object[] <caret>field=foo();
+ Object[] foo() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before3.java b/plugins/typeMigration/testData/intentions/atomic/before3.java
new file mode 100644
index 000000000000..661dbdd63fb2
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before3.java
@@ -0,0 +1,5 @@
+// "Convert to atomic" "true"
+class Test {
+ int[] <caret>field= new int[]{1};
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before4.java b/plugins/typeMigration/testData/intentions/atomic/before4.java
new file mode 100644
index 000000000000..ecf4b985a5d2
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before4.java
@@ -0,0 +1,7 @@
+// "Convert to atomic" "true"
+class Test {
+ int <caret>i = 0;
+
+ int j = i + 5;
+ String s = "i = " + i;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before5.java b/plugins/typeMigration/testData/intentions/atomic/before5.java
new file mode 100644
index 000000000000..7ace336aa8be
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before5.java
@@ -0,0 +1,7 @@
+// "Convert to atomic" "true"
+class Test {
+ int <caret>i = 0 + 8;
+
+ int j = i + 5;
+ String s = "i = " + i;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before6.java b/plugins/typeMigration/testData/intentions/atomic/before6.java
new file mode 100644
index 000000000000..abc59802e025
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before6.java
@@ -0,0 +1,4 @@
+// "Convert to atomic" "true"
+class Test {
+ int[] <caret>i = new int[0];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before7.java b/plugins/typeMigration/testData/intentions/atomic/before7.java
new file mode 100644
index 000000000000..fd2d066a4337
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before7.java
@@ -0,0 +1,9 @@
+// "Convert to atomic" "true"
+class Test {
+ int <caret>o = 0;
+ int j = o;
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before8.java b/plugins/typeMigration/testData/intentions/atomic/before8.java
new file mode 100644
index 000000000000..d2ef50810f7e
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before8.java
@@ -0,0 +1,9 @@
+// "Convert to atomic" "true"
+class Test {
+ int <caret>o;
+ int j = o;
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/before9.java b/plugins/typeMigration/testData/intentions/atomic/before9.java
new file mode 100644
index 000000000000..a9f693800f81
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/before9.java
@@ -0,0 +1,13 @@
+// "Convert to atomic" "true"
+class Test {
+ final int <caret>o;
+ int j = o;
+
+ Test(int o) {
+ this.o = o;
+ }
+
+ void foo() {
+ while ((o = j) != 0) {}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/beforeExcl.java b/plugins/typeMigration/testData/intentions/atomic/beforeExcl.java
new file mode 100644
index 000000000000..3df455583c35
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/beforeExcl.java
@@ -0,0 +1,7 @@
+// "Convert to atomic" "true"
+class Test {
+ boolean <caret>field=false;
+ {
+ boolean b = !field;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/atomic/beforeTA1.java b/plugins/typeMigration/testData/intentions/atomic/beforeTA1.java
new file mode 100644
index 000000000000..10bdd5df4822
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/atomic/beforeTA1.java
@@ -0,0 +1,9 @@
+// "Convert to atomic" "true"
+import java.lang.annotation.*;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { int value(); }
+
+class T {
+ @TA(42) String <caret>v;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after1.java b/plugins/typeMigration/testData/intentions/threadLocal/after1.java
new file mode 100644
index 000000000000..b5df8fd35214
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after1.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<Integer> field = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return 0;
+ }
+ };
+ void foo() {
+ field.set(field.get() + 1);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after2.java b/plugins/typeMigration/testData/intentions/threadLocal/after2.java
new file mode 100644
index 000000000000..3a546c5b0c9a
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after2.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<String> field = new ThreadLocal<String>() {
+ @Override
+ protected String initialValue() {
+ return "";
+ }
+ };
+ void foo() {
+ System.out.println(field.get());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after3.java b/plugins/typeMigration/testData/intentions/threadLocal/after3.java
new file mode 100644
index 000000000000..9fc0f825ac4b
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after3.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<Integer> field = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return new Integer(0);
+ }
+ };
+ void foo() {
+ if (field.get() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after4.java b/plugins/typeMigration/testData/intentions/threadLocal/after4.java
new file mode 100644
index 000000000000..8410a1c33c0e
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after4.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<String> field = new ThreadLocal<String>() {
+ @Override
+ protected String initialValue() {
+ return "";
+ }
+ };
+ void foo() {
+ if (field.get().indexOf("a") == -1) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after5.java b/plugins/typeMigration/testData/intentions/threadLocal/after5.java
new file mode 100644
index 000000000000..435e1b6a50e6
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after5.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ final ThreadLocal<Integer> field = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return new Integer(0);
+ }
+ };
+ void foo(Test t) {
+ if (t.field.get() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after6.java b/plugins/typeMigration/testData/intentions/threadLocal/after6.java
new file mode 100644
index 000000000000..1879a46be16d
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after6.java
@@ -0,0 +1,12 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ static final ThreadLocal<Integer> field;
+ static {
+ field = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return new Integer(0);
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after7.java b/plugins/typeMigration/testData/intentions/threadLocal/after7.java
new file mode 100644
index 000000000000..5398ff5e2991
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after7.java
@@ -0,0 +1,15 @@
+// "Convert to ThreadLocal" "true"
+class X {
+ private final ThreadLocal<byte[]> bytes = new ThreadLocal<byte[]>() {
+ @Override
+ protected byte[] initialValue() {
+ return new byte[10];
+ }
+ };
+
+ byte foo(byte b) {
+ bytes.get()[0] = 1;
+ foo(bytes.get()[1])
+ return bytes.get()[2];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/after8.java b/plugins/typeMigration/testData/intentions/threadLocal/after8.java
new file mode 100644
index 000000000000..d158894b6130
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/after8.java
@@ -0,0 +1,9 @@
+// "Convert to ThreadLocal" "true"
+class X {
+ final ThreadLocal<Integer> i = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return 0;
+ }
+ };
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/afterTA1.java b/plugins/typeMigration/testData/intentions/threadLocal/afterTA1.java
new file mode 100644
index 000000000000..0e3687e146b6
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/afterTA1.java
@@ -0,0 +1,14 @@
+// "Convert to ThreadLocal" "true"
+import java.lang.annotation.*;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { int value(); }
+
+class Test {
+ final ThreadLocal<@TA(42) Integer> field = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return 0;
+ }
+ };
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before1.java b/plugins/typeMigration/testData/intentions/threadLocal/before1.java
new file mode 100644
index 000000000000..e35925390137
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before1.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ int <caret>field=0;
+ void foo() {
+ field++;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before2.java b/plugins/typeMigration/testData/intentions/threadLocal/before2.java
new file mode 100644
index 000000000000..47c6471739d7
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before2.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ String <caret>field="";
+ void foo() {
+ System.out.println(field);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before3.java b/plugins/typeMigration/testData/intentions/threadLocal/before3.java
new file mode 100644
index 000000000000..19d296cffa36
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before3.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ Integer <caret>field=new Integer(0);
+ void foo() {
+ if (field == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before4.java b/plugins/typeMigration/testData/intentions/threadLocal/before4.java
new file mode 100644
index 000000000000..66d2efa6230a
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before4.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ String <caret>field="";
+ void foo() {
+ if (field.indexOf("a") == -1) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before5.java b/plugins/typeMigration/testData/intentions/threadLocal/before5.java
new file mode 100644
index 000000000000..c459443241e4
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before5.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ Integer <caret>field=new Integer(0);
+ void foo(Test t) {
+ if (t.field == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before6.java b/plugins/typeMigration/testData/intentions/threadLocal/before6.java
new file mode 100644
index 000000000000..74427e6e4f06
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before6.java
@@ -0,0 +1,7 @@
+// "Convert to ThreadLocal" "true"
+class Test {
+ static final Integer <caret>field;
+ static {
+ field = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before7.java b/plugins/typeMigration/testData/intentions/threadLocal/before7.java
new file mode 100644
index 000000000000..dfff0417b272
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before7.java
@@ -0,0 +1,10 @@
+// "Convert to ThreadLocal" "true"
+class X {
+ private final byte[] <caret>bytes = new byte[10];
+
+ byte foo(byte b) {
+ bytes[0] = 1;
+ foo(bytes[1])
+ return bytes[2];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/before8.java b/plugins/typeMigration/testData/intentions/threadLocal/before8.java
new file mode 100644
index 000000000000..af321e0da56c
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/before8.java
@@ -0,0 +1,4 @@
+// "Convert to ThreadLocal" "true"
+class X {
+ volatile int <caret>i = 0;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/intentions/threadLocal/beforeTA1.java b/plugins/typeMigration/testData/intentions/threadLocal/beforeTA1.java
new file mode 100644
index 000000000000..ac3409c2e759
--- /dev/null
+++ b/plugins/typeMigration/testData/intentions/threadLocal/beforeTA1.java
@@ -0,0 +1,9 @@
+// "Convert to ThreadLocal" "true"
+import java.lang.annotation.*;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { int value(); }
+
+class Test {
+ @TA(42) int <caret>field = 0;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java
new file mode 100644
index 000000000000..051e42810e3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java
@@ -0,0 +1,9 @@
+import java.util.List;
+class A<T> {
+ List<T> getKey(){return null;}
+}
+public class B extends A<S<caret>tring> {
+ List<String> getKey() {
+ return new List<String>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java.after
new file mode 100644
index 000000000000..8966bc1ee03d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/CompositeReturnType.java.after
@@ -0,0 +1,9 @@
+import java.util.List;
+class A<T> {
+ List<T> getKey(){return null;}
+}
+public class B extends A<Object> {
+ List<Object> getKey() {
+ return new List<>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java
new file mode 100644
index 000000000000..fabb24302b8d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java
@@ -0,0 +1,12 @@
+class Test {
+ interface A<T> {
+ void foo(T t);
+ }
+
+ class B implements A<Inte<caret>ger> {
+ Integer str;
+ public void foo(Integer s) {
+ str = s;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java.after
new file mode 100644
index 000000000000..01a6bf49322e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldTypeMigration.java.after
@@ -0,0 +1,12 @@
+class Test {
+ interface A<T> {
+ void foo(T t);
+ }
+
+ class B implements A<String> {
+ String str;
+ public void foo(String s) {
+ str = s;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java
new file mode 100644
index 000000000000..92864f163560
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java
@@ -0,0 +1,16 @@
+import java.util.List;
+
+class A<T> {
+ T t;
+ List<T> list = new List<T>();
+}
+
+class B extends A<S<caret>tring> {
+ void foo() {
+ if (t == null) return;
+ if (list == null) return;
+ for (String s : list) {
+ //do nothing
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java.after
new file mode 100644
index 000000000000..07ee7a4e9351
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage.java.after
@@ -0,0 +1,16 @@
+import java.util.List;
+
+class A<T> {
+ T t;
+ List<T> list = new List<T>();
+}
+
+class B extends A<Object> {
+ void foo() {
+ if (t == null) return;
+ if (list == null) return;
+ for (Object s : list) {
+ //do nothing
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java
new file mode 100644
index 000000000000..bff01e33a9e3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java
@@ -0,0 +1,17 @@
+import java.util.*;
+
+class A<T> {
+ protected T t;
+ protected List<T> list = new ArrayList<T>();
+}
+
+public class B extends A<S<caret>tring> {
+ void foo() {
+ if (t == null) return;
+ if (list == null) return;
+ System.out.println(t);
+ for (String s : list) {
+ //do nothing
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java.after
new file mode 100644
index 000000000000..b3764fda80de
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/FieldUsage1.java.after
@@ -0,0 +1,17 @@
+import java.util.*;
+
+class A<T> {
+ protected T t;
+ protected List<T> list = new ArrayList<T>();
+}
+
+public class B extends A<Object> {
+ void foo() {
+ if (t == null) return;
+ if (list == null) return;
+ System.out.println(t);
+ for (Object s : list) {
+ //do nothing
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java
new file mode 100644
index 000000000000..98b178156750
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java
@@ -0,0 +1,4 @@
+import java.util.List;
+class ListTypeArguments implements List<I<caret>nteger> {
+ public boolean add(Integer o){return true;}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java.after
new file mode 100644
index 000000000000..535acf216d57
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ListTypeArguments.java.after
@@ -0,0 +1,4 @@
+import java.util.List;
+class ListTypeArguments implements List<Object> {
+ public boolean add(Object o){return true;}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java
new file mode 100644
index 000000000000..8183831c3ff3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java
@@ -0,0 +1,16 @@
+class Test {
+ interface A<T> {
+ T foo();
+ }
+
+ class B implements A<Stri<caret>ng> {
+ public String foo() {
+ return null;
+ }
+
+ public void bar() {
+ String s = foo();
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java.after
new file mode 100644
index 000000000000..405cd8a74384
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/MethodReturnTypeMigration.java.after
@@ -0,0 +1,16 @@
+class Test {
+ interface A<T> {
+ T foo();
+ }
+
+ class B implements A<Integer> {
+ public Integer foo() {
+ return null;
+ }
+
+ public void bar() {
+ Integer s = foo();
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java
new file mode 100644
index 000000000000..fdce63b995a8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java
@@ -0,0 +1,29 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){}
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Strin<caret>g> {
+ void foo(String s) {
+ f(s);
+ }
+
+ public void main() {
+ for (String integer : l) {
+
+ }
+ }
+
+ void bar(Map<String, String> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java.after
new file mode 100644
index 000000000000..ff031aa42904
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration.java.after
@@ -0,0 +1,29 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){}
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Object> {
+ void foo(String s) {
+ f(s);
+ }
+
+ public void main() {
+ for (Object integer : l) {
+
+ }
+ }
+
+ void bar(Map<Object, Object> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java
new file mode 100644
index 000000000000..fdce63b995a8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java
@@ -0,0 +1,29 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){}
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Strin<caret>g> {
+ void foo(String s) {
+ f(s);
+ }
+
+ public void main() {
+ for (String integer : l) {
+
+ }
+ }
+
+ void bar(Map<String, String> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java.after
new file mode 100644
index 000000000000..f3cef5b65bba
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration1.java.after
@@ -0,0 +1,29 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){}
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Integer> {
+ void foo(Integer s) {
+ f(s);
+ }
+
+ public void main() {
+ for (Integer integer : l) {
+
+ }
+ }
+
+ void bar(Map<Integer, Integer> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java
new file mode 100644
index 000000000000..278b80eb95d5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java
@@ -0,0 +1,31 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){
+ for (T t1 : t.keySet()) {}
+ }
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Strin<caret>g> {
+ void foo(String s) {
+ f(s);
+ }
+
+ public void main() {
+ for (String integer : l) {
+
+ }
+ }
+
+ void bar(Map<String, String> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java.after
new file mode 100644
index 000000000000..5978a88ee283
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ParameterMigration2.java.after
@@ -0,0 +1,31 @@
+import java.util.*;
+
+class Test {
+ class C<T> {
+ List<T> l;
+
+ void bar(Map<T, T> t){
+ for (T t1 : t.keySet()) {}
+ }
+
+ void f(T t){}
+
+ }
+
+ class D extends C<Integer> {
+ void foo(Integer s) {
+ f(s);
+ }
+
+ public void main() {
+ for (Integer integer : l) {
+
+ }
+ }
+
+ void bar(Map<Integer, Integer> t) {
+ super.bar(t);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java
new file mode 100644
index 000000000000..416bf0f810b8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java
@@ -0,0 +1,16 @@
+class A<T> {
+ void foo(T t){}
+ void bar(T t, int i){}
+}
+
+class B extends A<S<caret>tring>{
+ void foo(String t) {
+ super.foo(t);
+ }
+
+ void bar(String t, int i){
+ foo(t);
+ int k = i;
+ super.bar(t, k);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java.after
new file mode 100644
index 000000000000..64847ab2afd1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter.java.after
@@ -0,0 +1,16 @@
+class A<T> {
+ void foo(T t){}
+ void bar(T t, int i){}
+}
+
+class B extends A<Object> {
+ void foo(Object t) {
+ super.foo(t);
+ }
+
+ void bar(Object t, int i){
+ foo(t);
+ int k = i;
+ super.bar(t, k);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java
new file mode 100644
index 000000000000..f9bdb275f3aa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java
@@ -0,0 +1,20 @@
+class A<T> {
+ void foo(T t){}
+ void bar(T t, int i){}
+}
+
+class B extends A<S<caret>tring>{
+ void foo(String t) {
+ super.foo(t);
+ }
+
+ void bar(String t, int i){
+ foo(t);
+ int k = i;
+ super.bar(t, k);
+ }
+
+ void bar1(String s) {
+ foo(s);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java.after
new file mode 100644
index 000000000000..1777cb6da9d8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter1.java.after
@@ -0,0 +1,20 @@
+class A<T> {
+ void foo(T t){}
+ void bar(T t, int i){}
+}
+
+class B extends A<Integer> {
+ void foo(Integer t) {
+ super.foo(t);
+ }
+
+ void bar(Integer t, int i){
+ foo(t);
+ int k = i;
+ super.bar(t, k);
+ }
+
+ void bar1(Integer s) {
+ foo(s);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java
new file mode 100644
index 000000000000..62c7cf4da263
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java
@@ -0,0 +1,12 @@
+class A<T> {
+ T bar(){}
+}
+
+class B extends A<S<caret>tring>{
+ void barInner(String s) {
+ }
+
+ void foo() {
+ barInner(bar());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java.after
new file mode 100644
index 000000000000..e5ed5910c2c1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/PassedParameter2.java.after
@@ -0,0 +1,12 @@
+class A<T> {
+ T bar(){}
+}
+
+class B extends A<Object> {
+ void barInner(Object s) {
+ }
+
+ void foo() {
+ barInner(bar());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java
new file mode 100644
index 000000000000..17960b186a46
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java
@@ -0,0 +1,14 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+class B extends A<S<caret>tring> {
+ String foo(){return null;}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java.after
new file mode 100644
index 000000000000..1758610f1571
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType.java.after
@@ -0,0 +1,14 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+class B extends A<Object> {
+ Object foo(){return null;}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java
new file mode 100644
index 000000000000..9e01a295be05
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java
@@ -0,0 +1,15 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+public class B extends A<S<caret>tring> {
+ String foo(){return null;}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ System.out.println(foo());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java.after
new file mode 100644
index 000000000000..8a584bdca610
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType1.java.after
@@ -0,0 +1,15 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+public class B extends A<Object> {
+ Object foo(){return null;}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ System.out.println(foo());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java
new file mode 100644
index 000000000000..83b7294972fc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java
@@ -0,0 +1,14 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+class B extends A<S<caret>tring> {
+ String foo(){return super.foo();}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java.after
new file mode 100644
index 000000000000..a26f7d3f1655
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/ReturnType2.java.after
@@ -0,0 +1,14 @@
+class A<T> {
+ T foo(){
+ return null;
+ }
+}
+
+class B extends A<Object> {
+ Object foo(){return super.foo();}
+
+ void bar() {
+ foo();
+ if (foo() == null) return;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java
new file mode 100644
index 000000000000..2bfa264828c0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java
@@ -0,0 +1,18 @@
+abstract class A<E> {
+ abstract E foo();
+}
+
+abstract class B<T> extends A<T> {
+}
+
+class C extends B<S<caret>tring> {
+ String foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {
+ //do smth
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java.after
new file mode 100644
index 000000000000..4c4736302857
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy.java.after
@@ -0,0 +1,18 @@
+abstract class A<E> {
+ abstract E foo();
+}
+
+abstract class B<T> extends A<T> {
+}
+
+class C extends B<Object> {
+ Object foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {
+ //do smth
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java
new file mode 100644
index 000000000000..5396a7c59422
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java
@@ -0,0 +1,19 @@
+abstract class A<E> {
+ public abstract E foo();
+}
+
+abstract class B<T> extends A<T> {
+}
+
+public class C extends B<S<caret>tring> {
+ public String foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {
+ //do smth
+ }
+ System.out.println(foo());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java.after
new file mode 100644
index 000000000000..16a02ae4ea3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy1.java.after
@@ -0,0 +1,19 @@
+abstract class A<E> {
+ public abstract E foo();
+}
+
+abstract class B<T> extends A<T> {
+}
+
+public class C extends B<Object> {
+ public Object foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {
+ //do smth
+ }
+ System.out.println(foo());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java
new file mode 100644
index 000000000000..2eb6d429915e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java
@@ -0,0 +1,18 @@
+public class Test extends B<S<caret>tring>{
+ String foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {}
+ }
+}
+
+abstract class A<T> {
+ abstract T foo();
+}
+
+abstract class B<E extends Object> extends A<E> {
+}
+
+
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java.after
new file mode 100644
index 000000000000..b30ab01e5594
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchy2.java.after
@@ -0,0 +1,18 @@
+public class Test extends B<Object> {
+ Object foo() {
+ return null;
+ }
+
+ void bar() {
+ if (foo() == null) {}
+ }
+}
+
+abstract class A<T> {
+ abstract T foo();
+}
+
+abstract class B<E extends Object> extends A<E> {
+}
+
+
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java
new file mode 100644
index 000000000000..3bf853421127
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java
@@ -0,0 +1,15 @@
+import java.util.List;
+class A<E> {
+ E e;
+ List<E> list = new List<E>();
+}
+
+class B<T> extends A<T> {}
+
+class C extends B <S<caret>tring> {
+ void foo() {
+ if (e == null && list != null) {
+ //do smth
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java.after
new file mode 100644
index 000000000000..5eeea8234a2e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsage.java.after
@@ -0,0 +1,15 @@
+import java.util.List;
+class A<E> {
+ E e;
+ List<E> list = new List<E>();
+}
+
+class B<T> extends A<T> {}
+
+class C extends B<Object> {
+ void foo() {
+ if (e == null && list != null) {
+ //do smth
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java
new file mode 100644
index 000000000000..bf9237fe6fb3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java
@@ -0,0 +1,16 @@
+import java.util.List;
+class A<E> {
+ E e;
+ List<E> list = new List<E>();
+}
+
+class B<T> extends A<T> {}
+
+class C extends B <S<caret>tring> {
+ void foo() {
+ if (e == null && list != null) {
+ for (String s : list) {
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java.after
new file mode 100644
index 000000000000..ffecf75c7f20
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/TypeHierarchyFieldUsageConflict.java.after
@@ -0,0 +1,16 @@
+import java.util.List;
+class A<E> {
+ E e;
+ List<E> list = new List<E>();
+}
+
+class B<T> extends A<T> {}
+
+class C extends B<Object> {
+ void foo() {
+ if (e == null && list != null) {
+ for (Object s : list) {
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java b/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java
new file mode 100644
index 000000000000..4cbee666c3cb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java
@@ -0,0 +1,9 @@
+class A<T> {
+ T foo(){return null;}
+ T bar(){return foo();}
+}
+
+class B extends A<S<caret>tring> {
+ String foo(){return super.bar();}
+ String bar(){return super.foo();}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java.after b/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java.after
new file mode 100644
index 000000000000..d321e6520dc0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/changeTypeSignature/UsedInSuper.java.after
@@ -0,0 +1,9 @@
+class A<T> {
+ T foo(){return null;}
+ T bar(){return foo();}
+}
+
+class B extends A<Object> {
+ Object foo(){return super.bar();}
+ Object bar(){return super.foo();}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.items
new file mode 100644
index 000000000000..7ce904f6afe4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.items
@@ -0,0 +1,33 @@
+Types:
+PsiField:myForAccess : ClassParent
+PsiLocalVariable:vf : ClassParent
+PsiLocalVariable:vfcthis : ClassParent
+PsiLocalVariable:vfnew : ClassParent
+PsiLocalVariable:vfparen : ClassParent
+PsiLocalVariable:vfthis : ClassParent
+PsiLocalVariable:vm : ClassParent
+PsiLocalVariable:vmcthis : ClassParent
+PsiLocalVariable:vmnew : ClassParent
+PsiLocalVariable:vmparen : ClassParent
+PsiLocalVariable:vmthis : ClassParent
+PsiMethod:forAccess : ClassParent
+PsiMethodCallExpression:(this).forAccess() : ClassParent
+PsiMethodCallExpression:Expr.this.forAccess() : ClassParent
+PsiMethodCallExpression:forAccess() : ClassParent
+PsiMethodCallExpression:forAccess() : ClassParent
+PsiMethodCallExpression:forAccess() : ClassParent
+PsiMethodCallExpression:new Expr().forAccess() : ClassParent
+PsiMethodCallExpression:this.forAccess() : ClassParent
+PsiReferenceExpression:(this).myForAccess : ClassParent
+PsiReferenceExpression:Expr.this.myForAccess : ClassParent
+PsiReferenceExpression:myForAccess : ClassParent
+PsiReferenceExpression:myForAccess : ClassParent
+PsiReferenceExpression:new Expr().myForAccess : ClassParent
+PsiReferenceExpression:this.myForAccess : ClassParent
+
+Conversions:
+
+New expression type changes:
+Fails:
+forAccess()->ClassParent
+forAccess()->ClassParent
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..65fd52a3e86e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/after/Expr.java
@@ -0,0 +1,35 @@
+class ClassParent {}
+class ClassChild extends ClassParent {
+ public void forAccess2() {
+ }
+
+ public int myForAccess;
+}
+class ClassGrandChild extends ClassChild {}
+
+class Expr {
+ public ClassParent myForAccess;
+ public ClassParent forAccess() {
+ return myForAccess;
+ }
+
+ public void methMemAcc() {
+ ClassParent vf = myForAccess;
+ ClassParent vm = forAccess();
+
+ ClassParent vfthis = this.myForAccess;
+ ClassParent vmthis = this.forAccess();
+
+ ClassParent vfcthis = Expr.this.myForAccess;
+ ClassParent vmcthis = Expr.this.forAccess();
+
+ ClassParent vfparen = (this).myForAccess;
+ ClassParent vmparen = (this).forAccess();
+
+ ClassParent vfnew = new Expr().myForAccess;
+ ClassParent vmnew = new Expr().forAccess();
+
+ int v = forAccess().myForAccess;
+ forAccess().forAccess2();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..1c13032fa121
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Lvalue/before/Expr.java
@@ -0,0 +1,35 @@
+class ClassParent {}
+class ClassChild extends ClassParent {
+ public void forAccess2() {
+ }
+
+ public int myForAccess;
+}
+class ClassGrandChild extends ClassChild {}
+
+class Expr {
+ public ClassChild myForAccess;
+ public ClassChild forAccess() {
+ return myForAccess;
+ }
+
+ public void methMemAcc() {
+ ClassChild vf = myForAccess;
+ ClassChild vm = forAccess();
+
+ ClassChild vfthis = this.myForAccess;
+ ClassChild vmthis = this.forAccess();
+
+ ClassChild vfcthis = Expr.this.myForAccess;
+ ClassChild vmcthis = Expr.this.forAccess();
+
+ ClassChild vfparen = (this).myForAccess;
+ ClassChild vmparen = (this).forAccess();
+
+ ClassChild vfnew = new Expr().myForAccess;
+ ClassChild vmnew = new Expr().forAccess();
+
+ int v = forAccess().myForAccess;
+ forAccess().forAccess2();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..d79df57fc220
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.items
@@ -0,0 +1,37 @@
+Types:
+PsiField:myField : ClassGrandChild
+PsiField:myForAccess1 : ClassGrandChild
+PsiField:myForAccess2 : ClassGrandChild
+PsiField:myForAccess3 : ClassGrandChild
+PsiField:myForAccess4 : ClassGrandChild
+PsiField:myForAccess5 : ClassGrandChild
+PsiMethod:forAccess1 : ClassGrandChild
+PsiMethod:forAccess2 : ClassGrandChild
+PsiMethod:forAccess3 : ClassGrandChild
+PsiMethod:forAccess4 : ClassGrandChild
+PsiMethod:forAccess5 : ClassGrandChild
+PsiMethodCallExpression:(this).forAccess4() : ClassGrandChild
+PsiMethodCallExpression:Expr.this.forAccess3() : ClassGrandChild
+PsiMethodCallExpression:forAccess1() : ClassGrandChild
+PsiMethodCallExpression:new Expr().forAccess5() : ClassGrandChild
+PsiMethodCallExpression:this.forAccess2() : ClassGrandChild
+PsiReferenceExpression:(this).myForAccess4 : ClassGrandChild
+PsiReferenceExpression:Expr.this.myForAccess3 : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myForAccess1 : ClassGrandChild
+PsiReferenceExpression:new Expr().myForAccess5 : ClassGrandChild
+PsiReferenceExpression:this.myForAccess2 : ClassGrandChild
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..11599a2cd3a6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/after/Expr.java
@@ -0,0 +1,54 @@
+class ClassParent {}
+class ClassChild extends ClassParent {
+ public void forAccess2() {
+ }
+
+ public int myForAccess;
+}
+class ClassGrandChild extends ClassChild {}
+
+class Expr {
+ private ClassGrandChild myField;
+
+ public ClassGrandChild myForAccess1;
+ public ClassGrandChild forAccess1() {
+ return null;
+ }
+
+ public ClassGrandChild myForAccess2;
+ public ClassGrandChild forAccess2() {
+ return null;
+ }
+
+ public ClassGrandChild myForAccess3;
+ public ClassGrandChild forAccess3() {
+ return null;
+ }
+
+ public ClassGrandChild myForAccess4;
+ public ClassGrandChild forAccess4() {
+ return null;
+ }
+
+ public ClassGrandChild myForAccess5;
+ public ClassGrandChild forAccess5() {
+ return null;
+ }
+
+ public void methMemAcc() {
+ myField = myForAccess1;
+ myField = forAccess1();
+
+ myField = this.myForAccess2;
+ myField = this.forAccess2();
+
+ myField = Expr.this.myForAccess3;
+ myField = Expr.this.forAccess3();
+
+ myField = (this).myForAccess4;
+ myField = (this).forAccess4();
+
+ myField = new Expr().myForAccess5;
+ myField = new Expr().forAccess5();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..64998cf198c8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccess2Rvalue/before/Expr.java
@@ -0,0 +1,54 @@
+class ClassParent {}
+class ClassChild extends ClassParent {
+ public void forAccess2() {
+ }
+
+ public int myForAccess;
+}
+class ClassGrandChild extends ClassChild {}
+
+class Expr {
+ private ClassChild myField;
+
+ public ClassChild myForAccess1;
+ public ClassChild forAccess1() {
+ return null;
+ }
+
+ public ClassChild myForAccess2;
+ public ClassChild forAccess2() {
+ return null;
+ }
+
+ public ClassChild myForAccess3;
+ public ClassChild forAccess3() {
+ return null;
+ }
+
+ public ClassChild myForAccess4;
+ public ClassChild forAccess4() {
+ return null;
+ }
+
+ public ClassChild myForAccess5;
+ public ClassChild forAccess5() {
+ return null;
+ }
+
+ public void methMemAcc() {
+ myField = myForAccess1;
+ myField = forAccess1();
+
+ myField = this.myForAccess2;
+ myField = this.forAccess2();
+
+ myField = Expr.this.myForAccess3;
+ myField = Expr.this.forAccess3();
+
+ myField = (this).myForAccess4;
+ myField = (this).forAccess4();
+
+ myField = new Expr().myForAccess5;
+ myField = new Expr().forAccess5();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Ession.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Ession.items
new file mode 100644
index 000000000000..15e80380b536
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Ession.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myForSuperAccess : ClassParent
+PsiLocalVariable:vfcsuper : ClassParent
+PsiLocalVariable:vfsuper : ClassParent
+PsiLocalVariable:vmcsuper : ClassParent
+PsiLocalVariable:vmsuper : ClassParent
+PsiMethod:forSuperAccess : ClassParent
+PsiMethodCallExpression:Expr.super.forSuperAccess() : ClassParent
+PsiMethodCallExpression:super.forSuperAccess() : ClassParent
+PsiReferenceExpression:Expr.super.myForSuperAccess : ClassParent
+PsiReferenceExpression:myForSuperAccess : ClassParent
+PsiReferenceExpression:super.myForSuperAccess : ClassParent
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..3a9531d8f9d8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/after/Expr.java
@@ -0,0 +1,20 @@
+class ClassParent {}
+class ClassChild extends ClassParent {}
+class ClassGrandChild extends ClassChild {}
+
+class Ession {
+ public ClassParent myForSuperAccess;
+ public ClassParent forSuperAccess() {
+ return myForSuperAccess;
+ }
+}
+
+class Expr extends Ession {
+ public void methMemAcc() {
+ ClassParent vfsuper = super.myForSuperAccess;
+ ClassParent vmsuper = super.forSuperAccess();
+
+ ClassParent vfcsuper = Expr.super.myForSuperAccess;
+ ClassParent vmcsuper = Expr.super.forSuperAccess();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..898b41a6ab6f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Lvalue/before/Expr.java
@@ -0,0 +1,20 @@
+class ClassParent {}
+class ClassChild extends ClassParent {}
+class ClassGrandChild extends ClassChild {}
+
+class Ession {
+ public ClassChild myForSuperAccess;
+ public ClassChild forSuperAccess() {
+ return myForSuperAccess;
+ }
+}
+
+class Expr extends Ession {
+ public void methMemAcc() {
+ ClassChild vfsuper = super.myForSuperAccess;
+ ClassChild vmsuper = super.forSuperAccess();
+
+ ClassChild vfcsuper = Expr.super.myForSuperAccess;
+ ClassChild vmcsuper = Expr.super.forSuperAccess();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..95bf149e7b68
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.items
@@ -0,0 +1,19 @@
+Types:
+PsiField:myField : ClassGrandChild
+PsiField:myForSuperAccess1 : ClassGrandChild
+PsiField:myForSuperAccess2 : ClassGrandChild
+PsiMethod:forSuperAccess1 : ClassGrandChild
+PsiMethod:forSuperAccess2 : ClassGrandChild
+PsiMethodCallExpression:Expr.super.forSuperAccess2() : ClassGrandChild
+PsiMethodCallExpression:super.forSuperAccess1() : ClassGrandChild
+PsiReferenceExpression:Expr.super.myForSuperAccess2 : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:myField : ClassGrandChild
+PsiReferenceExpression:super.myForSuperAccess1 : ClassGrandChild
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..9ffe2e3a7332
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/after/Expr.java
@@ -0,0 +1,26 @@
+class ClassParent {}
+class ClassChild extends ClassParent {}
+class ClassGrandChild extends ClassChild {}
+
+class Ession {
+ public ClassGrandChild myForSuperAccess1;
+ public ClassGrandChild forSuperAccess1() {
+ return null;
+ }
+
+ public ClassGrandChild myForSuperAccess2;
+ public ClassGrandChild forSuperAccess2() {
+ return null;
+ }
+}
+
+class Expr extends Ession {
+ private ClassGrandChild myField;
+ public void methMemAcc() {
+ myField = super.myForSuperAccess1;
+ myField = super.forSuperAccess1();
+
+ myField = Expr.super.myForSuperAccess2;
+ myField = Expr.super.forSuperAccess2();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..0a244c6448bd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprAccessParent2Rvalue/before/Expr.java
@@ -0,0 +1,26 @@
+class ClassParent {}
+class ClassChild extends ClassParent {}
+class ClassGrandChild extends ClassChild {}
+
+class Ession {
+ public ClassChild myForSuperAccess1;
+ public ClassChild forSuperAccess1() {
+ return null;
+ }
+
+ public ClassChild myForSuperAccess2;
+ public ClassChild forSuperAccess2() {
+ return null;
+ }
+}
+
+class Expr extends Ession {
+ private ClassChild myField;
+ public void methMemAcc() {
+ myField = super.myForSuperAccess1;
+ myField = super.forSuperAccess1();
+
+ myField = Expr.super.myForSuperAccess2;
+ myField = Expr.super.forSuperAccess2();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.items
new file mode 100644
index 000000000000..0f10ca83564b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : double
+PsiReferenceExpression:p : double
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->double
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.java
new file mode 100644
index 000000000000..9258f512d2b1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/after/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ public void meth(double p) {
+ String[] sa = new String[]{"0", "1"};
+ String s = sa[p];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/before/Expr.java
new file mode 100644
index 000000000000..57fde1c6b34c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessNegative/before/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ public void meth(int p) {
+ String[] sa = new String[]{"0", "1"};
+ String s = sa[p];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.items
new file mode 100644
index 000000000000..afc565fc6df7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : char
+PsiReferenceExpression:p : char
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.java
new file mode 100644
index 000000000000..7971b5e9e770
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/after/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ public void meth(char p) {
+ String[] sa = new String[]{"0", "1"};
+ String s = sa[p];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/before/Expr.java
new file mode 100644
index 000000000000..57fde1c6b34c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprArrayAccessPositive/before/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ public void meth(int p) {
+ String[] sa = new String[]{"0", "1"};
+ String s = sa[p];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.items
new file mode 100644
index 000000000000..4e6bf57cbb3e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.items
@@ -0,0 +1,30 @@
+Types:
+PsiLocalVariable:vba : int
+PsiLocalVariable:vbb : int
+PsiLocalVariable:vbc : int
+PsiParameter:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+PsiReferenceExpression:pb : int
+
+Conversions:
+
+New expression type changes:
+Fails:
+pb->int
+pb->int
+pb->int
+pb->int
+pb->int
+pb->int
+pb->int
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.java
new file mode 100644
index 000000000000..d0dd0e83a559
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/after/Expr.java
@@ -0,0 +1,16 @@
+class Expr {
+ public void meth(int pb) {
+ int vba = pb & pb;
+ int vbb = pb ^ pb;
+ int vbc = pb | pb;
+ boolean vbd = pb && pb;
+ boolean vbe = pb || pb;
+
+ boolean vn1 = false;
+ vn1 &= pb;
+ boolean vn2 = false;
+ vn2 ^= pb;
+ boolean vn3 = false;
+ vn3 |= pb;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/before/Expr.java
new file mode 100644
index 000000000000..d0364a40ca25
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanBoolean/before/Expr.java
@@ -0,0 +1,16 @@
+class Expr {
+ public void meth(boolean pb) {
+ boolean vba = pb & pb;
+ boolean vbb = pb ^ pb;
+ boolean vbc = pb | pb;
+ boolean vbd = pb && pb;
+ boolean vbe = pb || pb;
+
+ boolean vn1 = false;
+ vn1 &= pb;
+ boolean vn2 = false;
+ vn2 ^= pb;
+ boolean vn3 = false;
+ vn3 |= pb;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.items
new file mode 100644
index 000000000000..21ecfb0d65a5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.items
@@ -0,0 +1,19 @@
+Types:
+PsiParameter:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+PsiReferenceExpression:pi : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
+pi->java.lang.Object
+pi->java.lang.Object
+pi->java.lang.Object
+pi->java.lang.Object
+pi->java.lang.Object
+pi->java.lang.Object
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.java
new file mode 100644
index 000000000000..c54d809c3906
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/after/Expr.java
@@ -0,0 +1,10 @@
+class Expr {
+ public void meth(Object pi) {
+ boolean vb1 = pi > 0;
+ boolean vb2 = pi >= 0;
+ boolean vb3 = pi < 0;
+ boolean vb4 = pi <= 0;
+ boolean vb6 = pi == 0;
+ boolean vb7 = pi != 0;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/before/Expr.java
new file mode 100644
index 000000000000..1b113b43a3e6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanNumeric/before/Expr.java
@@ -0,0 +1,10 @@
+class Expr {
+ public void meth(int pi) {
+ boolean vb1 = pi > 0;
+ boolean vb2 = pi >= 0;
+ boolean vb3 = pi < 0;
+ boolean vb4 = pi <= 0;
+ boolean vb6 = pi == 0;
+ boolean vb7 = pi != 0;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.items
new file mode 100644
index 000000000000..815d62ca7530
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:ps : double
+PsiReferenceExpression:ps : double
+PsiReferenceExpression:ps : double
+PsiReferenceExpression:ps : double
+PsiReferenceExpression:ps : double
+
+Conversions:
+
+New expression type changes:
+Fails:
+ps->double
+ps->double
+ps->double
+ps->double
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.java
new file mode 100644
index 000000000000..bc4c04967759
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/after/Expr.java
@@ -0,0 +1,8 @@
+class Expr {
+ public void meth(double ps) {
+ boolean vb5 = ps instanceof CharSequence;
+ boolean vb8 = ps == "string";
+ boolean vb9 = ps != "string";
+ boolean vbf = (1 >= 0) && (ps instanceof CharSequence);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/before/Expr.java
new file mode 100644
index 000000000000..6def87eb9709
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcBooleanReference/before/Expr.java
@@ -0,0 +1,8 @@
+class Expr {
+ public void meth(String ps) {
+ boolean vb5 = ps instanceof CharSequence;
+ boolean vb8 = ps == "string";
+ boolean vb9 = ps != "string";
+ boolean vbf = (1 >= 0) && (ps instanceof CharSequence);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.items
new file mode 100644
index 000000000000..aeddc71515d9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.items
@@ -0,0 +1,58 @@
+Types:
+PsiLocalVariable:vb9 : boolean
+PsiLocalVariable:vba : boolean
+PsiLocalVariable:vbb : boolean
+PsiParameter:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+PsiReferenceExpression:p : boolean
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
+p->boolean
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.java
new file mode 100644
index 000000000000..c90c55120370
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/after/Expr.java
@@ -0,0 +1,35 @@
+class Expr {
+ public void meth(boolean p) {
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ int vb4 = p + p;
+ int vb5 = p - p;
+ boolean vb9 = p & p;
+ boolean vba = p ^ p;
+ boolean vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ int vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/before/Expr.java
new file mode 100644
index 000000000000..057b284248a0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Boolean/before/Expr.java
@@ -0,0 +1,35 @@
+class Expr {
+ public void meth(int p) {
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ int vb4 = p + p;
+ int vb5 = p - p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ int vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.items
new file mode 100644
index 000000000000..0fdb9d1291e9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.items
@@ -0,0 +1,78 @@
+Types:
+PsiLocalVariable:vb1 : float
+PsiLocalVariable:vb2 : float
+PsiLocalVariable:vb3 : float
+PsiLocalVariable:vb4 : float
+PsiLocalVariable:vb5 : float
+PsiLocalVariable:vn1 : float
+PsiLocalVariable:vn2 : float
+PsiLocalVariable:vn3 : float
+PsiLocalVariable:vn4 : float
+PsiLocalVariable:vn5 : float
+PsiLocalVariable:vu1 : float
+PsiLocalVariable:vu2 : float
+PsiLocalVariable:vu3 : float
+PsiLocalVariable:vu4 : float
+PsiLocalVariable:vu5 : float
+PsiLocalVariable:vu6 : float
+PsiParameter:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:vn1 : float
+PsiReferenceExpression:vn2 : float
+PsiReferenceExpression:vn3 : float
+PsiReferenceExpression:vn4 : float
+PsiReferenceExpression:vn5 : float
+
+Conversions:
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+
+New expression type changes:
+Fails:
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
+p->float
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.java
new file mode 100644
index 000000000000..8e16d5b5d974
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/after/Expr.java
@@ -0,0 +1,42 @@
+class Expr {
+ public void meth(float p) {
+ float vu1 = p++;
+ float vu2 = p--;
+ float vu3 = ++p;
+ float vu4 = --p;
+ float vu5 = -p;
+ float vu6 = +p;
+
+ float vb1 = p * p;
+ float vb2 = p / p;
+ float vb3 = p % p;
+ float vb4 = p + p;
+ float vb5 = p - p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ float vn1 = 0;
+ vn1 *= p;
+ float vn2 = 0;
+ vn2 /= p;
+ float vn3 = 0;
+ vn3 %= p;
+ float vn4 = 0;
+ vn4 += p;
+ float vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/before/Expr.java
new file mode 100644
index 000000000000..4088b28a0060
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Floating/before/Expr.java
@@ -0,0 +1,42 @@
+class Expr {
+ public void meth(int p) {
+ int vu1 = p++;
+ int vu2 = p--;
+ int vu3 = ++p;
+ int vu4 = --p;
+ int vu5 = -p;
+ int vu6 = +p;
+
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ int vb4 = p + p;
+ int vb5 = p - p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ int vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.items
new file mode 100644
index 000000000000..36e79ff677b4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.items
@@ -0,0 +1,98 @@
+Types:
+PsiLocalVariable:vb1 : long
+PsiLocalVariable:vb2 : long
+PsiLocalVariable:vb3 : long
+PsiLocalVariable:vb4 : long
+PsiLocalVariable:vb5 : long
+PsiLocalVariable:vb6 : long
+PsiLocalVariable:vb7 : long
+PsiLocalVariable:vb8 : long
+PsiLocalVariable:vb9 : long
+PsiLocalVariable:vba : long
+PsiLocalVariable:vbb : long
+PsiLocalVariable:vn1 : long
+PsiLocalVariable:vn2 : long
+PsiLocalVariable:vn3 : long
+PsiLocalVariable:vn4 : long
+PsiLocalVariable:vn5 : long
+PsiLocalVariable:vn6 : long
+PsiLocalVariable:vn7 : long
+PsiLocalVariable:vn8 : long
+PsiLocalVariable:vn9 : long
+PsiLocalVariable:vna : long
+PsiLocalVariable:vnb : long
+PsiLocalVariable:vu1 : long
+PsiLocalVariable:vu2 : long
+PsiLocalVariable:vu3 : long
+PsiLocalVariable:vu4 : long
+PsiLocalVariable:vu5 : long
+PsiLocalVariable:vu6 : long
+PsiLocalVariable:vu7 : long
+PsiParameter:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:vn1 : long
+PsiReferenceExpression:vn2 : long
+PsiReferenceExpression:vn3 : long
+PsiReferenceExpression:vn4 : long
+PsiReferenceExpression:vn5 : long
+PsiReferenceExpression:vn6 : long
+PsiReferenceExpression:vn7 : long
+PsiReferenceExpression:vn8 : long
+PsiReferenceExpression:vn9 : long
+PsiReferenceExpression:vna : long
+PsiReferenceExpression:vnb : long
+
+Conversions:
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+0 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.java
new file mode 100644
index 000000000000..323dad23d5d3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/after/Expr.java
@@ -0,0 +1,46 @@
+class Expr {
+ public void meth(long p) {
+ long vu1 = p++;
+ long vu2 = p--;
+ long vu3 = ++p;
+ long vu4 = --p;
+ long vu5 = -p;
+ long vu6 = +p;
+ long vu7 = ~p;
+
+ long vb1 = p * p;
+ long vb2 = p / p;
+ long vb3 = p % p;
+ long vb4 = p + p;
+ long vb5 = p - p;
+ long vb6 = p << p;
+ long vb7 = p >> p;
+ long vb8 = p >>> p;
+ long vb9 = p & p;
+ long vba = p ^ p;
+ long vbb = p | p;
+
+ long vn1 = 0;
+ vn1 *= p;
+ long vn2 = 0;
+ vn2 /= p;
+ long vn3 = 0;
+ vn3 %= p;
+ long vn4 = 0;
+ vn4 += p;
+ long vn5 = 0;
+ vn5 -= p;
+ long vn6 = 0;
+ vn6 <<= p;
+ long vn7 = 0;
+ vn7 >>= p;
+ long vn8 = 0;
+ vn8 >>>= p;
+ long vn9 = 0;
+ vn9 &= p;
+ long vna = 0;
+ vna ^= p;
+ long vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/before/Expr.java
new file mode 100644
index 000000000000..716f4b7e60e1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2Int/before/Expr.java
@@ -0,0 +1,46 @@
+class Expr {
+ public void meth(int p) {
+ int vu1 = p++;
+ int vu2 = p--;
+ int vu3 = ++p;
+ int vu4 = --p;
+ int vu5 = -p;
+ int vu6 = +p;
+ int vu7 = ~p;
+
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ int vb4 = p + p;
+ int vb5 = p - p;
+ int vb6 = p << p;
+ int vb7 = p >> p;
+ int vb8 = p >>> p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ int vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.items
new file mode 100644
index 000000000000..406008949bd1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.items
@@ -0,0 +1,62 @@
+Types:
+PsiLocalVariable:vb4 : java.lang.String
+PsiLocalVariable:vn4 : java.lang.String
+PsiParameter:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:vn4 : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+0->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
+p->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.java
new file mode 100644
index 000000000000..62fd2ff0b0ff
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/after/Expr.java
@@ -0,0 +1,35 @@
+class Expr {
+ public void meth(String p) {
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ String vb4 = p + p;
+ int vb5 = p - p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ String vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/before/Expr.java
new file mode 100644
index 000000000000..057b284248a0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCalcNumeric2String/before/Expr.java
@@ -0,0 +1,35 @@
+class Expr {
+ public void meth(int p) {
+ int vb1 = p * p;
+ int vb2 = p / p;
+ int vb3 = p % p;
+ int vb4 = p + p;
+ int vb5 = p - p;
+ int vb9 = p & p;
+ int vba = p ^ p;
+ int vbb = p | p;
+
+ int vn1 = 0;
+ vn1 *= p;
+ int vn2 = 0;
+ vn2 /= p;
+ int vn3 = 0;
+ vn3 %= p;
+ int vn4 = 0;
+ vn4 += p;
+ int vn5 = 0;
+ vn5 -= p;
+ int vn6 = 0;
+ vn6 <<= p;
+ int vn7 = 0;
+ vn7 >>= p;
+ int vn8 = 0;
+ vn8 >>>= p;
+ int vn9 = 0;
+ vn9 &= p;
+ int vna = 0;
+ vna ^= p;
+ int vnb = 0;
+ vnb |= p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.items
new file mode 100644
index 000000000000..01f325b2852d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+(short) p->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.java
new file mode 100644
index 000000000000..5a7343152288
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/after/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(String p) {
+ short v = (short) p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/before/Expr.java
new file mode 100644
index 000000000000..e3519b4bb4bf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvalueNeg/before/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(byte p) {
+ short v = (short) p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.items
new file mode 100644
index 000000000000..f69d09024863
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : int
+PsiReferenceExpression:p : int
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.java
new file mode 100644
index 000000000000..64aecc896b80
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/after/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(int p) {
+ short v = (short) p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/before/Expr.java
new file mode 100644
index 000000000000..e3519b4bb4bf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprCast2LvaluePos/before/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(byte p) {
+ short v = (short) p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.items
new file mode 100644
index 000000000000..0b73994dece5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:pns : java.lang.Object
+PsiReferenceExpression:pns : java.lang.Object
+PsiReferenceExpression:pns : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.java
new file mode 100644
index 000000000000..cf844f4eddf2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/after/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(Object pns, String ps) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/before/Expr.java
new file mode 100644
index 000000000000..71b89f955e59
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2Reference/before/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(int pns, String ps) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.items
new file mode 100644
index 000000000000..46d6b1f5a15f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:pns : java.lang.String
+PsiReferenceExpression:pns : java.lang.String
+PsiReferenceExpression:pns : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.java
new file mode 100644
index 000000000000..5ce2b795d268
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/after/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(String pns, String ps) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/before/Expr.java
new file mode 100644
index 000000000000..71b89f955e59
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatNumeric2String/before/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(int pns, String ps) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.items
new file mode 100644
index 000000000000..3bb9c1ebf19a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myString : int
+PsiParameter:ps : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:ps : int
+PsiReferenceExpression:ps : int
+PsiReferenceExpression:ps : int
+PsiReferenceExpression:ps : int
+PsiReferenceExpression:ps : int
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.java
new file mode 100644
index 000000000000..ac05959f3c08
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/after/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private int myString;
+ public void meth(int ps, int pns) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/before/Expr.java
new file mode 100644
index 000000000000..bb57398b961c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Numeric/before/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(String ps, int pns) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.items
new file mode 100644
index 000000000000..302e3c9da48c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.items
@@ -0,0 +1,23 @@
+Types:
+PsiField:myString : int
+PsiParameter:ps : java.lang.Object
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:myString : int
+PsiReferenceExpression:ps : java.lang.Object
+PsiReferenceExpression:ps : java.lang.Object
+PsiReferenceExpression:ps : java.lang.Object
+PsiReferenceExpression:ps : java.lang.Object
+PsiReferenceExpression:ps : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
+myString->int
+ps->java.lang.Object
+ps->java.lang.Object
+ps->java.lang.Object
+ps->java.lang.Object
+ps->java.lang.Object
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.java
new file mode 100644
index 000000000000..c23893bd5b63
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/after/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private int myString;
+ public void meth(Object ps, int pns) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/before/Expr.java
new file mode 100644
index 000000000000..bb57398b961c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprConcatString2Reference/before/Expr.java
@@ -0,0 +1,9 @@
+class Expr {
+ private String myString;
+ public void meth(String ps, int pns) {
+ myString = ps + ps;
+ myString = ps + pns;
+ myString = pns + ps;
+ myString += ps;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.items
new file mode 100644
index 000000000000..7712b490ec9a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.List
+PsiReferenceExpression:p : java.util.List
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->java.util.List
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.java
new file mode 100644
index 000000000000..93da179e0c37
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/after/Expr.java
@@ -0,0 +1,9 @@
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+class Expr {
+ public void meth(List p) {
+ boolean b = p instanceof HashSet;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/before/Expr.java
new file mode 100644
index 000000000000..72af0a04ab0b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofNeg/before/Expr.java
@@ -0,0 +1,9 @@
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+class Expr {
+ public void meth(Set p) {
+ boolean b = p instanceof HashSet;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.items
new file mode 100644
index 000000000000..5b608c5c0b1a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : java.util.AbstractMap
+PsiReferenceExpression:p : java.util.AbstractMap
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.java
new file mode 100644
index 000000000000..e7f8a225bd9e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/after/Expr.java
@@ -0,0 +1,9 @@
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+
+class Expr {
+ public void meth(AbstractMap p) {
+ boolean b = p instanceof HashMap;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/before/Expr.java
new file mode 100644
index 000000000000..fa8ab953a084
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprInstanceofPos/before/Expr.java
@@ -0,0 +1,9 @@
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+
+class Expr {
+ public void meth(Map p) {
+ boolean b = p instanceof HashMap;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.items
new file mode 100644
index 000000000000..b446d1101a06
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.items
@@ -0,0 +1,35 @@
+Types:
+PsiField:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:myField : boolean
+
+Conversions:
+
+New expression type changes:
+Fails:
+"#"->boolean
+'#'->boolean
+043->boolean
+043F->boolean
+043L->boolean
+0x23->boolean
+0x23F->boolean
+0x23L->boolean
+35->boolean
+35.0->boolean
+35F->boolean
+35L->boolean
+null->boolean
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.java
new file mode 100644
index 000000000000..d0d0a2d12326
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private boolean myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralBoolean/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.items
new file mode 100644
index 000000000000..efc0c3bb0c41
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.items
@@ -0,0 +1,37 @@
+Types:
+PsiField:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
+"#"->byte
+'#'->byte
+043->byte
+043F->byte
+043L->byte
+0x23->byte
+0x23F->byte
+0x23L->byte
+35->byte
+35.0->byte
+35F->byte
+35L->byte
+false->byte
+null->byte
+true->byte
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.java
new file mode 100644
index 000000000000..6288f06f450a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private byte myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralByte/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.items
new file mode 100644
index 000000000000..62960ffeacf8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.items
@@ -0,0 +1,36 @@
+Types:
+PsiField:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+
+Conversions:
+
+New expression type changes:
+Fails:
+"#"->char
+043->char
+043F->char
+043L->char
+0x23->char
+0x23F->char
+0x23L->char
+35->char
+35.0->char
+35F->char
+35L->char
+false->char
+null->char
+true->char
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.java
new file mode 100644
index 000000000000..eab5b7cf5059
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private char myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralChar/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.items
new file mode 100644
index 000000000000..2a1f903ca5ab
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myField : java.lang.Class<? extends java.util.Collection[]>
+PsiReferenceExpression:myField : java.lang.Class<? extends java.util.Collection[]>
+PsiReferenceExpression:myField : java.lang.Class<? extends java.util.Collection[]>
+PsiReferenceExpression:myField : java.lang.Class<? extends java.util.Collection[]>
+PsiReferenceExpression:myField : java.lang.Class<? extends java.util.Collection[]>
+PsiReferenceExpression:myField : java.lang.Class<? extends java.util.Collection[]>
+
+Conversions:
+Set[].class -> $
+
+New expression type changes:
+Fails:
+Set.class->java.lang.Class<? extends java.util.Collection[]>
+int.class->java.lang.Class<? extends java.util.Collection[]>
+int[].class->java.lang.Class<? extends java.util.Collection[]>
+void.class->java.lang.Class<? extends java.util.Collection[]>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.java
new file mode 100644
index 000000000000..a9f761e2bd1f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/after/Expr.java
@@ -0,0 +1,13 @@
+import java.util.Collection;
+import java.util.Set;
+
+class Expr {
+ private Class<? extends Collection[]> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/before/Expr.java
new file mode 100644
index 000000000000..202ef9ef2da6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassExtends/before/Expr.java
@@ -0,0 +1,13 @@
+import java.util.Collection;
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.items
new file mode 100644
index 000000000000..485a0f5d91a4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : java.lang.Class<java.lang.Integer>
+PsiReferenceExpression:myField : java.lang.Class<java.lang.Integer>
+PsiReferenceExpression:myField : java.lang.Class<java.lang.Integer>
+PsiReferenceExpression:myField : java.lang.Class<java.lang.Integer>
+PsiReferenceExpression:myField : java.lang.Class<java.lang.Integer>
+PsiReferenceExpression:myField : java.lang.Class<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+Fails:
+Set.class->java.lang.Class<java.lang.Integer>
+Set[].class->java.lang.Class<java.lang.Integer>
+int[].class->java.lang.Class<java.lang.Integer>
+void.class->java.lang.Class<java.lang.Integer>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.java
new file mode 100644
index 000000000000..44edef75bfe4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/after/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Class<Integer> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/before/Expr.java
new file mode 100644
index 000000000000..35a3d63f8dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitive/before/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.items
new file mode 100644
index 000000000000..cd609774cf24
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : java.lang.Class<int[]>
+PsiReferenceExpression:myField : java.lang.Class<int[]>
+PsiReferenceExpression:myField : java.lang.Class<int[]>
+PsiReferenceExpression:myField : java.lang.Class<int[]>
+PsiReferenceExpression:myField : java.lang.Class<int[]>
+PsiReferenceExpression:myField : java.lang.Class<int[]>
+
+Conversions:
+
+New expression type changes:
+Fails:
+Set.class->java.lang.Class<int[]>
+Set[].class->java.lang.Class<int[]>
+int.class->java.lang.Class<int[]>
+void.class->java.lang.Class<int[]>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.java
new file mode 100644
index 000000000000..9939d2f3d410
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/after/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Class<int[]> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/before/Expr.java
new file mode 100644
index 000000000000..35a3d63f8dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassPrimitiveArray/before/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.items
new file mode 100644
index 000000000000..0bda2fd18195
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myField : java.lang.Class
+PsiReferenceExpression:myField : java.lang.Class
+PsiReferenceExpression:myField : java.lang.Class
+PsiReferenceExpression:myField : java.lang.Class
+PsiReferenceExpression:myField : java.lang.Class
+PsiReferenceExpression:myField : java.lang.Class
+
+Conversions:
+Set.class -> $
+Set[].class -> $
+int.class -> $
+int[].class -> $
+void.class -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.java
new file mode 100644
index 000000000000..9edcf9d47a31
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/after/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Class myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/before/Expr.java
new file mode 100644
index 000000000000..35a3d63f8dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassRaw/before/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.items
new file mode 100644
index 000000000000..ee8fece53e89
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : java.lang.Class<java.util.Set>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set>
+
+Conversions:
+
+New expression type changes:
+Fails:
+Set[].class->java.lang.Class<java.util.Set>
+int.class->java.lang.Class<java.util.Set>
+int[].class->java.lang.Class<java.util.Set>
+void.class->java.lang.Class<java.util.Set>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.java
new file mode 100644
index 000000000000..45fd995735ae
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/after/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Class<Set> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/before/Expr.java
new file mode 100644
index 000000000000..35a3d63f8dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReference/before/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.items
new file mode 100644
index 000000000000..26be6c5d8e6f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : java.lang.Class<java.util.Set[]>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set[]>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set[]>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set[]>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set[]>
+PsiReferenceExpression:myField : java.lang.Class<java.util.Set[]>
+
+Conversions:
+
+New expression type changes:
+Fails:
+Set.class->java.lang.Class<java.util.Set[]>
+int.class->java.lang.Class<java.util.Set[]>
+int[].class->java.lang.Class<java.util.Set[]>
+void.class->java.lang.Class<java.util.Set[]>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.java
new file mode 100644
index 000000000000..46b110d7f75f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/after/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Class<Set[]> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/before/Expr.java
new file mode 100644
index 000000000000..35a3d63f8dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassReferenceArray/before/Expr.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.items
new file mode 100644
index 000000000000..61336d444497
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myField : java.lang.Class<? super java.util.AbstractSet[]>
+PsiReferenceExpression:myField : java.lang.Class<? super java.util.AbstractSet[]>
+PsiReferenceExpression:myField : java.lang.Class<? super java.util.AbstractSet[]>
+PsiReferenceExpression:myField : java.lang.Class<? super java.util.AbstractSet[]>
+PsiReferenceExpression:myField : java.lang.Class<? super java.util.AbstractSet[]>
+PsiReferenceExpression:myField : java.lang.Class<? super java.util.AbstractSet[]>
+
+Conversions:
+Set[].class -> $
+
+New expression type changes:
+Fails:
+Set.class->java.lang.Class<? super java.util.AbstractSet[]>
+int.class->java.lang.Class<? super java.util.AbstractSet[]>
+int[].class->java.lang.Class<? super java.util.AbstractSet[]>
+void.class->java.lang.Class<? super java.util.AbstractSet[]>
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.java
new file mode 100644
index 000000000000..3ae94c8c1228
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/after/Expr.java
@@ -0,0 +1,13 @@
+import java.util.AbstractSet;
+import java.util.Set;
+
+class Expr {
+ private Class<? super AbstractSet[]> myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/before/Expr.java
new file mode 100644
index 000000000000..1e5b26a44e4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralClassSuper/before/Expr.java
@@ -0,0 +1,13 @@
+import java.util.AbstractSet;
+import java.util.Set;
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = int.class;
+ myField = int[].class;
+ myField = Set.class;
+ myField = Set[].class;
+ myField = void.class;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.items
new file mode 100644
index 000000000000..eb7229ef905e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.items
@@ -0,0 +1,36 @@
+Types:
+PsiField:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+PsiReferenceExpression:myField : double
+
+Conversions:
+'#' -> $
+043 -> $
+043F -> $
+043L -> $
+0x23 -> $
+0x23F -> $
+0x23L -> $
+35 -> $
+35F -> $
+35L -> $
+
+New expression type changes:
+Fails:
+"#"->double
+false->double
+null->double
+true->double
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.java
new file mode 100644
index 000000000000..a1fafc25fe6e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private double myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralDouble/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.items
new file mode 100644
index 000000000000..dcf1562d69b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.items
@@ -0,0 +1,35 @@
+Types:
+PsiField:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+
+Conversions:
+'#' -> $
+043 -> $
+043L -> $
+0x23 -> $
+0x23F -> $
+0x23L -> $
+35 -> $
+35L -> $
+
+New expression type changes:
+Fails:
+"#"->float
+35.0->float
+false->float
+null->float
+true->float
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.java
new file mode 100644
index 000000000000..8210b283c426
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private float myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralFloat/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.items
new file mode 100644
index 000000000000..6969f1efd214
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.items
@@ -0,0 +1,33 @@
+Types:
+PsiField:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+
+Conversions:
+'#' -> $
+
+New expression type changes:
+Fails:
+"#"->int
+043F->int
+043L->int
+0x23L->int
+35.0->int
+35F->int
+35L->int
+false->int
+null->int
+true->int
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.java
new file mode 100644
index 000000000000..51bce6ac6430
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private int myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralInt/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.items
new file mode 100644
index 000000000000..71718fa25bb1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.items
@@ -0,0 +1,34 @@
+Types:
+PsiField:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+
+Conversions:
+'#' -> $
+043 -> $
+0x23 -> $
+0x23F -> $
+35 -> $
+
+New expression type changes:
+Fails:
+"#"->long
+043F->long
+35.0->long
+35F->long
+false->long
+null->long
+true->long
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.java
new file mode 100644
index 000000000000..1556e9f05ffb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private long myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralLong/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.items
new file mode 100644
index 000000000000..f282b956c933
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.items
@@ -0,0 +1,37 @@
+Types:
+PsiField:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+
+Conversions:
+
+New expression type changes:
+Fails:
+"#"->short
+'#'->short
+043->short
+043F->short
+043L->short
+0x23->short
+0x23F->short
+0x23L->short
+35->short
+35.0->short
+35F->short
+35L->short
+false->short
+null->short
+true->short
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.java
new file mode 100644
index 000000000000..39b549b335bb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private short myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralShort/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.items
new file mode 100644
index 000000000000..6bb1edafdfa8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.items
@@ -0,0 +1,35 @@
+Types:
+PsiField:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+PsiReferenceExpression:myField : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+'#'->java.lang.String
+043->java.lang.String
+043F->java.lang.String
+043L->java.lang.String
+0x23->java.lang.String
+0x23F->java.lang.String
+0x23L->java.lang.String
+35->java.lang.String
+35.0->java.lang.String
+35F->java.lang.String
+35L->java.lang.String
+false->java.lang.String
+true->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.java
new file mode 100644
index 000000000000..3adc44418ad4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/after/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private String myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/before/Expr.java
new file mode 100644
index 000000000000..05b89dc47d4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprLiteralString/before/Expr.java
@@ -0,0 +1,27 @@
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = null;
+
+ myField = false;
+ myField = true;
+
+ myField = 043;
+ myField = 35;
+ myField = 0x23;
+
+ myField = '#';
+
+ myField = 043L;
+ myField = 35L;
+ myField = 0x23L;
+
+ myField = 043F;
+ myField = 35F;
+ myField = 0x23F;
+
+ myField = 35.0;
+
+ myField = "#";
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.items
new file mode 100644
index 000000000000..444531918ce0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.items
@@ -0,0 +1,22 @@
+Types:
+PsiArrayInitializerExpression:{pfc} : FaceParent[][]
+PsiArrayInitializerExpression:{pfc} : FaceParent[][]
+PsiArrayInitializerExpression:{{pfc}} : FaceParent[][][]
+PsiField:myArrayOne : FaceParent[][]
+PsiField:myArrayTwo : FaceParent[][][]
+PsiNewExpression:new FaceChild[][][]{{pfc}} : FaceParent[][][]
+PsiNewExpression:new FaceChild[][]{pfc} : FaceParent[][]
+PsiParameter:pfc : FaceParent[]
+PsiReferenceExpression:myArrayOne : FaceParent[][]
+PsiReferenceExpression:myArrayTwo : FaceParent[][][]
+PsiReferenceExpression:pfc : FaceParent[]
+PsiReferenceExpression:pfc : FaceParent[]
+
+Conversions:
+pfc -> $
+pfc -> $
+
+New expression type changes:
+new FaceChild[][][]{{pfc}} -> FaceParent[][][]
+new FaceChild[][]{pfc} -> FaceParent[][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..570367998bd1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/after/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+
+class Expr {
+ private FaceParent[][] myArrayOne;
+ private FaceParent[][][] myArrayTwo;
+ public void meth(FaceParent[] pfc) {
+ myArrayOne = new FaceParent[][]{pfc};
+ myArrayTwo = new FaceParent[][][]{{pfc}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..d88808766d7d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Lvalue/before/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+
+class Expr {
+ private FaceChild[][] myArrayOne;
+ private FaceChild[][][] myArrayTwo;
+ public void meth(FaceChild[] pfc) {
+ myArrayOne = new FaceChild[][]{pfc};
+ myArrayTwo = new FaceChild[][][]{{pfc}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..4b4b9036abb0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.items
@@ -0,0 +1,14 @@
+Types:
+PsiArrayInitializerExpression:{null} : ClassParent[][]
+PsiArrayInitializerExpression:{pfc} : ClassParent[][]
+PsiField:myField : ClassParent[][][]
+PsiNewExpression:new FaceChild[][][]{{pfc}, {null}, null} : ClassParent[][][]
+PsiParameter:pfc : ClassParent[]
+PsiReferenceExpression:myField : ClassParent[][][]
+PsiReferenceExpression:pfc : ClassParent[]
+
+Conversions:
+
+New expression type changes:
+new FaceChild[][][]{{pfc}, {null}, null} -> ClassParent[][][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..fc54bb6ca9d6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/after/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private ClassParent[][][] myField;
+ public void meth(ClassParent[] pfc) {
+ myField = new ClassParent[][][]{{pfc}, {null}, null};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..8c4093e44d75
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayArray2Rvalue/before/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private FaceChild[][][] myField;
+ public void meth(FaceChild[] pfc) {
+ myField = new FaceChild[][][]{{pfc}, {null}, null};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..825ef4f10f19
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : java.util.Set<java.lang.Integer>[]
+PsiReferenceExpression:myField : java.util.Set<java.lang.Integer>[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+new Set[1]->java.util.Set<java.lang.Integer>[]
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..5083896eb293
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/after/Expr.java
@@ -0,0 +1,8 @@
+import java.util.Set;
+
+class Expr {
+ private Set<Integer>[] myField;
+ public void meth() {
+ myField = new Set[1];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..c2301a434ec9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayGen2Rvalue/before/Expr.java
@@ -0,0 +1,8 @@
+import java.util.Set;
+
+class Expr {
+ private Set[] myField;
+ public void meth() {
+ myField = new Set[1];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.items
new file mode 100644
index 000000000000..d5976f11c486
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.items
@@ -0,0 +1,25 @@
+Types:
+PsiArrayInitializerExpression:{!p} : int[]
+PsiArrayInitializerExpression:{p} : int[]
+PsiArrayInitializerExpression:{p} : int[]
+PsiArrayInitializerExpression:{{p}, {!p}} : int[][]
+PsiField:myArrayOne : int[]
+PsiField:myArrayTwo : int[][]
+PsiNewExpression:new boolean[][]{{p}, {!p}} : int[][]
+PsiNewExpression:new boolean[]{p} : int[]
+PsiParameter:p : int
+PsiReferenceExpression:myArrayOne : int[]
+PsiReferenceExpression:myArrayTwo : int[][]
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+
+Conversions:
+p -> $
+p -> $
+
+New expression type changes:
+new boolean[][]{{p}, {!p}} -> int[][]
+new boolean[]{p} -> int[]
+Fails:
+!p->int
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..0c6c31bf4929
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/after/Expr.java
@@ -0,0 +1,8 @@
+class Expr {
+ private int[] myArrayOne;
+ private int[][] myArrayTwo;
+ public void meth(int p) {
+ myArrayOne = new int[]{p};
+ myArrayTwo = new int[][]{{p}, {!p}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..e7724ca422f4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Lvalue/before/Expr.java
@@ -0,0 +1,8 @@
+class Expr {
+ private boolean[] myArrayOne;
+ private boolean[][] myArrayTwo;
+ public void meth(boolean p) {
+ myArrayOne = new boolean[]{p};
+ myArrayTwo = new boolean[][]{{p}, {!p}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..5f371c0c6430
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.items
@@ -0,0 +1,21 @@
+Types:
+PsiArrayInitializerExpression:{!p} : int[]
+PsiArrayInitializerExpression:{0} : int[]
+PsiArrayInitializerExpression:{p} : int[]
+PsiArrayInitializerExpression:{true} : int[]
+PsiArrayInitializerExpression:{{p}, {!p}, {true}, {0}} : int[][]
+PsiField:myField : int[][]
+PsiNewExpression:new boolean[][]{{p}, {!p}, {true}, {0}} : int[][]
+PsiParameter:p : int
+PsiReferenceExpression:myField : int[][]
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+
+Conversions:
+p -> $
+
+New expression type changes:
+new boolean[][]{{p}, {!p}, {true}, {0}} -> int[][]
+Fails:
+!p->int
+true->int
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..58017644820c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/after/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ private int[][] myField;
+ public void meth(int p) {
+ myField = new int[][]{{p}, {!p}, {true}, {0}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..cb1e0d64aa4b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayPrimitive2Rvalue/before/Expr.java
@@ -0,0 +1,6 @@
+class Expr {
+ private boolean[][] myField;
+ public void meth(boolean p) {
+ myField = new boolean[][]{{p}, {!p}, {true}, {0}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.items
new file mode 100644
index 000000000000..a1472a46da67
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.items
@@ -0,0 +1,34 @@
+Types:
+PsiArrayInitializerExpression:{pcc} : FaceParent[]
+PsiArrayInitializerExpression:{pcp} : FaceParent[]
+PsiArrayInitializerExpression:{pfc, pcp, pcc} : FaceParent[]
+PsiArrayInitializerExpression:{pfc} : FaceParent[]
+PsiArrayInitializerExpression:{{pfc}, {pcp}, {pcc}} : FaceParent[][]
+PsiField:myArrayOne : FaceParent[]
+PsiField:myArrayTwo : FaceParent[][]
+PsiNewExpression:new FaceChild[][]{{pfc}, {pcp}, {pcc}} : FaceParent[][]
+PsiNewExpression:new FaceChild[]{pfc, pcp, pcc} : FaceParent[]
+PsiParameter:pcc : ClassChild
+PsiParameter:pcp : ClassParent
+PsiParameter:pfc : FaceParent
+PsiReferenceExpression:myArrayOne : FaceParent[]
+PsiReferenceExpression:myArrayTwo : FaceParent[][]
+PsiReferenceExpression:pcc : ClassChild
+PsiReferenceExpression:pcc : ClassChild
+PsiReferenceExpression:pcp : ClassParent
+PsiReferenceExpression:pcp : ClassParent
+PsiReferenceExpression:pfc : FaceParent
+PsiReferenceExpression:pfc : FaceParent
+
+Conversions:
+pcc -> $
+pcc -> $
+pcp -> $
+pcp -> $
+pfc -> $
+pfc -> $
+
+New expression type changes:
+new FaceChild[][]{{pfc}, {pcp}, {pcc}} -> FaceParent[][]
+new FaceChild[]{pfc, pcp, pcc} -> FaceParent[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..bfae5390508e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/after/Expr.java
@@ -0,0 +1,13 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private FaceParent[] myArrayOne;
+ private FaceParent[][] myArrayTwo;
+ public void meth(FaceParent pfc, ClassParent pcp, ClassChild pcc) {
+ myArrayOne = new FaceParent[]{pfc, pcp, pcc};
+ myArrayTwo = new FaceParent[][]{{pfc}, {pcp}, {pcc}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..5cb70f7265f7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Lvalue/before/Expr.java
@@ -0,0 +1,13 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private FaceChild[] myArrayOne;
+ private FaceChild[][] myArrayTwo;
+ public void meth(FaceChild pfc, ClassParent pcp, ClassChild pcc) {
+ myArrayOne = new FaceChild[]{pfc, pcp, pcc};
+ myArrayTwo = new FaceChild[][]{{pfc}, {pcp}, {pcc}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..4dabd7d9161e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.items
@@ -0,0 +1,18 @@
+Types:
+PsiArrayInitializerExpression:{null} : ClassParent[]
+PsiArrayInitializerExpression:{pcc} : ClassParent[]
+PsiArrayInitializerExpression:{pcp} : ClassParent[]
+PsiArrayInitializerExpression:{pfc} : ClassParent[]
+PsiField:myField : ClassParent[][]
+PsiNewExpression:new FaceChild[][]{{pfc}, {pcp}, {pcc}, {null}} : ClassParent[][]
+PsiParameter:pcc : ClassChild
+PsiParameter:pfc : ClassParent
+PsiReferenceExpression:myField : ClassParent[][]
+PsiReferenceExpression:pcc : ClassChild
+PsiReferenceExpression:pfc : ClassParent
+
+Conversions:
+
+New expression type changes:
+new FaceChild[][]{{pfc}, {pcp}, {pcc}, {null}} -> ClassParent[][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..f2d53b50f272
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/after/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private ClassParent[][] myField;
+ public void meth(ClassParent pfc, ClassParent pcp, ClassChild pcc) {
+ myField = new ClassParent[][]{{pfc}, {pcp}, {pcc}, {null}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..9e973b7925a0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewArrayReftype2Rvalue/before/Expr.java
@@ -0,0 +1,11 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Expr {
+ private FaceChild[][] myField;
+ public void meth(FaceChild pfc, ClassParent pcp, ClassChild pcc) {
+ myField = new FaceChild[][]{{pfc}, {pcp}, {pcc}, {null}};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.items
new file mode 100644
index 000000000000..d19a8ab094b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myField : java.util.Set<Subject>
+PsiNewExpression:new Set() : java.util.Set
+PsiNewExpression:new Set<Ancestor>() : java.util.Set<Subject>
+PsiNewExpression:new Set<Descendant>() : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+
+Conversions:
+
+New expression type changes:
+new Set() -> java.util.Set
+new Set<Ancestor>() -> java.util.Set<Subject>
+new Set<Descendant>() -> java.util.Set<Subject>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.java
new file mode 100644
index 000000000000..aab73939b929
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/after/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Set<Subject> myField;
+ public void meth() {
+ myField = new Set();
+ myField = new Set<Subject>();
+ myField = new Set<Subject>();
+ myField = new Set<Subject>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/before/Expr.java
new file mode 100644
index 000000000000..e38d8aa7229f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGen/before/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = new Set();
+ myField = new Set<Ancestor>();
+ myField = new Set<Subject>();
+ myField = new Set<Descendant>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.items
new file mode 100644
index 000000000000..9003258e73a5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : java.util.Set<? extends Subject>
+PsiNewExpression:new Set() : java.util.Set
+PsiNewExpression:new Set<Ancestor>() : java.util.Set<Subject>
+PsiNewExpression:new Set<Subject>() : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<? extends Subject>
+PsiReferenceExpression:myField : java.util.Set<? extends Subject>
+PsiReferenceExpression:myField : java.util.Set<? extends Subject>
+
+Conversions:
+
+New expression type changes:
+new Set() -> java.util.Set
+new Set<Ancestor>() -> java.util.Set<Subject>
+new Set<Subject>() -> java.util.Set<Subject>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.java
new file mode 100644
index 000000000000..f939534d6972
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/after/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Set<? extends Subject> myField;
+ public void meth() {
+ myField = new Set();
+ myField = new Set<Subject>();
+ myField = new Set<Subject>();
+ // myField = new Set<Descendant>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/before/Expr.java
new file mode 100644
index 000000000000..e65ce8b9a8fc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenExtends/before/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = new Set();
+ myField = new Set<Ancestor>();
+ myField = new Set<Subject>();
+ // myField = new Set<Descendant>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.items
new file mode 100644
index 000000000000..ca323d833a2c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:myField : java.util.Set<? super Subject>
+PsiNewExpression:new Set() : java.util.Set
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+
+Conversions:
+
+New expression type changes:
+new Set() -> java.util.Set
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.java
new file mode 100644
index 000000000000..4f5a29eecc6c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/after/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Set<? super Subject> myField;
+ public void meth() {
+ myField = new Set();
+ // myField = new Set<Ancestor>();
+ // myField = new Set<Subject>();
+ // myField = new Set<Descendant>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/before/Expr.java
new file mode 100644
index 000000000000..73a22ebeccde
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewGenSuper/before/Expr.java
@@ -0,0 +1,15 @@
+import java.util.Set;
+
+class Ancestor {}
+class Subject extends Ancestor {}
+class Descendant extends Subject {}
+
+class Expr {
+ private Object myField;
+ public void meth() {
+ myField = new Set();
+ // myField = new Set<Ancestor>();
+ // myField = new Set<Subject>();
+ // myField = new Set<Descendant>();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.items
new file mode 100644
index 000000000000..cab7f8173076
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.items
@@ -0,0 +1,27 @@
+Types:
+PsiField:myField : Expr.Subject
+PsiNewExpression:new Descendant() : Expr.Descendant
+PsiNewExpression:new Descendant() {} : Expr.Descendant
+PsiNewExpression:new Subject() {} : Expr.Subject
+PsiNewExpression:this.new Descendant() : Expr.Descendant
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+PsiReferenceExpression:myField : Expr.Subject
+
+Conversions:
+
+New expression type changes:
+new Descendant() -> Expr.Descendant
+new Descendant() {} -> Expr.Descendant
+new Subject() {} -> Expr.Subject
+this.new Descendant() -> Expr.Descendant
+Fails:
+new Ancestor()->Expr.Subject
+new Ancestor() {}->Expr.Subject
+this.new Ancestor()->Expr.Subject
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.java
new file mode 100644
index 000000000000..5cc9c87ec7e4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/after/Expr.java
@@ -0,0 +1,21 @@
+class Expr {
+ private class Ancestor {}
+ private class Subject extends Ancestor {}
+ private class Descendant extends Subject {}
+
+ private Subject myField;
+
+ public void meth() {
+ myField = new Ancestor();
+ myField = this.new Ancestor();
+ myField = new Ancestor() {};
+
+ myField = new Subject();
+ myField = this.new Subject();
+ myField = new Subject() {};
+
+ myField = new Descendant();
+ myField = this.new Descendant();
+ myField = new Descendant() {};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/before/Expr.java
new file mode 100644
index 000000000000..ed03e4ddc1d3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprNewReference/before/Expr.java
@@ -0,0 +1,21 @@
+class Expr {
+ private class Ancestor {}
+ private class Subject extends Ancestor {}
+ private class Descendant extends Subject {}
+
+ private Ancestor myField;
+
+ public void meth() {
+ myField = new Ancestor();
+ myField = this.new Ancestor();
+ myField = new Ancestor() {};
+
+ myField = new Subject();
+ myField = this.new Subject();
+ myField = new Subject() {};
+
+ myField = new Descendant();
+ myField = this.new Descendant();
+ myField = new Descendant() {};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.items
new file mode 100644
index 000000000000..e91631f5c332
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiMethod:meth : java.lang.String
+PsiParameter:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.java
new file mode 100644
index 000000000000..37c310d405e3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/after/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public String meth(String p) {
+ return p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/before/Expr.java
new file mode 100644
index 000000000000..76e26b5c15bb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Lvalue/before/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public int meth(int p) {
+ return p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.items
new file mode 100644
index 000000000000..e91631f5c332
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.items
@@ -0,0 +1,9 @@
+Types:
+PsiMethod:meth : java.lang.String
+PsiParameter:p : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.java
new file mode 100644
index 000000000000..37c310d405e3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/after/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public String meth(String p) {
+ return p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/before/Expr.java
new file mode 100644
index 000000000000..76e26b5c15bb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprReturn2Rvalue/before/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public int meth(int p) {
+ return p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.items
new file mode 100644
index 000000000000..6e445ca2c431
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.items
@@ -0,0 +1,10 @@
+Types:
+PsiLocalVariable:v : java.lang.String
+PsiParameter:pd : java.lang.String
+PsiReferenceExpression:pd : java.lang.String
+PsiReferenceExpression:pd : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.java
new file mode 100644
index 000000000000..1e75f910f300
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/after/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(String pd, int pp) {
+ String v = pp > 0 ? pd : pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/before/Expr.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/before/Expr.java
new file mode 100644
index 000000000000..3a714e5334a4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/exprTernary/before/Expr.java
@@ -0,0 +1,5 @@
+class Expr {
+ public void meth(double pd, int pp) {
+ double v = pp > 0 ? pd : pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Overriding.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Overriding.java
new file mode 100644
index 000000000000..9fb5b2161ba1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Overriding.java
@@ -0,0 +1,13 @@
+class Parent {
+ private byte myInt;
+ public byte getInt() {
+ return myInt;
+ }
+}
+
+class Child extends Parent {
+ private byte myInt;
+ public byte getInt() {
+ return myInt;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Parent.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Parent.items
new file mode 100644
index 000000000000..0857363a2808
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/after/Parent.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:myInt : byte
+PsiField:myInt : byte
+PsiMethod:getInt : byte
+PsiMethod:getInt : byte
+PsiReferenceExpression:myInt : byte
+PsiReferenceExpression:myInt : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/before/Overriding.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/before/Overriding.java
new file mode 100644
index 000000000000..212ce8080636
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingDown/before/Overriding.java
@@ -0,0 +1,13 @@
+class Parent {
+ private int myInt;
+ public int getInt() {
+ return myInt;
+ }
+}
+
+class Child extends Parent {
+ private int myInt;
+ public int getInt() {
+ return myInt;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Child.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Child.items
new file mode 100644
index 000000000000..0857363a2808
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Child.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:myInt : byte
+PsiField:myInt : byte
+PsiMethod:getInt : byte
+PsiMethod:getInt : byte
+PsiReferenceExpression:myInt : byte
+PsiReferenceExpression:myInt : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Overriding.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Overriding.java
new file mode 100644
index 000000000000..9fb5b2161ba1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/after/Overriding.java
@@ -0,0 +1,13 @@
+class Parent {
+ private byte myInt;
+ public byte getInt() {
+ return myInt;
+ }
+}
+
+class Child extends Parent {
+ private byte myInt;
+ public byte getInt() {
+ return myInt;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/before/Overriding.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/before/Overriding.java
new file mode 100644
index 000000000000..212ce8080636
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/overridingUp/before/Overriding.java
@@ -0,0 +1,13 @@
+class Parent {
+ private int myInt;
+ public int getInt() {
+ return myInt;
+ }
+}
+
+class Child extends Parent {
+ private int myInt;
+ public int getInt() {
+ return myInt;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.items
new file mode 100644
index 000000000000..4428712f4683
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : java.util.Set
+
+Conversions:
+#meth(double) -> PsiMethod:meth
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.java
new file mode 100644
index 000000000000..b6c748c1e749
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/after/Spec.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Spec {
+ /**
+ * @see #meth(java.util.Set)
+ */
+ public void methRef() {
+ }
+
+ public void meth(Set p) {
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/before/Spec.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/before/Spec.java
new file mode 100644
index 000000000000..45080dc2dec1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specJavadoc/before/Spec.java
@@ -0,0 +1,12 @@
+import java.util.Set;
+
+class Spec {
+ /**
+ * @see #meth(double)
+ */
+ public void methRef() {
+ }
+
+ public void meth(double p) {
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.items
new file mode 100644
index 000000000000..8ffc5c9a6744
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.items
@@ -0,0 +1,7 @@
+Types:
+PsiField:myField : boolean
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.java
new file mode 100644
index 000000000000..03d0dc267246
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/after/Spec.java
@@ -0,0 +1,3 @@
+class Spec {
+ private boolean myField;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/before/Spec.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/before/Spec.java
new file mode 100644
index 000000000000..36a606c54faa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/specNotUsed/before/Spec.java
@@ -0,0 +1,3 @@
+class Spec {
+ private int myField;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.items
new file mode 100644
index 000000000000..e56da57e1062
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.items
@@ -0,0 +1,13 @@
+Types:
+PsiField:myDescendants : Subject[]
+PsiParameter:p : Subject[]
+PsiReferenceExpression:myDescendants : Subject[]
+PsiReferenceExpression:p : Subject[]
+PsiReferenceExpression:p : Subject[]
+PsiReferenceExpression:p : Subject[]
+
+Conversions:
+myAncestors -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.java
new file mode 100644
index 000000000000..5b667afd7284
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/after/Type.java
@@ -0,0 +1,15 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myAncestors;
+ private Subject[] mySubjects;
+ private Subject[] myDescendants;
+
+ public void meth(Subject[] p) {
+ myAncestors = p;
+ mySubjects = p;
+ myDescendants = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/before/Type.java
new file mode 100644
index 000000000000..6c0ad8e907ae
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Lvalue/before/Type.java
@@ -0,0 +1,15 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myAncestors;
+ private Subject[] mySubjects;
+ private Descendant[] myDescendants;
+
+ public void meth(Descendant[] p) {
+ myAncestors = p;
+ mySubjects = p;
+ myDescendants = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.items
new file mode 100644
index 000000000000..aa0545cd97f1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.items
@@ -0,0 +1,13 @@
+Types:
+PsiField:myField : Subject[][]
+PsiParameter:pa : Subject[][]
+PsiReferenceExpression:myField : Subject[][]
+PsiReferenceExpression:myField : Subject[][]
+PsiReferenceExpression:myField : Subject[][]
+PsiReferenceExpression:pa : Subject[][]
+
+Conversions:
+pd -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.java
new file mode 100644
index 000000000000..1dc9d19b69d7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Subject[][] myField;
+ public void meth(Subject[][] pa, Subject[][] ps, Descendant[][] pd) {
+ myField = pa;
+ myField = ps;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/before/Type.java
new file mode 100644
index 000000000000..b84f5fada9b6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayReftype2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[][] myField;
+ public void meth(Ancestor[][] pa, Subject[][] ps, Descendant[][] pd) {
+ myField = pa;
+ myField = ps;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.items
new file mode 100644
index 000000000000..bfcf79449245
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myHolder : Holder[]
+PsiParameter:p : Holder[]
+PsiReferenceExpression:myHolder : Holder[]
+PsiReferenceExpression:p : Holder[]
+PsiReferenceExpression:p : Holder[]
+PsiReferenceExpression:p : Holder[]
+PsiReferenceExpression:p : Holder[]
+
+Conversions:
+myCloneable -> $
+myObject -> $
+mySerializable -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.java
new file mode 100644
index 000000000000..ea67626d3e12
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/after/Type.java
@@ -0,0 +1,15 @@
+class Holder implements Cloneable, java.io.Serializable {}
+
+class Type {
+ private Object myObject;
+ private Cloneable myCloneable;
+ private java.io.Serializable mySerializable;
+ private Holder[] myHolder;
+
+ public void meth(Holder[] p) {
+ myObject = p;
+ myCloneable = p;
+ mySerializable = p;
+ myHolder = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/before/Type.java
new file mode 100644
index 000000000000..41bb17f7fec2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayRoots2Lvalue/before/Type.java
@@ -0,0 +1,15 @@
+class Holder implements Cloneable, java.io.Serializable {}
+
+class Type {
+ private Object myObject;
+ private Cloneable myCloneable;
+ private java.io.Serializable mySerializable;
+ private Holder myHolder;
+
+ public void meth(Holder p) {
+ myObject = p;
+ myCloneable = p;
+ mySerializable = p;
+ myHolder = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.items
new file mode 100644
index 000000000000..9bcbf6e3ccf2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.items
@@ -0,0 +1,13 @@
+Types:
+PsiField:myDescendants : Subject[]
+PsiParameter:p : Subject...
+PsiReferenceExpression:myDescendants : Subject[]
+PsiReferenceExpression:p : Subject[]
+PsiReferenceExpression:p : Subject[]
+PsiReferenceExpression:p : Subject[]
+
+Conversions:
+myAncestors -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.java
new file mode 100644
index 000000000000..82714edc14eb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/after/Type.java
@@ -0,0 +1,15 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myAncestors;
+ private Subject[] mySubjects;
+ private Subject[] myDescendants;
+
+ public void meth(Subject... p) {
+ myAncestors = p;
+ mySubjects = p;
+ myDescendants = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/before/Type.java
new file mode 100644
index 000000000000..6c0ad8e907ae
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2Lvalue/before/Type.java
@@ -0,0 +1,15 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myAncestors;
+ private Subject[] mySubjects;
+ private Descendant[] myDescendants;
+
+ public void meth(Descendant[] p) {
+ myAncestors = p;
+ mySubjects = p;
+ myDescendants = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.items
new file mode 100644
index 000000000000..8e16567f6b52
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:myField : Descendant[]
+PsiParameter:p : Descendant[]
+PsiReferenceExpression:myField : Descendant[]
+PsiReferenceExpression:p : Descendant[]
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.java
new file mode 100644
index 000000000000..b14ffa0b66b9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/after/Type.java
@@ -0,0 +1,10 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Descendant[] myField;
+ public void meth(Descendant[] p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/before/Type.java
new file mode 100644
index 000000000000..299d07095294
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvalueNeg/before/Type.java
@@ -0,0 +1,10 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myField;
+ public void meth(Subject... p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.items
new file mode 100644
index 000000000000..fa58313766a2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:myField : Subject[]
+PsiReferenceExpression:myField : Subject[]
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.java
new file mode 100644
index 000000000000..b17f19ce9366
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/after/Type.java
@@ -0,0 +1,10 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Subject[] myField;
+ public void meth(Subject... p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/before/Type.java
new file mode 100644
index 000000000000..299d07095294
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeArrayVararg2RvaluePos/before/Type.java
@@ -0,0 +1,10 @@
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Ancestor[] myField;
+ public void meth(Subject... p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.items
new file mode 100644
index 000000000000..d2a5bdf18da5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.items
@@ -0,0 +1,11 @@
+Types:
+PsiParameter:p : java.lang.Boolean
+PsiReferenceExpression:p : java.lang.Boolean
+PsiReferenceExpression:p : java.lang.Boolean
+
+Conversions:
+myField -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.java
new file mode 100644
index 000000000000..256ad8ae87ba
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/after/Type.java
@@ -0,0 +1,8 @@
+class Type {
+ private boolean myField;
+ private Object myFieldSuper3;
+ public void meth(Boolean p) {
+ myField = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/before/Type.java
new file mode 100644
index 000000000000..e27196d88750
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Lvalue/before/Type.java
@@ -0,0 +1,8 @@
+class Type {
+ private boolean myField;
+ private Object myFieldSuper3;
+ public void meth(boolean p) {
+ myField = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.items
new file mode 100644
index 000000000000..ddbe17fb4ffc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : boolean
+PsiReferenceExpression:myField : boolean
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.java
new file mode 100644
index 000000000000..d58f3df69336
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private boolean myField;
+ public void meth(Boolean p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/before/Type.java
new file mode 100644
index 000000000000..fcfe89fe9eca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxBoolean2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Boolean myField;
+ public void meth(Boolean p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.items
new file mode 100644
index 000000000000..1c80a5546782
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:p : java.lang.Byte
+PsiReferenceExpression:p : java.lang.Byte
+PsiReferenceExpression:p : java.lang.Byte
+PsiReferenceExpression:p : java.lang.Byte
+PsiReferenceExpression:p : java.lang.Byte
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.java
new file mode 100644
index 000000000000..40e19f5b4a68
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private byte myField;
+ private short myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Byte p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/before/Type.java
new file mode 100644
index 000000000000..c525d82e6f19
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Lvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private byte myField;
+ private short myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(byte p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.items
new file mode 100644
index 000000000000..192b82591e68
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : byte
+PsiReferenceExpression:myField : byte
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.java
new file mode 100644
index 000000000000..435b929c8591
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private byte myField;
+ public void meth(Byte p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/before/Type.java
new file mode 100644
index 000000000000..c0c7993580df
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxByte2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Byte myField;
+ public void meth(Byte p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.items
new file mode 100644
index 000000000000..3499c81915b3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.items
@@ -0,0 +1,13 @@
+Types:
+PsiParameter:p : java.lang.Character
+PsiReferenceExpression:p : java.lang.Character
+PsiReferenceExpression:p : java.lang.Character
+PsiReferenceExpression:p : java.lang.Character
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.java
new file mode 100644
index 000000000000..c075b5ea1ae1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/after/Type.java
@@ -0,0 +1,10 @@
+class Type {
+ private char myField;
+ private int myFieldSuper1;
+ private Object myFieldSuper3;
+ public void meth(Character p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/before/Type.java
new file mode 100644
index 000000000000..c821e8a38b8e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Lvalue/before/Type.java
@@ -0,0 +1,10 @@
+class Type {
+ private char myField;
+ private int myFieldSuper1;
+ private Object myFieldSuper3;
+ public void meth(char p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.items
new file mode 100644
index 000000000000..8f1b31f74f05
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : char
+PsiReferenceExpression:myField : char
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.java
new file mode 100644
index 000000000000..bec7b611e95a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private char myField;
+ public void meth(Character p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/before/Type.java
new file mode 100644
index 000000000000..a98d2a5fa05a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxChar2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Character myField;
+ public void meth(Character p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.items
new file mode 100644
index 000000000000..c961b407f293
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.items
@@ -0,0 +1,13 @@
+Types:
+PsiParameter:p : java.lang.Double
+PsiReferenceExpression:p : java.lang.Double
+PsiReferenceExpression:p : java.lang.Double
+PsiReferenceExpression:p : java.lang.Double
+
+Conversions:
+myField -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.java
new file mode 100644
index 000000000000..c2cc8485f4f5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/after/Type.java
@@ -0,0 +1,10 @@
+class Type {
+ private double myField;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Double p) {
+ myField = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/before/Type.java
new file mode 100644
index 000000000000..56ec2d53eb99
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Lvalue/before/Type.java
@@ -0,0 +1,10 @@
+class Type {
+ private double myField;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(double p) {
+ myField = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.items
new file mode 100644
index 000000000000..2c80921ecfcb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : double
+PsiReferenceExpression:myField : double
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.java
new file mode 100644
index 000000000000..ac0e3c68ebdb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private double myField;
+ public void meth(Double p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/before/Type.java
new file mode 100644
index 000000000000..4950dcb0d5bd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxDouble2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Double myField;
+ public void meth(Double p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.items
new file mode 100644
index 000000000000..d51dd6bd244e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:p : java.lang.Float
+PsiReferenceExpression:p : java.lang.Float
+PsiReferenceExpression:p : java.lang.Float
+PsiReferenceExpression:p : java.lang.Float
+PsiReferenceExpression:p : java.lang.Float
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.java
new file mode 100644
index 000000000000..4e06d3369857
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private float myField;
+ private double myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Float p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/before/Type.java
new file mode 100644
index 000000000000..24ec9a945603
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Lvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private float myField;
+ private double myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(float p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.items
new file mode 100644
index 000000000000..1b905928d822
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : float
+PsiReferenceExpression:myField : float
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.java
new file mode 100644
index 000000000000..1db8edb10bed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private float myField;
+ public void meth(Float p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/before/Type.java
new file mode 100644
index 000000000000..078b103e8df1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxFloat2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Float myField;
+ public void meth(Float p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.items
new file mode 100644
index 000000000000..24c52d5796ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.java
new file mode 100644
index 000000000000..e0075f597b24
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private int myField;
+ private long myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Integer p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/before/Type.java
new file mode 100644
index 000000000000..9c2f74c3f26f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Lvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private int myField;
+ private long myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(int p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.items
new file mode 100644
index 000000000000..d95e0af0768c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : int
+PsiReferenceExpression:myField : int
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.java
new file mode 100644
index 000000000000..4bf28b31788c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private int myField;
+ public void meth(Integer p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/before/Type.java
new file mode 100644
index 000000000000..87273262b496
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxInt2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Integer myField;
+ public void meth(Integer p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.items
new file mode 100644
index 000000000000..29939f335f62
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:p : java.lang.Long
+PsiReferenceExpression:p : java.lang.Long
+PsiReferenceExpression:p : java.lang.Long
+PsiReferenceExpression:p : java.lang.Long
+PsiReferenceExpression:p : java.lang.Long
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.java
new file mode 100644
index 000000000000..695801b1bc4f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private long myField;
+ private float myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Long p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/before/Type.java
new file mode 100644
index 000000000000..c6a909f7c46a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Lvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private long myField;
+ private float myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(long p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.items
new file mode 100644
index 000000000000..0fa3e3feb520
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : long
+PsiReferenceExpression:myField : long
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.java
new file mode 100644
index 000000000000..6f407a2591a1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private long myField;
+ public void meth(Long p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/before/Type.java
new file mode 100644
index 000000000000..ceceb07caa8e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxLong2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Long myField;
+ public void meth(Long p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.items
new file mode 100644
index 000000000000..c6a4cc9b70c8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiParameter:p : java.lang.Short
+PsiReferenceExpression:p : java.lang.Short
+PsiReferenceExpression:p : java.lang.Short
+PsiReferenceExpression:p : java.lang.Short
+PsiReferenceExpression:p : java.lang.Short
+
+Conversions:
+myField -> $
+myFieldSuper1 -> $
+myFieldSuper2 -> $
+myFieldSuper3 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.java
new file mode 100644
index 000000000000..50d61183a785
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private short myField;
+ private int myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(Short p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/before/Type.java
new file mode 100644
index 000000000000..52eb7aa5b30c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Lvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private short myField;
+ private int myFieldSuper1;
+ private Number myFieldSuper2;
+ private Object myFieldSuper3;
+ public void meth(short p) {
+ myField = p;
+ myFieldSuper1 = p;
+ myFieldSuper2 = p;
+ myFieldSuper3 = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.items
new file mode 100644
index 000000000000..28ba15701be6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : short
+PsiReferenceExpression:myField : short
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.java
new file mode 100644
index 000000000000..ba146982c723
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private short myField;
+ public void meth(Short p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/before/Type.java
new file mode 100644
index 000000000000..9ca0f4947260
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeAutoboxShort2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private Short myField;
+ public void meth(Short p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.items
new file mode 100644
index 000000000000..6106a705cdd8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.items
@@ -0,0 +1,33 @@
+Types:
+PsiField:myAncestorSupers : java.util.Set<Subject>
+PsiField:myAncestors : java.util.Set<Subject>
+PsiField:myCollection : java.util.Collection<Subject>
+PsiField:myDescendantExtends : java.util.Set<Subject>
+PsiField:myDescendants : java.util.Set<Subject>
+PsiParameter:p : java.util.Set<Subject>
+PsiReferenceExpression:myAncestorSupers : java.util.Set<Subject>
+PsiReferenceExpression:myAncestors : java.util.Set<Subject>
+PsiReferenceExpression:myCollection : java.util.Collection<Subject>
+PsiReferenceExpression:myDescendantExtends : java.util.Set<Subject>
+PsiReferenceExpression:myDescendants : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+PsiReferenceExpression:p : java.util.Set<Subject>
+
+Conversions:
+myAncestorExtends -> $
+myDescendantSupers -> $
+mySet -> $
+mySubjectExtends -> $
+mySubjectSupers -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.java
new file mode 100644
index 000000000000..7e3eeb9770ca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/after/Type.java
@@ -0,0 +1,40 @@
+import java.util.Collection;
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<Subject> myAncestors;
+ private Set<? extends Ancestor> myAncestorExtends;
+ private Set<Subject> myAncestorSupers;
+
+ private Set<Subject> mySubjects;
+ private Set<? extends Subject> mySubjectExtends;
+ private Set<? super Subject> mySubjectSupers;
+
+ private Set<Subject> myDescendants;
+ private Set<Subject> myDescendantExtends;
+ private Set<? super Descendant> myDescendantSupers;
+
+ private Set mySet;
+ private Collection<Subject> myCollection;
+
+ public void meth(Set<Subject> p) {
+ myAncestors = p;
+ myAncestorExtends = p;
+ myAncestorSupers = p;
+
+ mySubjects = p;
+ mySubjectExtends = p;
+ mySubjectSupers = p;
+
+ myDescendants = p;
+ myDescendantExtends = p;
+ myDescendantSupers = p;
+
+ mySet = p;
+ myCollection = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2e63240580ca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestor2Lvalue/before/Type.java
@@ -0,0 +1,40 @@
+import java.util.Collection;
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<Ancestor> myAncestors;
+ private Set<? extends Ancestor> myAncestorExtends;
+ private Set<? super Ancestor> myAncestorSupers;
+
+ private Set<Subject> mySubjects;
+ private Set<? extends Subject> mySubjectExtends;
+ private Set<? super Subject> mySubjectSupers;
+
+ private Set<Descendant> myDescendants;
+ private Set<? extends Descendant> myDescendantExtends;
+ private Set<? super Descendant> myDescendantSupers;
+
+ private Set mySet;
+ private Collection<Ancestor> myCollection;
+
+ public void meth(Set p) {
+ myAncestors = p;
+ myAncestorExtends = p;
+ myAncestorSupers = p;
+
+ mySubjects = p;
+ mySubjectExtends = p;
+ mySubjectSupers = p;
+
+ myDescendants = p;
+ myDescendantExtends = p;
+ myDescendantSupers = p;
+
+ mySet = p;
+ myCollection = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.items
new file mode 100644
index 000000000000..6cb2f2be0d34
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.items
@@ -0,0 +1,33 @@
+Types:
+PsiField:myAncestorSupers : java.util.Set<? extends Subject>
+PsiField:myAncestors : java.util.Set<? extends Subject>
+PsiField:myDescendantExtends : java.util.Set<? extends Subject>
+PsiField:myDescendantSupers : java.util.Set<? extends Subject>
+PsiField:myDescendants : java.util.Set<? extends Subject>
+PsiField:mySubjectSupers : java.util.Set<? extends Subject>
+PsiField:mySubjects : java.util.Set<? extends Subject>
+PsiParameter:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:myAncestorSupers : java.util.Set<? extends Subject>
+PsiReferenceExpression:myAncestors : java.util.Set<? extends Subject>
+PsiReferenceExpression:myDescendantExtends : java.util.Set<? extends Subject>
+PsiReferenceExpression:myDescendantSupers : java.util.Set<? extends Subject>
+PsiReferenceExpression:myDescendants : java.util.Set<? extends Subject>
+PsiReferenceExpression:mySubjectSupers : java.util.Set<? extends Subject>
+PsiReferenceExpression:mySubjects : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+PsiReferenceExpression:p : java.util.Set<? extends Subject>
+
+Conversions:
+myAncestorExtends -> $
+mySet -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.java
new file mode 100644
index 000000000000..2ffef9b4e9ad
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/after/Type.java
@@ -0,0 +1,37 @@
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<? extends Subject> myAncestors;
+ private Set<? extends Ancestor> myAncestorExtends;
+ private Set<? extends Subject> myAncestorSupers;
+
+ private Set<? extends Subject> mySubjects;
+ private Set<? extends Subject> mySubjectExtends;
+ private Set<? extends Subject> mySubjectSupers;
+
+ private Set<? extends Subject> myDescendants;
+ private Set<? extends Subject> myDescendantExtends;
+ private Set<? extends Subject> myDescendantSupers;
+
+ private Set mySet;
+
+ public void meth(Set<? extends Subject> p) {
+ myAncestors = p;
+ myAncestorExtends = p;
+ myAncestorSupers = p;
+
+ mySubjects = p;
+ mySubjectExtends = p;
+ mySubjectSupers = p;
+
+ myDescendants = p;
+ myDescendantExtends = p;
+ myDescendantSupers = p;
+
+ mySet = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/before/Type.java
new file mode 100644
index 000000000000..4fc8d5baf167
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenAncestorWildcard2Lvalue/before/Type.java
@@ -0,0 +1,37 @@
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<Ancestor> myAncestors;
+ private Set<? extends Ancestor> myAncestorExtends;
+ private Set<? super Ancestor> myAncestorSupers;
+
+ private Set<Subject> mySubjects;
+ private Set<? extends Subject> mySubjectExtends;
+ private Set<? super Subject> mySubjectSupers;
+
+ private Set<Descendant> myDescendants;
+ private Set<? extends Descendant> myDescendantExtends;
+ private Set<? super Descendant> myDescendantSupers;
+
+ private Set mySet;
+
+ public void meth(Set p) {
+ myAncestors = p;
+ myAncestorExtends = p;
+ myAncestorSupers = p;
+
+ mySubjects = p;
+ mySubjectExtends = p;
+ mySubjectSupers = p;
+
+ myDescendants = p;
+ myDescendantExtends = p;
+ myDescendantSupers = p;
+
+ mySet = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.items
new file mode 100644
index 000000000000..ab6a62095446
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.items
@@ -0,0 +1,37 @@
+Types:
+PsiField:myField : java.util.Set<Subject>
+PsiLocalVariable:ancestorExtends : java.util.Set<Subject>
+PsiLocalVariable:ancestorSupers : java.util.Set<Subject>
+PsiLocalVariable:ancestors : java.util.Set<Subject>
+PsiLocalVariable:descendantExtends : java.util.Set<Subject>
+PsiLocalVariable:descendantSupers : java.util.Set<Subject>
+PsiLocalVariable:descendants : java.util.Set<Subject>
+PsiLocalVariable:myCollection : java.util.AbstractSet<Subject>
+PsiLocalVariable:subjectExtends : java.util.Set<Subject>
+PsiLocalVariable:subjectSupers : java.util.Set<Subject>
+PsiReferenceExpression:ancestorExtends : java.util.Set<Subject>
+PsiReferenceExpression:ancestorSupers : java.util.Set<Subject>
+PsiReferenceExpression:ancestors : java.util.Set<Subject>
+PsiReferenceExpression:descendantExtends : java.util.Set<Subject>
+PsiReferenceExpression:descendantSupers : java.util.Set<Subject>
+PsiReferenceExpression:descendants : java.util.Set<Subject>
+PsiReferenceExpression:myCollection : java.util.AbstractSet<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:myField : java.util.Set<Subject>
+PsiReferenceExpression:subjectExtends : java.util.Set<Subject>
+PsiReferenceExpression:subjectSupers : java.util.Set<Subject>
+
+Conversions:
+set -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.java
new file mode 100644
index 000000000000..119e65ca61b5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/after/Type.java
@@ -0,0 +1,39 @@
+import java.util.AbstractSet;
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<Subject> myField;
+
+ public void meth() {
+ Set<Subject> ancestors = null;
+ myField = ancestors;
+ Set<Subject> ancestorExtends = null;
+ myField = ancestorExtends;
+ Set<Subject> ancestorSupers = null;
+ myField = ancestorSupers;
+
+ // turning everything into Set<Subject> is actually too strict, but correct
+ Set<Subject> subjects = null;
+ myField = subjects;
+ Set<Subject> subjectExtends = null;
+ myField = subjectExtends;
+ Set<Subject> subjectSupers = null;
+ myField = subjectSupers;
+
+ Set<Subject> descendants = null;
+ myField = descendants;
+ Set<Subject> descendantExtends = null;
+ myField = descendantExtends;
+ Set<Subject> descendantSupers = null;
+ myField = descendantSupers;
+
+ Set set = null;
+ myField = set;
+ AbstractSet<Subject> myCollection = null;
+ myField = myCollection;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/before/Type.java
new file mode 100644
index 000000000000..e53aa1d3cd1b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendant2Rvalue/before/Type.java
@@ -0,0 +1,39 @@
+import java.util.AbstractSet;
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set myField;
+
+ public void meth() {
+ Set<Ancestor> ancestors = null;
+ myField = ancestors;
+ Set<? extends Ancestor> ancestorExtends = null;
+ myField = ancestorExtends;
+ Set<? super Ancestor> ancestorSupers = null;
+ myField = ancestorSupers;
+
+ // turning everything into Set<Subject> is actually too strict, but correct
+ Set<Subject> subjects = null;
+ myField = subjects;
+ Set<? extends Subject> subjectExtends = null;
+ myField = subjectExtends;
+ Set<? super Subject> subjectSupers = null;
+ myField = subjectSupers;
+
+ Set<Descendant> descendants = null;
+ myField = descendants;
+ Set<? extends Descendant> descendantExtends = null;
+ myField = descendantExtends;
+ Set<? super Descendant> descendantSupers = null;
+ myField = descendantSupers;
+
+ Set set = null;
+ myField = set;
+ AbstractSet<Descendant> myCollection = null;
+ myField = myCollection;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.items
new file mode 100644
index 000000000000..e34aedf887d3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.items
@@ -0,0 +1,32 @@
+Types:
+PsiField:myField : java.util.Set<? super Subject>
+PsiLocalVariable:ancestorExtends : java.util.Set<? super Subject>
+PsiLocalVariable:descendantExtends : java.util.Set<? super Subject>
+PsiLocalVariable:descendantSupers : java.util.Set<? super Subject>
+PsiLocalVariable:descendants : java.util.Set<? super Subject>
+PsiLocalVariable:subjectExtends : java.util.Set<? super Subject>
+PsiReferenceExpression:ancestorExtends : java.util.Set<? super Subject>
+PsiReferenceExpression:descendantExtends : java.util.Set<? super Subject>
+PsiReferenceExpression:descendantSupers : java.util.Set<? super Subject>
+PsiReferenceExpression:descendants : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:myField : java.util.Set<? super Subject>
+PsiReferenceExpression:subjectExtends : java.util.Set<? super Subject>
+
+Conversions:
+ancestorSupers -> $
+ancestors -> $
+set -> $
+subjectSupers -> $
+subjects -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.java
new file mode 100644
index 000000000000..a0982c89aa5c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/after/Type.java
@@ -0,0 +1,35 @@
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set<? super Subject> myField;
+
+ public void meth() {
+ Set<Ancestor> ancestors = null;
+ myField = ancestors;
+ Set<? super Subject> ancestorExtends = null;
+ myField = ancestorExtends;
+ Set<? super Ancestor> ancestorSupers = null;
+ myField = ancestorSupers;
+
+ Set<Subject> subjects = null;
+ myField = subjects;
+ Set<? super Subject> subjectExtends = null;
+ myField = subjectExtends;
+ Set<? super Subject> subjectSupers = null;
+ myField = subjectSupers;
+
+ Set<? super Subject> descendants = null;
+ myField = descendants;
+ Set<? super Subject> descendantExtends = null;
+ myField = descendantExtends;
+ Set<? super Subject> descendantSupers = null;
+ myField = descendantSupers;
+
+ Set set = null;
+ myField = set;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/before/Type.java
new file mode 100644
index 000000000000..79f4d219b47c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenDescendantWildcard2Rvalue/before/Type.java
@@ -0,0 +1,35 @@
+import java.util.Set;
+
+interface Ancestor {}
+interface Subject extends Ancestor {}
+class Descendant implements Subject {}
+
+class Type {
+ private Set myField;
+
+ public void meth() {
+ Set<Ancestor> ancestors = null;
+ myField = ancestors;
+ Set<? extends Ancestor> ancestorExtends = null;
+ myField = ancestorExtends;
+ Set<? super Ancestor> ancestorSupers = null;
+ myField = ancestorSupers;
+
+ Set<Subject> subjects = null;
+ myField = subjects;
+ Set<? extends Subject> subjectExtends = null;
+ myField = subjectExtends;
+ Set<? super Subject> subjectSupers = null;
+ myField = subjectSupers;
+
+ Set<Descendant> descendants = null;
+ myField = descendants;
+ Set<? extends Descendant> descendantExtends = null;
+ myField = descendantExtends;
+ Set<? super Descendant> descendantSupers = null;
+ myField = descendantSupers;
+
+ Set set = null;
+ myField = set;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.items
new file mode 100644
index 000000000000..9da02a3b248c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.Set
+PsiReferenceExpression:p : java.util.Set
+
+Conversions:
+myField -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.java
new file mode 100644
index 000000000000..f66a7c1fadc0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/after/Type.java
@@ -0,0 +1,10 @@
+import java.util.Set;
+
+class Any {}
+
+class Type {
+ private Set<Any> myField;
+ public void meth(Set p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/before/Type.java
new file mode 100644
index 000000000000..968d7e85e0b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Lvalue/before/Type.java
@@ -0,0 +1,10 @@
+import java.util.Set;
+
+class Any {}
+
+class Type {
+ private Set<Any> myField;
+ public void meth(Set<Any> p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.items
new file mode 100644
index 000000000000..a3dd46449c57
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:myField : java.util.Set
+PsiReferenceExpression:myField : java.util.Set
+
+Conversions:
+p -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.java
new file mode 100644
index 000000000000..f78a0b3d5a68
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/after/Type.java
@@ -0,0 +1,10 @@
+import java.util.Set;
+
+class Any {}
+
+class Type {
+ private Set myField;
+ public void meth(Set<Any> p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/before/Type.java
new file mode 100644
index 000000000000..968d7e85e0b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeGenRaw2Rvalue/before/Type.java
@@ -0,0 +1,10 @@
+import java.util.Set;
+
+class Any {}
+
+class Type {
+ private Set<Any> myField;
+ public void meth(Set<Any> p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.items
new file mode 100644
index 000000000000..361d3837f2da
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:myField : boolean
+PsiParameter:p : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:p : boolean
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.java
new file mode 100644
index 000000000000..8a5b062df2e6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private boolean myField;
+ public void meth(boolean p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/before/Type.java
new file mode 100644
index 000000000000..b9185a0c81ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Lvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private int myField;
+ public void meth(int p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.items
new file mode 100644
index 000000000000..361d3837f2da
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:myField : boolean
+PsiParameter:p : boolean
+PsiReferenceExpression:myField : boolean
+PsiReferenceExpression:p : boolean
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.java
new file mode 100644
index 000000000000..8a5b062df2e6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/after/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private boolean myField;
+ public void meth(boolean p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/before/Type.java
new file mode 100644
index 000000000000..b9185a0c81ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubBoolean2Rvalue/before/Type.java
@@ -0,0 +1,6 @@
+class Type {
+ private int myField;
+ public void meth(int p) {
+ myField = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.items
new file mode 100644
index 000000000000..71e76cc5a1e9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.items
@@ -0,0 +1,26 @@
+Types:
+PsiField:myField : byte
+PsiParameter:pc : byte
+PsiParameter:pd : byte
+PsiParameter:pf : byte
+PsiParameter:pi : byte
+PsiParameter:pl : byte
+PsiParameter:ps : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:myField : byte
+PsiReferenceExpression:pc : byte
+PsiReferenceExpression:pd : byte
+PsiReferenceExpression:pf : byte
+PsiReferenceExpression:pi : byte
+PsiReferenceExpression:pl : byte
+PsiReferenceExpression:ps : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.java
new file mode 100644
index 000000000000..ac3a40879f5b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private byte myField;
+ public void meth(byte pb, byte ps, byte pc, byte pi, byte pl, byte pf, byte pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubByte2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.items
new file mode 100644
index 000000000000..521321c601c1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.items
@@ -0,0 +1,22 @@
+Types:
+PsiField:myByte : char
+PsiField:myShort : char
+PsiParameter:p : char
+PsiReferenceExpression:myByte : char
+PsiReferenceExpression:myShort : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+PsiReferenceExpression:p : char
+
+Conversions:
+myDouble -> $
+myFloat -> $
+myInt -> $
+myLong -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.java
new file mode 100644
index 000000000000..8b94e45d5626
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private char myByte;
+ private char myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(char p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.items
new file mode 100644
index 000000000000..404f84f33867
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.items
@@ -0,0 +1,26 @@
+Types:
+PsiField:myField : char
+PsiParameter:pb : char
+PsiParameter:pd : char
+PsiParameter:pf : char
+PsiParameter:pi : char
+PsiParameter:pl : char
+PsiParameter:ps : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:myField : char
+PsiReferenceExpression:pb : char
+PsiReferenceExpression:pd : char
+PsiReferenceExpression:pf : char
+PsiReferenceExpression:pi : char
+PsiReferenceExpression:pl : char
+PsiReferenceExpression:ps : char
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.java
new file mode 100644
index 000000000000..dc346a77074c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private char myField;
+ public void meth(char pb, char ps, char pc, char pi, char pl, char pf, char pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubChar2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.items
new file mode 100644
index 000000000000..6946fcefbac0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.items
@@ -0,0 +1,26 @@
+Types:
+PsiField:myByte : double
+PsiField:myChar : double
+PsiField:myFloat : double
+PsiField:myInt : double
+PsiField:myLong : double
+PsiField:myShort : double
+PsiParameter:p : double
+PsiReferenceExpression:myByte : double
+PsiReferenceExpression:myChar : double
+PsiReferenceExpression:myFloat : double
+PsiReferenceExpression:myInt : double
+PsiReferenceExpression:myLong : double
+PsiReferenceExpression:myShort : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.java
new file mode 100644
index 000000000000..8a5035c81e4d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private double myByte;
+ private double myShort;
+ private double myChar;
+ private double myInt;
+ private double myLong;
+ private double myFloat;
+ private double myDouble;
+ public void meth(double p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubDouble2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.items
new file mode 100644
index 000000000000..c479836287e0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.items
@@ -0,0 +1,25 @@
+Types:
+PsiField:myByte : float
+PsiField:myChar : float
+PsiField:myInt : float
+PsiField:myLong : float
+PsiField:myShort : float
+PsiParameter:p : float
+PsiReferenceExpression:myByte : float
+PsiReferenceExpression:myChar : float
+PsiReferenceExpression:myInt : float
+PsiReferenceExpression:myLong : float
+PsiReferenceExpression:myShort : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+
+Conversions:
+myDouble -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.java
new file mode 100644
index 000000000000..8b59184de85f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private float myByte;
+ private float myShort;
+ private float myChar;
+ private float myInt;
+ private float myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(float p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.items
new file mode 100644
index 000000000000..7a22f6771caf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.items
@@ -0,0 +1,21 @@
+Types:
+PsiField:myField : float
+PsiParameter:pd : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:myField : float
+PsiReferenceExpression:pd : float
+
+Conversions:
+pb -> $
+pc -> $
+pi -> $
+pl -> $
+ps -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.java
new file mode 100644
index 000000000000..0b933cce77dd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private float myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, float pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubFloat2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.items
new file mode 100644
index 000000000000..200b3b8b3fb5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.items
@@ -0,0 +1,23 @@
+Types:
+PsiField:myByte : int
+PsiField:myChar : int
+PsiField:myShort : int
+PsiParameter:p : int
+PsiReferenceExpression:myByte : int
+PsiReferenceExpression:myChar : int
+PsiReferenceExpression:myShort : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+PsiReferenceExpression:p : int
+
+Conversions:
+myDouble -> $
+myFloat -> $
+myLong -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.java
new file mode 100644
index 000000000000..b15830da724d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private int myByte;
+ private int myShort;
+ private int myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(int p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.items
new file mode 100644
index 000000000000..b7c45d6a6aff
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.items
@@ -0,0 +1,23 @@
+Types:
+PsiField:myField : int
+PsiParameter:pd : int
+PsiParameter:pf : int
+PsiParameter:pl : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:myField : int
+PsiReferenceExpression:pd : int
+PsiReferenceExpression:pf : int
+PsiReferenceExpression:pl : int
+
+Conversions:
+pb -> $
+pc -> $
+ps -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.java
new file mode 100644
index 000000000000..c13b0ab9bee2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private int myField;
+ public void meth(byte pb, short ps, char pc, int pi, int pl, int pf, int pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubInt2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.items
new file mode 100644
index 000000000000..3f94bd20c6e8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.items
@@ -0,0 +1,24 @@
+Types:
+PsiField:myByte : long
+PsiField:myChar : long
+PsiField:myInt : long
+PsiField:myShort : long
+PsiParameter:p : long
+PsiReferenceExpression:myByte : long
+PsiReferenceExpression:myChar : long
+PsiReferenceExpression:myInt : long
+PsiReferenceExpression:myShort : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+PsiReferenceExpression:p : long
+
+Conversions:
+myDouble -> $
+myFloat -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.java
new file mode 100644
index 000000000000..1b594666283c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private long myByte;
+ private long myShort;
+ private long myChar;
+ private long myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(long p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.items
new file mode 100644
index 000000000000..98a3c92987b9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.items
@@ -0,0 +1,22 @@
+Types:
+PsiField:myField : long
+PsiParameter:pd : long
+PsiParameter:pf : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:myField : long
+PsiReferenceExpression:pd : long
+PsiReferenceExpression:pf : long
+
+Conversions:
+pb -> $
+pc -> $
+pi -> $
+ps -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.java
new file mode 100644
index 000000000000..e3e3b25d89b4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private long myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, long pf, long pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubLong2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.items
new file mode 100644
index 000000000000..8f0cd52a3560
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.items
@@ -0,0 +1,22 @@
+Types:
+PsiField:myByte : short
+PsiField:myChar : short
+PsiParameter:p : short
+PsiReferenceExpression:myByte : short
+PsiReferenceExpression:myChar : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+PsiReferenceExpression:p : short
+
+Conversions:
+myDouble -> $
+myFloat -> $
+myInt -> $
+myLong -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.java
new file mode 100644
index 000000000000..ccbe23c4b4e2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private short myByte;
+ private short myShort;
+ private short myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(short p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/before/Type.java
new file mode 100644
index 000000000000..2d55ceaa511a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+class Type {
+ private byte myByte;
+ private short myShort;
+ private char myChar;
+ private int myInt;
+ private long myLong;
+ private float myFloat;
+ private double myDouble;
+ public void meth(byte p) {
+ myByte = p;
+ myShort = p;
+ myChar = p;
+ myInt = p;
+ myLong = p;
+ myFloat = p;
+ myDouble = p;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.items
new file mode 100644
index 000000000000..754060e723ec
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.items
@@ -0,0 +1,25 @@
+Types:
+PsiField:myField : short
+PsiParameter:pc : short
+PsiParameter:pd : short
+PsiParameter:pf : short
+PsiParameter:pi : short
+PsiParameter:pl : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:myField : short
+PsiReferenceExpression:pc : short
+PsiReferenceExpression:pd : short
+PsiReferenceExpression:pf : short
+PsiReferenceExpression:pi : short
+PsiReferenceExpression:pl : short
+
+Conversions:
+pb -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.java
new file mode 100644
index 000000000000..eb53bcd49ebc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/after/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private short myField;
+ public void meth(byte pb, short ps, short pc, short pi, short pl, short pf, short pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/before/Type.java
new file mode 100644
index 000000000000..f7edce2eea98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typePrimsubShort2Rvalue/before/Type.java
@@ -0,0 +1,12 @@
+class Type {
+ private double myField;
+ public void meth(byte pb, short ps, char pc, int pi, long pl, float pf, double pd) {
+ myField = pb;
+ myField = ps;
+ myField = pc;
+ myField = pi;
+ myField = pl;
+ myField = pf;
+ myField = pd;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.items
new file mode 100644
index 000000000000..78431b6e4a4a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myField : ClassChild
+PsiParameter:pcp : ClassChild
+PsiParameter:pfc : ClassChild
+PsiParameter:pfp : ClassChild
+PsiReferenceExpression:myField : ClassChild
+PsiReferenceExpression:myField : ClassChild
+PsiReferenceExpression:myField : ClassChild
+PsiReferenceExpression:myField : ClassChild
+PsiReferenceExpression:pcp : ClassChild
+PsiReferenceExpression:pfc : ClassChild
+PsiReferenceExpression:pfp : ClassChild
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.java
new file mode 100644
index 000000000000..f5d9434c07c4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/after/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassChild myField;
+ public void meth(ClassChild pcc, ClassChild pcp, ClassChild pfc, ClassChild pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/before/Type.java
new file mode 100644
index 000000000000..e5cfab9f9af5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassChild2Rvalue/before/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceParent myField;
+ public void meth(ClassChild pcc, ClassParent pcp, FaceChild pfc, FaceParent pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.items
new file mode 100644
index 000000000000..18fce6b3d6ec
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiField:myClassChild : ClassParent
+PsiParameter:p : ClassParent
+PsiReferenceExpression:myClassChild : ClassParent
+PsiReferenceExpression:p : ClassParent
+PsiReferenceExpression:p : ClassParent
+PsiReferenceExpression:p : ClassParent
+PsiReferenceExpression:p : ClassParent
+
+Conversions:
+myFaceChild -> $
+myFaceParent -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.java
new file mode 100644
index 000000000000..8d7fee567890
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassParent myClassChild;
+ private ClassParent myClassParent;
+ private FaceChild myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(ClassParent p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/before/Type.java
new file mode 100644
index 000000000000..074af076748d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassChild myClassChild;
+ private ClassParent myClassParent;
+ private FaceChild myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(ClassChild p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.items
new file mode 100644
index 000000000000..4e7bfb9a5f9a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myField : ClassParent
+PsiParameter:pfc : ClassParent
+PsiParameter:pfp : ClassParent
+PsiReferenceExpression:myField : ClassParent
+PsiReferenceExpression:myField : ClassParent
+PsiReferenceExpression:myField : ClassParent
+PsiReferenceExpression:myField : ClassParent
+PsiReferenceExpression:pfc : ClassParent
+PsiReferenceExpression:pfp : ClassParent
+
+Conversions:
+pcc -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.java
new file mode 100644
index 000000000000..9953f41083c5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/after/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassParent myField;
+ public void meth(ClassChild pcc, ClassParent pcp, ClassParent pfc, ClassParent pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/before/Type.java
new file mode 100644
index 000000000000..e5cfab9f9af5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefClassParent2Rvalue/before/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceParent myField;
+ public void meth(ClassChild pcc, ClassParent pcp, FaceChild pfc, FaceParent pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.items
new file mode 100644
index 000000000000..9dd227a952df
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:myClassChild : FaceChild
+PsiField:myClassParent : FaceChild
+PsiParameter:p : FaceChild
+PsiReferenceExpression:myClassChild : FaceChild
+PsiReferenceExpression:myClassParent : FaceChild
+PsiReferenceExpression:p : FaceChild
+PsiReferenceExpression:p : FaceChild
+PsiReferenceExpression:p : FaceChild
+PsiReferenceExpression:p : FaceChild
+
+Conversions:
+myFaceParent -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.java
new file mode 100644
index 000000000000..f4b8de1d6028
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceChild myClassChild;
+ private FaceChild myClassParent;
+ private FaceChild myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(FaceChild p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/before/Type.java
new file mode 100644
index 000000000000..074af076748d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassChild myClassChild;
+ private ClassParent myClassParent;
+ private FaceChild myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(ClassChild p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.items
new file mode 100644
index 000000000000..91683c097f98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.items
@@ -0,0 +1,15 @@
+Types:
+PsiField:myField : FaceChild
+PsiParameter:pfp : FaceChild
+PsiReferenceExpression:myField : FaceChild
+PsiReferenceExpression:myField : FaceChild
+PsiReferenceExpression:myField : FaceChild
+PsiReferenceExpression:myField : FaceChild
+PsiReferenceExpression:pfp : FaceChild
+
+Conversions:
+pcc -> $
+pcp -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.java
new file mode 100644
index 000000000000..f16470efa1df
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/after/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceChild myField;
+ public void meth(ClassChild pcc, ClassParent pcp, FaceChild pfc, FaceChild pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/before/Type.java
new file mode 100644
index 000000000000..e5cfab9f9af5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceChild2Rvalue/before/Type.java
@@ -0,0 +1,14 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceParent myField;
+ public void meth(ClassChild pcc, ClassParent pcp, FaceChild pfc, FaceParent pfp) {
+ myField = pcc;
+ myField = pcp;
+ myField = pfc;
+ myField = pfp;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.items b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.items
new file mode 100644
index 000000000000..a10aad579ef2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.items
@@ -0,0 +1,17 @@
+Types:
+PsiField:myClassChild : FaceParent
+PsiField:myClassParent : FaceParent
+PsiField:myFaceChild : FaceParent
+PsiParameter:p : FaceParent
+PsiReferenceExpression:myClassChild : FaceParent
+PsiReferenceExpression:myClassParent : FaceParent
+PsiReferenceExpression:myFaceChild : FaceParent
+PsiReferenceExpression:p : FaceParent
+PsiReferenceExpression:p : FaceParent
+PsiReferenceExpression:p : FaceParent
+PsiReferenceExpression:p : FaceParent
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.java
new file mode 100644
index 000000000000..d53c072b9b56
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/after/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private FaceParent myClassChild;
+ private FaceParent myClassParent;
+ private FaceParent myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(FaceParent p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/before/Type.java b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/before/Type.java
new file mode 100644
index 000000000000..074af076748d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/migrateTypeSignature/typeRefFaceParent2Lvalue/before/Type.java
@@ -0,0 +1,18 @@
+interface FaceParent {}
+interface FaceChild extends FaceParent {}
+class ClassParent implements FaceChild {}
+class ClassChild extends ClassParent {}
+
+class Type {
+ private ClassChild myClassChild;
+ private ClassParent myClassParent;
+ private FaceChild myFaceChild;
+ private FaceParent myFaceParent;
+
+ public void meth(ClassChild p) {
+ myClassChild = p;
+ myClassParent = p;
+ myFaceChild = p;
+ myFaceParent = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/Test.items
new file mode 100644
index 000000000000..702373b694d5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:i.foo(new Integer[0]) : Foo
+PsiParameter:i : Foo
+PsiReferenceExpression:i : Foo
+
+Conversions:
+i.foo -> PsiMethod:moo
+
+New expression type changes:
+Fails:
+new Integer[0]->int
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/test.java
new file mode 100644
index 000000000000..cf8dd0203f05
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t01/after/test.java
@@ -0,0 +1,39 @@
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Oct 16, 2004
+ * Time: 10:10:35 PM
+ * To change this template use File | Settings | File Templates.
+ */
+
+class Foo {
+ Moo moo(int i) {
+ return null;
+ }
+}
+
+class Moo {
+ Foo foo(Integer[] j) {
+ return null;
+ }
+}
+
+class P {
+ int f(int y) {
+ return y;
+ }
+}
+
+class G extends P {
+ int f(int y) {
+ return y;
+ }
+}
+
+public class Test {
+ Moo g(Foo i) {
+ Foo j = i.moo(new Integer[0]);
+ return null;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t01/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t01/before/test.java
new file mode 100644
index 000000000000..1f7a52e4aa63
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t01/before/test.java
@@ -0,0 +1,39 @@
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Oct 16, 2004
+ * Time: 10:10:35 PM
+ * To change this template use File | Settings | File Templates.
+ */
+
+class Foo {
+ Moo moo(int i) {
+ return null;
+ }
+}
+
+class Moo {
+ Foo foo(Integer[] j) {
+ return null;
+ }
+}
+
+class P {
+ int f(int y) {
+ return y;
+ }
+}
+
+class G extends P {
+ int f(int y) {
+ return y;
+ }
+}
+
+public class Test {
+ Moo g(Moo i) {
+ Foo j = i.foo(new Integer[0]);
+ return null;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/Test.items
new file mode 100644
index 000000000000..eb13633449ca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethod:sum : java.lang.Integer
+PsiMethodCallExpression:sum(n, k) : java.lang.Integer
+
+Conversions:
+a -> $
+i + j -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/test.java
new file mode 100644
index 000000000000..5842b8fa99e0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t02/after/test.java
@@ -0,0 +1,20 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ Integer sum(int i, int j) {
+ return i + j;
+ }
+
+ int foo(int n, int k) {
+ int a;
+
+ a = sum(n, k);
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t02/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t02/before/test.java
new file mode 100644
index 000000000000..d0ebca58783c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t02/before/test.java
@@ -0,0 +1,20 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ int sum(int i, int j) {
+ return i + j;
+ }
+
+ int foo(int n, int k) {
+ int a;
+
+ a = sum(n, k);
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/Test.items
new file mode 100644
index 000000000000..f1747c90b2ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethod:sum : java.lang.Integer
+PsiMethodCallExpression:sum(i, k) : java.lang.Integer
+
+Conversions:
+a -> $
+i + j -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/test.java
new file mode 100644
index 000000000000..5fd61417ba05
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t03/after/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ Integer sum(int i, int j) {
+ return i + j;
+ }
+
+ int[] foo(int n, int k) {
+ int[] a = new int[n];
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = sum(i, k);
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t03/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t03/before/test.java
new file mode 100644
index 000000000000..9e1559784bde
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t03/before/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ int sum(int i, int j) {
+ return i + j;
+ }
+
+ int[] foo(int n, int k) {
+ int[] a = new int[n];
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = sum(i, k);
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/Test.items
new file mode 100644
index 000000000000..edea723357ea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/Test.items
@@ -0,0 +1,21 @@
+Types:
+PsiLocalVariable:a : java.lang.Long[][]
+PsiMethod:bar : java.lang.Long[]
+PsiMethod:foo : java.lang.Long[][]
+PsiMethodCallExpression:bar() : java.lang.Long[]
+PsiNewExpression:new Integer[0] : java.lang.Long[]
+PsiNewExpression:new Integer[0] : java.lang.Long[]
+PsiNewExpression:new Integer[0] : java.lang.Long[]
+PsiNewExpression:new Integer[][] {new Integer[0], new Integer[0]} : java.lang.Long[][]
+PsiReferenceExpression:a : java.lang.Long[][]
+PsiReferenceExpression:a : java.lang.Long[][]
+PsiReferenceExpression:a : java.lang.Long[][]
+
+Conversions:
+
+New expression type changes:
+new Integer[0] -> java.lang.Long[]
+new Integer[0] -> java.lang.Long[]
+new Integer[0] -> java.lang.Long[]
+new Integer[][] {new Integer[0], new Integer[0]} -> java.lang.Long[][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/test.java
new file mode 100644
index 000000000000..080208fcbd6c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t04/after/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ Long[] bar() {
+ return new Long[0];
+ }
+
+ Long[][] foo(int n, int k) {
+ Long[][] a = new Long[][]{new Long[0], new Long[0]};
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = bar();
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t04/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t04/before/test.java
new file mode 100644
index 000000000000..591b5a530d2b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t04/before/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ Integer[] bar() {
+ return new Integer[0];
+ }
+
+ Integer[] foo(int n, int k) {
+ Integer[][] a = new Integer[][] {new Integer[0], new Integer[0]};
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = bar();
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/Test.items
new file mode 100644
index 000000000000..8152c1b711e7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:i : java.lang.Integer
+PsiReferenceExpression:i : java.lang.Integer
+
+Conversions:
+i -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/test.java
new file mode 100644
index 000000000000..b74d13b84fda
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t05/after/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ int sum(Integer i, int j) {
+ return i + j;
+ }
+
+ int[] foo(int n, int k) {
+ int[] a = new int[] {1, 2, 3, 4};
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = sum(i, k);
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t05/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t05/before/test.java
new file mode 100644
index 000000000000..e8a96127f4fd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t05/before/test.java
@@ -0,0 +1,22 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Test {
+ int sum(int i, int j) {
+ return i + j;
+ }
+
+ int[] foo(int n, int k) {
+ int[] a = new int[] {1, 2, 3, 4};
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = sum(i, k);
+ }
+
+ return a;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/Test.items
new file mode 100644
index 000000000000..3ad4c0f7992f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiLocalVariable:a : B
+PsiMethod:getA : B
+PsiMethodCallExpression:getA () : B
+PsiReferenceExpression:a : B
+
+Conversions:
+
+New expression type changes:
+Fails:
+new A ()->B
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/test.java
new file mode 100644
index 000000000000..f4fa6ab1f876
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t06/after/test.java
@@ -0,0 +1,25 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class A {}
+class B {}
+
+public class Test {
+ B getA() {
+ return new A ();
+ }
+
+ int foo() {
+ B a = getA ();
+
+ if (a != null){
+ return 0;
+ }
+
+ return 1;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t06/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t06/before/test.java
new file mode 100644
index 000000000000..862356ebd9cc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t06/before/test.java
@@ -0,0 +1,25 @@
+/**
+ * Created by IntelliJ IDEA.
+ * User: db
+ * Date: Nov 15, 2004
+ * Time: 5:40:02 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class A {}
+class B {}
+
+public class Test {
+ A getA() {
+ return new A ();
+ }
+
+ int foo() {
+ A a = getA ();
+
+ if (a != null){
+ return 0;
+ }
+
+ return 1;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/Test.items
new file mode 100644
index 000000000000..12252787a292
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.lang.Integer[]
+PsiNewExpression:new int[0] : java.lang.Integer[]
+
+Conversions:
+
+New expression type changes:
+new int[0] -> java.lang.Integer[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/test.java
new file mode 100644
index 000000000000..09d7a0982009
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t07/after/test.java
@@ -0,0 +1,3 @@
+public class Test {
+ Integer[] f = new Integer[0];
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t07/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t07/before/test.java
new file mode 100644
index 000000000000..87955af32435
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t07/before/test.java
@@ -0,0 +1,3 @@
+public class Test {
+ int[] f = new int[0];
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/Test.items
new file mode 100644
index 000000000000..7c09ce5a46f7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.lang.String[]
+PsiNewExpression:new Integer[0] : java.lang.String[]
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:f : java.lang.String[]
+
+Conversions:
+
+New expression type changes:
+new Integer[0] -> java.lang.String[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/test.java
new file mode 100644
index 000000000000..9f13a80a2f2a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t08/after/test.java
@@ -0,0 +1,6 @@
+public class Test {
+ String[] f = new String[0];
+ void foo() {
+ for (String i : f) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t08/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t08/before/test.java
new file mode 100644
index 000000000000..e38a9aa3155d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t08/before/test.java
@@ -0,0 +1,6 @@
+public class Test {
+ Integer[] f = new Integer[0];
+ void foo() {
+ for (Integer i : f) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/Test.items
new file mode 100644
index 000000000000..39394462b76e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:f : java.lang.String[]
+PsiNewExpression:new Integer[0] : java.lang.String[]
+PsiParameter:g : java.lang.String[]
+PsiReferenceExpression:f : java.lang.String[]
+
+Conversions:
+f -> $
+
+New expression type changes:
+new Integer[0] -> java.lang.String[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/test.java
new file mode 100644
index 000000000000..5e779c9e12f5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t09/after/test.java
@@ -0,0 +1,8 @@
+public class Test {
+ String[] f = new String[0];
+ void foo() {
+ bar(1, f);
+ }
+
+ void bar(int i, String[] g){}
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t09/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t09/before/test.java
new file mode 100644
index 000000000000..db3f02ed1976
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t09/before/test.java
@@ -0,0 +1,8 @@
+public class Test {
+ Integer[] f = new Integer[0];
+ void foo() {
+ bar(1, f);
+ }
+
+ void bar(int i, Integer[] g){}
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/Test.items
new file mode 100644
index 000000000000..77d161720fb5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.List<java.lang.String>
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:f : java.util.List<java.lang.String>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/test.java
new file mode 100644
index 000000000000..7820f54d0340
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t10/after/test.java
@@ -0,0 +1,7 @@
+import java.util.List;
+public class Test {
+ List<String> f;
+ void foo() {
+ for (String i : f) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t10/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t10/before/test.java
new file mode 100644
index 000000000000..726f23a4bf8d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t10/before/test.java
@@ -0,0 +1,7 @@
+import java.util.List;
+public class Test {
+ List<Integer> f;
+ void foo() {
+ for (Integer i : f) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/Test.items
new file mode 100644
index 000000000000..135dca6a135e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.Map<java.lang.String,java.lang.Integer>
+PsiNewExpression:new HashMap<String,String>() : java.util.HashMap<java.lang.String,java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+new HashMap<String,String>() -> java.util.HashMap<java.lang.String,java.lang.Integer>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/test.java
new file mode 100644
index 000000000000..b2917c86149e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t100/after/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ Map<String, Integer> f = new HashMap<>();
+
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t100/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t100/before/test.java
new file mode 100644
index 000000000000..7bf03e3a27da
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t100/before/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ Map<String,String> f = new HashMap<String,String>();
+
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/Test.items
new file mode 100644
index 000000000000..285bc5b6ca51
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.util.ArrayList<java.lang.Integer>
+PsiParameter:p : java.util.ArrayList<java.lang.Integer>[]
+PsiReferenceExpression:p : java.util.ArrayList<java.lang.Integer>[]
+
+Conversions:
+p.get(0) -> $qualifier$[$i$] $qualifier$.get($i$) p.get(0)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/test.java
new file mode 100644
index 000000000000..6344b428b46c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t101/after/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ void meth(ArrayList<Integer>[] p) {
+ ArrayList<Integer> v = p[0];
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t101/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t101/before/test.java
new file mode 100644
index 000000000000..e16f3d100bc9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t101/before/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ void meth(List<ArrayList<Integer>> p) {
+ ArrayList<Integer> v = p.get(0);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/Test.items
new file mode 100644
index 000000000000..b9f794b195bf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:s : java.lang.Object[]
+PsiReferenceExpression:s : java.lang.Object[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+s->java.lang.Object[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/test.java
new file mode 100644
index 000000000000..dcd056fcaf90
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t102/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(Object[] s) {
+ s.add(null);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t102/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t102/before/test.java
new file mode 100644
index 000000000000..f59b5db84644
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t102/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(Set<? extends Object> s) {
+ s.add(null);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/Test.items
new file mode 100644
index 000000000000..b13c3192a1d8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:l : java.lang.Integer[]
+PsiReferenceExpression:l : java.lang.Integer[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+l->java.lang.Integer[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/test.java
new file mode 100644
index 000000000000..af807d53c7b0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t103/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(Integer[] l) {
+ l.set(1, "");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t103/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t103/before/test.java
new file mode 100644
index 000000000000..7e5802d50574
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t103/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(ArrayList<String> l) {
+ l.set(1, "");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/Test.items
new file mode 100644
index 000000000000..f085abb3c681
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:l : java.lang.String[]
+PsiReferenceExpression:l : java.lang.String[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+l->java.lang.String[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/test.java
new file mode 100644
index 000000000000..d70a09a513bd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t104/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(String[] l) {
+ l.set(1, "");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t104/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t104/before/test.java
new file mode 100644
index 000000000000..bc4b40c061a2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t104/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+public class Test {
+ void method(ArrayList l) {
+ l.set(1, "");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/Test.items
new file mode 100644
index 000000000000..7821f01df96c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/Test.items
@@ -0,0 +1,7 @@
+Types:
+PsiField:t : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/test.java
new file mode 100644
index 000000000000..71797316503f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t105/after/test.java
@@ -0,0 +1,3 @@
+public class Test<T> {
+ String t;
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t105/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t105/before/test.java
new file mode 100644
index 000000000000..763dc905176d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t105/before/test.java
@@ -0,0 +1,3 @@
+public class Test<T> {
+ T t;
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/Test.items
new file mode 100644
index 000000000000..2fab8a1f5fae
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:t : java.lang.String
+PsiReferenceExpression:t : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+t->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/test.java
new file mode 100644
index 000000000000..dafbfca4a742
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t106/after/test.java
@@ -0,0 +1,6 @@
+public class Test<T extends Number> {
+ String t;
+ void foo() {
+ int i = t.intValue();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t106/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t106/before/test.java
new file mode 100644
index 000000000000..65ad21055710
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t106/before/test.java
@@ -0,0 +1,6 @@
+public class Test<T extends Number> {
+ T t;
+ void foo() {
+ int i = t.intValue();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/Test.items
new file mode 100644
index 000000000000..93a16148be72
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:t : java.lang.Integer
+PsiMethodCallExpression:t.intValue() : int
+PsiReferenceExpression:t : java.lang.Integer
+
+Conversions:
+t.intValue() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/test.java
new file mode 100644
index 000000000000..ce44f19e2458
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t107/after/test.java
@@ -0,0 +1,6 @@
+public class Test<T extends Number> {
+ Integer t;
+ void foo() {
+ int i = t.intValue();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t107/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t107/before/test.java
new file mode 100644
index 000000000000..65ad21055710
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t107/before/test.java
@@ -0,0 +1,6 @@
+public class Test<T extends Number> {
+ T t;
+ void foo() {
+ int i = t.intValue();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/Test.items
new file mode 100644
index 000000000000..a9f530ce25f7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:integer.intValue() : int
+PsiParameter:integer : java.lang.Number
+PsiParameter:l : java.util.List<? extends java.lang.Number>
+PsiReferenceExpression:integer : java.lang.Number
+PsiReferenceExpression:l : java.util.List<? extends java.lang.Number>
+
+Conversions:
+integer.intValue() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/test.java
new file mode 100644
index 000000000000..26b9322b4739
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t108/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<? extends Number> l) {
+ for (Number integer : l) {
+ System.out.println(integer.intValue());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t108/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t108/before/test.java
new file mode 100644
index 000000000000..08a3229cd932
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t108/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<Integer> l) {
+ for (Integer integer : l) {
+ System.out.println(integer.intValue());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/Test.items
new file mode 100644
index 000000000000..6a47f6675781
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:integer.hashCode() : int
+PsiParameter:integer : java.lang.Object
+PsiParameter:l : java.util.List<? super java.lang.Number>
+PsiReferenceExpression:integer : java.lang.Object
+PsiReferenceExpression:l : java.util.List<? super java.lang.Number>
+
+Conversions:
+integer.hashCode() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/test.java
new file mode 100644
index 000000000000..bae70cd5b0d4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t109/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<? super Number> l) {
+ for (Object integer : l) {
+ System.out.println(integer.hashCode());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t109/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t109/before/test.java
new file mode 100644
index 000000000000..26280e892cd0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t109/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<Integer> l) {
+ for (Integer integer : l) {
+ System.out.println(integer.hashCode());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/Test.items
new file mode 100644
index 000000000000..4058a7862ff2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.util.Map<java.lang.String,java.lang.Integer>
+PsiMethodCallExpression:f.keySet() : java.util.Set<java.lang.String>
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:f : java.util.Map<java.lang.String,java.lang.Integer>
+
+Conversions:
+f.keySet() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/test.java
new file mode 100644
index 000000000000..1491875ea2b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t11/after/test.java
@@ -0,0 +1,7 @@
+import java.util.Map;
+public class Test {
+ Map<String, Integer> f;
+ void foo() {
+ for (String i : f.keySet()) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t11/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t11/before/test.java
new file mode 100644
index 000000000000..b0aa7086f175
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t11/before/test.java
@@ -0,0 +1,7 @@
+import java.util.Map;
+public class Test {
+ Map<Integer, Integer> f;
+ void foo() {
+ for (Integer i : f.keySet()) {}
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/Test.items
new file mode 100644
index 000000000000..3853e035e26b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiParameter:integer : java.lang.String
+PsiParameter:l : java.util.List<? extends java.lang.String>
+PsiReferenceExpression:integer : java.lang.String
+PsiReferenceExpression:l : java.util.List<? extends java.lang.String>
+
+Conversions:
+
+New expression type changes:
+Fails:
+integer->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/test.java
new file mode 100644
index 000000000000..cb813fd6567f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t110/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<? extends String> l) {
+ for (String integer : l) {
+ System.out.println(integer.intValue());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t110/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t110/before/test.java
new file mode 100644
index 000000000000..08a3229cd932
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t110/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ void method(List<Integer> l) {
+ for (Integer integer : l) {
+ System.out.println(integer.intValue());
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/Test.items
new file mode 100644
index 000000000000..29717a0b2377
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiParameter:i : java.lang.Integer[]
+PsiReferenceExpression:i : java.lang.Integer[]
+PsiReferenceExpression:i : java.lang.Integer[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+i->java.lang.Integer[]
+i++->java.lang.Integer[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/test.java
new file mode 100644
index 000000000000..e257e485d6bb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t111/after/test.java
@@ -0,0 +1,7 @@
+public class Test {
+ void method(Integer[] i) {
+ if (i == 0) {
+ i++;
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t111/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t111/before/test.java
new file mode 100644
index 000000000000..2620dd9f5d6a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t111/before/test.java
@@ -0,0 +1,7 @@
+public class Test {
+ void method(Integer i) {
+ if (i == 0) {
+ i++;
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/Test.items
new file mode 100644
index 000000000000..78f2ed729f10
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiMethod:method : java.lang.Integer[]
+
+Conversions:
+112 -> new java.lang.Integer[]{$qualifier$} $qualifier$ 112
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/test.java
new file mode 100644
index 000000000000..c31ec11010c3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t112/after/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ Integer[] method() {
+ return new Integer[]{112};
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t112/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t112/before/test.java
new file mode 100644
index 000000000000..e7bf28f0de1e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t112/before/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ Integer method() {
+ return 112;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/Test.items
new file mode 100644
index 000000000000..1b69785be552
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/Test.items
@@ -0,0 +1,7 @@
+Types:
+PsiParameter:p : java.lang.Number...
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/test.java
new file mode 100644
index 000000000000..9f9bdcaffad7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t113/after/test.java
@@ -0,0 +1,7 @@
+public class Test {
+ void method(Number... p) {}
+
+ public void doSmth() {
+ m(123);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t113/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t113/before/test.java
new file mode 100644
index 000000000000..6627e8d101de
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t113/before/test.java
@@ -0,0 +1,7 @@
+public class Test {
+ void method(Integer... p) {}
+
+ public void doSmth() {
+ m(123);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/Test.items
new file mode 100644
index 000000000000..b6c70f112866
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.lang.String...
+PsiReferenceExpression:p : java.lang.String[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[0]->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/test.java
new file mode 100644
index 000000000000..6e2b9f24c22a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t114/after/test.java
@@ -0,0 +1,9 @@
+public class Test {
+ void method(String... p) {
+ int i = p[0].intValue();
+ }
+
+ public void doSmth() {
+ m(123);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t114/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t114/before/test.java
new file mode 100644
index 000000000000..f73951e56432
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t114/before/test.java
@@ -0,0 +1,9 @@
+public class Test {
+ void method(Integer... p) {
+ int i = p[0].intValue();
+ }
+
+ public void doSmth() {
+ m(123);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/Test.items
new file mode 100644
index 000000000000..b07cf0af793c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:i : java.lang.String...
+
+Conversions:
+
+New expression type changes:
+Fails:
+2->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/test.java
new file mode 100644
index 000000000000..8d69a2330c70
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t115/after/test.java
@@ -0,0 +1,8 @@
+class Test {
+ void foo(String... i) {
+ }
+
+ void bar() {
+ foo("str", 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t115/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t115/before/test.java
new file mode 100644
index 000000000000..f585aba2e91c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t115/before/test.java
@@ -0,0 +1,8 @@
+class Test {
+ void foo(Object... i) {
+ }
+
+ void bar() {
+ foo("str", 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/Test.items
new file mode 100644
index 000000000000..0aee5ef814c6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:str : java.lang.String
+PsiParameter:number : java.lang.String
+PsiReferenceExpression:number : java.lang.String
+PsiReferenceExpression:str : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/test.java
new file mode 100644
index 000000000000..95ddfb44251f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t116/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ String str;
+
+ void foo(String[] p) {
+ for (String number : p) {
+ number = str;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t116/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t116/before/test.java
new file mode 100644
index 000000000000..d68047e81823
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t116/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ Number str;
+
+ void foo(String[] p) {
+ for (Number number : p) {
+ number = str;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/Test.items
new file mode 100644
index 000000000000..0aee5ef814c6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:str : java.lang.String
+PsiParameter:number : java.lang.String
+PsiReferenceExpression:number : java.lang.String
+PsiReferenceExpression:str : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/test.java
new file mode 100644
index 000000000000..3172eaa133dc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t117/after/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+ String str;
+
+ void foo(List<String> p) {
+ for (String number : p) {
+ number = str;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t117/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t117/before/test.java
new file mode 100644
index 000000000000..46cde69dca96
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t117/before/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+ Number str;
+
+ void foo(List<String> p) {
+ for (Number number : p) {
+ number = str;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/Test.items
new file mode 100644
index 000000000000..dcd1be2928cb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/Test.items
@@ -0,0 +1,7 @@
+Types:
+PsiParameter:p : java.lang.Integer...
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/test.java
new file mode 100644
index 000000000000..37d684a97957
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t118/after/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+
+ void method(Integer... p) {
+ }
+
+ public void doSmth(ArrayList<Integer> p) {
+ method(p.get(2));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t118/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t118/before/test.java
new file mode 100644
index 000000000000..012a188e5ad5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t118/before/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+
+ void method(Integer p) {
+ }
+
+ public void doSmth(ArrayList<Integer> p) {
+ method(p.get(2));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/Test.items
new file mode 100644
index 000000000000..dcd1be2928cb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/Test.items
@@ -0,0 +1,7 @@
+Types:
+PsiParameter:p : java.lang.Integer...
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/test.java
new file mode 100644
index 000000000000..28446b6bc761
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t119/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+
+ void method(Integer... p) {
+ }
+
+ public void doSmth(Integer[] p) {
+ method(p[2]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t119/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t119/before/test.java
new file mode 100644
index 000000000000..28aeed25cefa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t119/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+
+ void method(Integer p) {
+ }
+
+ public void doSmth(Integer[] p) {
+ method(p[2]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/Test.items
new file mode 100644
index 000000000000..a1b75e0f23ac
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.List<java.lang.String>
+PsiLocalVariable:i : java.lang.String
+PsiReferenceExpression:f : java.util.List<java.lang.String>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/test.java
new file mode 100644
index 000000000000..657869206253
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t12/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+public class Test {
+ List<String> f;
+ void foo() {
+ String i = Collections.min(f);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t12/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t12/before/test.java
new file mode 100644
index 000000000000..24199ff02584
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t12/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+public class Test {
+ List<Integer> f;
+ void foo() {
+ Integer i = Collections.min(f);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/Test.items
new file mode 100644
index 000000000000..6f23d60f1d3c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiParameter:p : java.lang.String...
+PsiParameter:p : java.lang.String[]
+PsiReferenceExpression:p : java.lang.String[]
+PsiReferenceExpression:p : java.lang.String[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[3]->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/test.java
new file mode 100644
index 000000000000..e40c1215581b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t120/after/test.java
@@ -0,0 +1,10 @@
+class Test {
+
+ void method(String... p) {
+ }
+
+ public void doSmth(String[] p) {
+ method(p[2]);
+ System.out.println(p[3].intValue());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t120/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t120/before/test.java
new file mode 100644
index 000000000000..0f65e57d94ee
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t120/before/test.java
@@ -0,0 +1,10 @@
+class Test {
+
+ void method(Integer p) {
+ }
+
+ public void doSmth(Integer[] p) {
+ method(p[2]);
+ System.out.println(p[3].intValue());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/Test.items
new file mode 100644
index 000000000000..dadc2c72891a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:p.add(8) : boolean
+PsiParameter:p : java.util.ArrayList<java.lang.Float>
+PsiReferenceExpression:p : java.util.ArrayList<java.lang.Float>
+
+Conversions:
+8 -> $
+p.add(8) -> $
+
+New expression type changes:
+Fails:
+8->java.lang.Float
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/test.java
new file mode 100644
index 000000000000..e3a952e4d560
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t121/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+
+ void method(ArrayList<Float> p){
+ p.add(8);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t121/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t121/before/test.java
new file mode 100644
index 000000000000..aad87ca532b7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t121/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+
+ void method(ArrayList<Number> p){
+ p.add(8);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/Test.items
new file mode 100644
index 000000000000..00092fc53a55
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.List<java.lang.Integer>[]
+PsiReferenceExpression:p : java.util.List<java.lang.Integer>[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->java.util.List<java.lang.Integer>[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/test.java
new file mode 100644
index 000000000000..5784ee52e360
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t122/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+
+ void method(List<Integer>[] p){
+ ArrayList<Integer> v = p.get(0);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t122/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t122/before/test.java
new file mode 100644
index 000000000000..bb086dad2af8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t122/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+
+ void method(List<ArrayList<Integer>> p){
+ ArrayList<Integer> v = p.get(0);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/Test.items
new file mode 100644
index 000000000000..691d3e6a1e26
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:n : java.lang.Integer
+PsiParameter:number : java.lang.Integer
+PsiParameter:p : java.lang.Integer[]
+PsiReferenceExpression:n : java.lang.Integer
+PsiReferenceExpression:number : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer[]
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/test.java
new file mode 100644
index 000000000000..883991ffec9d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t123/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ Integer n;
+
+ void foo(Integer[] p) {
+ for (Integer number : p) {
+ n = number;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t123/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t123/before/test.java
new file mode 100644
index 000000000000..516fcf828234
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t123/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ Number n;
+
+ void foo(Number[] p) {
+ for (Number number : p) {
+ n = number;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/Test.items
new file mode 100644
index 000000000000..4a7df94f76b2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->java.lang.Integer
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/test.java
new file mode 100644
index 000000000000..f41fe88534f4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t124/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public <U> U meth(Integer p) {
+ return p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t124/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t124/before/test.java
new file mode 100644
index 000000000000..b40d864d16c7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t124/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public <U> U meth(U p) {
+ return p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/Test.items
new file mode 100644
index 000000000000..3859bad4e428
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.lang.Integer
+PsiReferenceExpression:p : java.lang.Integer
+
+Conversions:
+
+New expression type changes:
+Fails:
+Collections.singletonList(p)->java.util.List<java.lang.Integer>
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/test.java
new file mode 100644
index 000000000000..7854f476cc9e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t125/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ public <U> List<U> meth(Integer p) {
+ return Collections.singletonList(p);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t125/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t125/before/test.java
new file mode 100644
index 000000000000..30cf3914d62a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t125/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ public <U> List<U> meth(U p) {
+ return Collections.singletonList(p);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/Test.items
new file mode 100644
index 000000000000..f870c21c0523
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiMethod:meth : T
+
+Conversions:
+
+New expression type changes:
+Fails:
+map.get(2)->T
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/test.java
new file mode 100644
index 000000000000..7b2814378d28
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t126/after/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+
+class Test<T> {
+ Map<Integer, String> map;
+
+ T meth() {
+ return map.get(2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t126/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t126/before/test.java
new file mode 100644
index 000000000000..0dc76ccbdc72
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t126/before/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+
+class Test<T> {
+ Map<Integer, String> map;
+
+ String meth() {
+ return map.get(2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/Test.items
new file mode 100644
index 000000000000..78aa0fbd396b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiLocalVariable:i : long
+PsiMethod:test234 : long
+PsiMethodCallExpression:test234(1,
+ 2) : long
+
+Conversions:
+1 -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/test.java
new file mode 100644
index 000000000000..06a4d09a41a6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t127/after/test.java
@@ -0,0 +1,13 @@
+public class Test {
+
+ public long test234(int i,
+ int j)
+ {
+ return 1;
+ }
+
+ public void foo() {
+ long i = test234(1,
+ 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t127/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t127/before/test.java
new file mode 100644
index 000000000000..dd2c813fd38e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t127/before/test.java
@@ -0,0 +1,13 @@
+public class Test {
+
+ public int test234(int i,
+ int j)
+ {
+ return 1;
+ }
+
+ public void foo() {
+ int i = test234(1,
+ 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/Test.items
new file mode 100644
index 000000000000..24ec208dbb43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:e.printStackTrace() : void
+PsiParameter:e : Test.E
+PsiReferenceExpression:e : Test.E
+
+Conversions:
+e.printStackTrace() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/test.java
new file mode 100644
index 000000000000..8f2ad153d911
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t128/after/test.java
@@ -0,0 +1,16 @@
+class Test {
+ static class E extends Exception { }
+ static class E1 extends E { }
+ static class E2 extends E { }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E e) {
+ e.printStackTrace();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t128/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t128/before/test.java
new file mode 100644
index 000000000000..33bb6bf973c1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t128/before/test.java
@@ -0,0 +1,16 @@
+class Test {
+ static class E extends Exception { }
+ static class E1 extends E { }
+ static class E2 extends E { }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E1 | E2 e) {
+ e.printStackTrace();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/Test.items
new file mode 100644
index 000000000000..8ca26492b5bd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:e.printStackTrace() : void
+PsiParameter:e : Test.E1 | Test.E2
+PsiReferenceExpression:e : Test.E1 | Test.E2
+
+Conversions:
+e.printStackTrace() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/test.java
new file mode 100644
index 000000000000..33bb6bf973c1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t129/after/test.java
@@ -0,0 +1,16 @@
+class Test {
+ static class E extends Exception { }
+ static class E1 extends E { }
+ static class E2 extends E { }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E1 | E2 e) {
+ e.printStackTrace();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t129/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t129/before/test.java
new file mode 100644
index 000000000000..8f2ad153d911
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t129/before/test.java
@@ -0,0 +1,16 @@
+class Test {
+ static class E extends Exception { }
+ static class E1 extends E { }
+ static class E2 extends E { }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E e) {
+ e.printStackTrace();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/Test.items
new file mode 100644
index 000000000000..ca5cc75efa2e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.util.List<java.lang.Integer>
+PsiMethodCallExpression:f.add("val") : boolean
+PsiReferenceExpression:f : java.util.List<java.lang.Integer>
+
+Conversions:
+f.add("val") -> $
+
+New expression type changes:
+Fails:
+"val"->java.lang.Integer
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/test.java
new file mode 100644
index 000000000000..53b97a29e38c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t13/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+public class Test {
+ List<Integer> f;
+ void foo() {
+ f.add("val");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t13/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t13/before/test.java
new file mode 100644
index 000000000000..9024eab86966
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t13/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+public class Test {
+ List<String> f;
+ void foo() {
+ f.add("val");
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/Test.items
new file mode 100644
index 000000000000..056ae7968e06
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:e.printStackTrace() : void
+PsiParameter:e : Test.E
+PsiReferenceExpression:e : Test.E
+PsiReferenceExpression:e : Test.E
+
+Conversions:
+e.printStackTrace() -> $
+
+New expression type changes:
+Fails:
+e->Test.E
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/test.java
new file mode 100644
index 000000000000..67ed3db2315a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t130/after/test.java
@@ -0,0 +1,18 @@
+class Test {
+ static class E extends Exception { }
+ static interface I { void i(); }
+ static class E1 extends E implements I { public void i() { } }
+ static class E2 extends E implements I { public void i() { } }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E e) {
+ e.printStackTrace();
+ e.i();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t130/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t130/before/test.java
new file mode 100644
index 000000000000..7ee7852db3d4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t130/before/test.java
@@ -0,0 +1,18 @@
+class Test {
+ static class E extends Exception { }
+ static interface I { void i(); }
+ static class E1 extends E implements I { public void i() { } }
+ static class E2 extends E implements I { public void i() { } }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E1 | E2 e) {
+ e.printStackTrace();
+ e.i();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/Test.items
new file mode 100644
index 000000000000..e8d3b6152d2d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/Test.items
@@ -0,0 +1,13 @@
+Types:
+PsiMethodCallExpression:e.i() : void
+PsiMethodCallExpression:e.printStackTrace() : void
+PsiParameter:e : Test.E2 | Test.E1
+PsiReferenceExpression:e : Test.E2 | Test.E1
+PsiReferenceExpression:e : Test.E2 | Test.E1
+
+Conversions:
+e.i() -> $
+e.printStackTrace() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/test.java
new file mode 100644
index 000000000000..5c02bb8a41f2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t131/after/test.java
@@ -0,0 +1,18 @@
+class Test {
+ static class E extends Exception { }
+ static interface I { void i(); }
+ static class E1 extends E implements I { public void i() { } }
+ static class E2 extends E implements I { public void i() { } }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E2 | E1 e) {
+ e.printStackTrace();
+ e.i();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t131/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t131/before/test.java
new file mode 100644
index 000000000000..7ee7852db3d4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t131/before/test.java
@@ -0,0 +1,18 @@
+class Test {
+ static class E extends Exception { }
+ static interface I { void i(); }
+ static class E1 extends E implements I { public void i() { } }
+ static class E2 extends E implements I { public void i() { } }
+
+ void m(boolean f) {
+ try {
+ if (f)
+ throw new E1();
+ else
+ throw new E2();
+ } catch (E1 | E2 e) {
+ e.printStackTrace();
+ e.i();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/Test.items
new file mode 100644
index 000000000000..e5b813b90288
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/Test.items
@@ -0,0 +1,15 @@
+Types:
+PsiMethodCallExpression:i.f() : void
+PsiMethodCallExpression:i.f() : void
+PsiParameter:i : I
+PsiParameter:i : I
+PsiParameter:i : I
+PsiReferenceExpression:i : I
+PsiReferenceExpression:i : I
+
+Conversions:
+i.f() -> $
+i.f() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/test.java
new file mode 100644
index 000000000000..6f53c98f5459
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t132/after/test.java
@@ -0,0 +1,25 @@
+interface I {
+ void f();
+}
+
+interface J extends I {
+ void g();
+}
+
+public interface Test {
+ void h(I i);
+}
+
+class B implements Test {
+ @Override
+ public void h(I i) {
+ i.f();
+ }
+}
+
+class C implements Test {
+ @Override
+ public void h(I i) {
+ i.f();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t132/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t132/before/test.java
new file mode 100644
index 000000000000..2e6ab23c21d6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t132/before/test.java
@@ -0,0 +1,25 @@
+interface I {
+ void f();
+}
+
+interface J extends I {
+ void g();
+}
+
+public interface Test {
+ void h(J i);
+}
+
+class B implements Test {
+ @Override
+ public void h(J i) {
+ i.f();
+ }
+}
+
+class C implements Test {
+ @Override
+ public void h(J i) {
+ i.f();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/Test.items
new file mode 100644
index 000000000000..777fddf90a83
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/Test.items
@@ -0,0 +1,16 @@
+Types:
+PsiMethodCallExpression:i.f() : void
+PsiMethodCallExpression:i.f() : void
+PsiParameter:i : I
+PsiParameter:i : I
+PsiParameter:i : I
+PsiParameter:i : I
+PsiReferenceExpression:i : I
+PsiReferenceExpression:i : I
+
+Conversions:
+i.f() -> $
+i.f() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/test.java
new file mode 100644
index 000000000000..41db920f7120
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t133/after/test.java
@@ -0,0 +1,33 @@
+interface I {
+ void f();
+}
+
+interface J extends I {
+ void g();
+}
+
+public interface Test {
+ void h(I i);
+}
+
+class B implements Test {
+ @Override
+ public void h(I i) {
+ i.f();
+ }
+}
+
+class C extends B {
+ @Override
+ public void h(I i) {
+ i.f();
+ }
+}
+
+abstract class F implements Test {}
+
+class FF extends F {
+ @Override
+ public void h(I i) {
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t133/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t133/before/test.java
new file mode 100644
index 000000000000..5599c1a59b46
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t133/before/test.java
@@ -0,0 +1,33 @@
+interface I {
+ void f();
+}
+
+interface J extends I {
+ void g();
+}
+
+public interface Test {
+ void h(J i);
+}
+
+class B implements Test {
+ @Override
+ public void h(J i) {
+ i.f();
+ }
+}
+
+class C extends B {
+ @Override
+ public void h(J i) {
+ i.f();
+ }
+}
+
+abstract class F implements Test {}
+
+class FF extends F {
+ @Override
+ public void h(J i) {
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/Test.items
new file mode 100644
index 000000000000..2880fefdc224
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiLocalVariable:i : java.lang.String
+PsiParameter:a : java.lang.String
+PsiReferenceExpression:a : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/test.java
new file mode 100644
index 000000000000..26cb24f419d2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t134/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void buzz(final String a, final int b, final int c) {
+ String i = a + b + c;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t134/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t134/before/test.java
new file mode 100644
index 000000000000..7a7760404f36
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t134/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void buzz(final int a, final int b, final int c) {
+ int i = a + b + c;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/Test.items
new file mode 100644
index 000000000000..4e20b05def59
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/Test.items
@@ -0,0 +1,16 @@
+Types:
+PsiField:bar : int
+PsiField:foo : int
+PsiParameter:bar : int
+PsiParameter:foo : int
+PsiReferenceExpression:bar : int
+PsiReferenceExpression:bar : int
+PsiReferenceExpression:foo : int
+PsiReferenceExpression:foo : int
+PsiReferenceExpression:this.bar : int
+PsiReferenceExpression:this.foo : int
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/test.java
new file mode 100644
index 000000000000..c992fd8569bf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t135/after/test.java
@@ -0,0 +1,19 @@
+class Test {
+ private int foo, bar;
+
+ public long getFoo() {
+ return foo;
+ }
+
+ public void setFoo(int foo) {
+ this.foo = foo;
+ }
+
+ public long getBar() {
+ return bar;
+ }
+
+ public void setBar(int bar) {
+ this.bar = bar;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t135/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t135/before/test.java
new file mode 100644
index 000000000000..756e9380835d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t135/before/test.java
@@ -0,0 +1,19 @@
+class Test {
+ private long foo, bar;
+
+ public long getFoo() {
+ return foo;
+ }
+
+ public void setFoo(long foo) {
+ this.foo = foo;
+ }
+
+ public long getBar() {
+ return bar;
+ }
+
+ public void setBar(long bar) {
+ this.bar = bar;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/Test.items
new file mode 100644
index 000000000000..617357a07275
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/Test.items
@@ -0,0 +1,17 @@
+Types:
+PsiLocalVariable:ints : java.util.ArrayList<java.lang.String>
+PsiMethodCallExpression:ints.add(i) : boolean
+PsiNewExpression:new ArrayList<Integer>() : java.util.ArrayList<java.lang.String>
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:i : java.lang.String
+PsiReferenceExpression:i : java.lang.String
+PsiReferenceExpression:ints : java.util.ArrayList<java.lang.String>
+PsiReferenceExpression:ints : java.util.ArrayList<java.lang.String>
+
+Conversions:
+i -> $
+ints.add(i) -> $
+
+New expression type changes:
+new ArrayList<Integer>() -> java.util.ArrayList<java.lang.String>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/test.java
new file mode 100644
index 000000000000..08185f4c079c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t136/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+ private void foo(String i) {
+ ArrayList<String> ints = new ArrayList<>();
+ ints.add(i);
+ Object j = constantaB == null ? ints : i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t136/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t136/before/test.java
new file mode 100644
index 000000000000..e66f3a5f5bfa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t136/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+ private void foo(Integer i) {
+ ArrayList<Integer> ints = new ArrayList<Integer>();
+ ints.add(i);
+ Object j = constantaB == null ? ints : i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/Test.items
new file mode 100644
index 000000000000..01da876f7e94
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:i : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+i[0]->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/test.java
new file mode 100644
index 000000000000..b2d59c1303dc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t137/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ private void foo(String i) {
+ int p = i[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t137/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t137/before/test.java
new file mode 100644
index 000000000000..832535bc9440
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t137/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ private void foo(int i) {
+ int p = i[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/Test.items
new file mode 100644
index 000000000000..176574ab1bc0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:set : java.util.Collection<java.lang.String>
+PsiReferenceExpression:set : java.util.Collection<java.lang.String>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/test.java
new file mode 100644
index 000000000000..141e122e2ccc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t138/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ Set<String> mySet = new HashSet();
+ void foo(Collection<String> set) {
+ mySet.retainAll(set);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t138/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t138/before/test.java
new file mode 100644
index 000000000000..28feb3c90d4a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t138/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ Set<String> mySet = new HashSet();
+ void foo(Set<String> set) {
+ mySet.retainAll(set);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/Test.items
new file mode 100644
index 000000000000..2fbe632fa578
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/Test.items
@@ -0,0 +1,7 @@
+Types:
+PsiParameter:s : java.lang.Integer
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/test.java
new file mode 100644
index 000000000000..d91661b68309
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t139/after/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+
+abstract class A implements Iterable<String> {}
+
+class Test {
+ void test(A it) {
+ for(Integer s : it) {
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t139/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t139/before/test.java
new file mode 100644
index 000000000000..f937525f52e2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t139/before/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+
+abstract class A implements Iterable<String> {}
+
+class Test {
+ void test(A it) {
+ for(String s : it) {
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/Test.items
new file mode 100644
index 000000000000..21635daebc66
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:f : A
+PsiMethodCallExpression:f.foo() : int
+PsiReferenceExpression:f : A
+
+Conversions:
+f.foo() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/test.java
new file mode 100644
index 000000000000..de034ae20adf
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t14/after/test.java
@@ -0,0 +1,13 @@
+public class Test {
+ A f;
+ int bar(){
+ return f.foo();
+ }
+}
+class A {
+ int foo(){
+ return 0;
+ }
+}
+
+class B extends A{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t14/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t14/before/test.java
new file mode 100644
index 000000000000..8f6feeba681d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t14/before/test.java
@@ -0,0 +1,13 @@
+public class Test {
+ B f;
+ int bar(){
+ return f.foo();
+ }
+}
+class A {
+ int foo(){
+ return 0;
+ }
+}
+
+class B extends A{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/Test.items
new file mode 100644
index 000000000000..31ff4b94b421
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : A
+PsiMethodCallExpression:f.foo(f) : int
+PsiReferenceExpression:f : A
+PsiReferenceExpression:f : A
+
+Conversions:
+f.foo(f) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/test.java
new file mode 100644
index 000000000000..dcc5808448d5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t15/after/test.java
@@ -0,0 +1,16 @@
+public class Test {
+ A f;
+ int bar(){
+ return f.foo(f);
+ }
+}
+class A {
+ /**
+ * @param a
+ */
+ int foo(A a){
+ return 0;
+ }
+}
+
+class B extends A{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t15/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t15/before/test.java
new file mode 100644
index 000000000000..b22cc32ea85b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t15/before/test.java
@@ -0,0 +1,16 @@
+public class Test {
+ B f;
+ int bar(){
+ return f.foo(f);
+ }
+}
+class A {
+ /**
+ * @param a
+ */
+ int foo(A a){
+ return 0;
+ }
+}
+
+class B extends A{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/Test.items
new file mode 100644
index 000000000000..c0038308e560
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:f : B
+PsiMethodCallExpression:f.foo(f) : B
+PsiReferenceExpression:f : B
+PsiReferenceExpression:f : B
+
+Conversions:
+f -> $
+f.foo(f) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/test.java
new file mode 100644
index 000000000000..8c87396bcb3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t16/after/test.java
@@ -0,0 +1,15 @@
+class Test {
+ B f;
+
+ A bar() {
+ return f.foo(f);
+ }
+}
+class A {
+ <T> T foo(T t) {
+ return t;
+ }
+}
+
+class B extends A {
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t16/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t16/before/test.java
new file mode 100644
index 000000000000..c401bf03de20
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t16/before/test.java
@@ -0,0 +1,15 @@
+class Test {
+ A f;
+
+ A bar() {
+ return f.foo(f);
+ }
+}
+class A {
+ <T> T foo(T t) {
+ return t;
+ }
+}
+
+class B extends A {
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/Test.items
new file mode 100644
index 000000000000..aa0aa0551659
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/Test.items
@@ -0,0 +1,18 @@
+Types:
+PsiField:f : B
+PsiMethodCallExpression:f.foo(s) : B
+PsiMethodCallExpression:s.add(f) : boolean
+PsiParameter:s : java.util.Set<B>
+PsiReferenceExpression:f : B
+PsiReferenceExpression:f : B
+PsiReferenceExpression:s : java.util.Set<B>
+PsiReferenceExpression:s : java.util.Set<B>
+
+Conversions:
+f -> $
+f.foo(s) -> $
+s -> $
+s.add(f) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/test.java
new file mode 100644
index 000000000000..73530057f21b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t17/after/test.java
@@ -0,0 +1,17 @@
+import java.util.*;
+class Test {
+ B f;
+
+ A bar(Set<B> s) {
+ s.add(f);
+ return f.foo(s);
+ }
+}
+class A {
+ <T> T foo(Set<T> t) {
+ return null;
+ }
+}
+
+class B extends A {
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t17/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t17/before/test.java
new file mode 100644
index 000000000000..a425495c6065
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t17/before/test.java
@@ -0,0 +1,17 @@
+import java.util.*;
+class Test {
+ A f;
+
+ A bar(Set<A> s) {
+ s.add(f);
+ return f.foo(s);
+ }
+}
+class A {
+ <T> T foo(Set<T> t) {
+ return null;
+ }
+}
+
+class B extends A {
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/Test.items
new file mode 100644
index 000000000000..2f426a4bb9b0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : B
+PsiReferenceExpression:f : B
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/test.java
new file mode 100644
index 000000000000..35d9b61c1045
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t18/after/test.java
@@ -0,0 +1,11 @@
+import java.util.*;
+class Test {
+ B f;
+ void bar(Set<A> s) {
+ for (String s : f) {}
+ }
+}
+
+class A<Y> extends List<String> {}
+
+class B extends A<Integer> {} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t18/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t18/before/test.java
new file mode 100644
index 000000000000..3113a46d5dc6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t18/before/test.java
@@ -0,0 +1,11 @@
+import java.util.*;
+class Test {
+ A f;
+ void bar(Set<A> s) {
+ for (String s : f) {}
+ }
+}
+
+class A<Y> extends List<String> {}
+
+class B extends A<Integer> {} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/Test.items
new file mode 100644
index 000000000000..a2ec06ad3634
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.util.HashMap<java.lang.Integer,java.lang.Integer>
+PsiLocalVariable:s : java.util.Set<java.lang.Integer>
+PsiMethodCallExpression:f.keySet() : java.util.Set<java.lang.Integer>
+PsiReferenceExpression:f : java.util.HashMap<java.lang.Integer,java.lang.Integer>
+
+Conversions:
+f.keySet() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/test.java
new file mode 100644
index 000000000000..9609791bb138
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t19/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ HashMap<Integer, Integer> f;
+ void foo() {
+ Set<Integer> s = f.keySet();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t19/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t19/before/test.java
new file mode 100644
index 000000000000..815f0ed1ab3a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t19/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ Map<String, String> f;
+ void foo() {
+ Set<String> s = f.keySet();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/Test.items
new file mode 100644
index 000000000000..c97038d663ce
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.util.Map<java.lang.String,java.lang.String>
+PsiLocalVariable:s : java.util.Set<java.lang.String>
+PsiMethodCallExpression:f.keySet() : java.util.Set<java.lang.String>
+PsiReferenceExpression:f : java.util.Map<java.lang.String,java.lang.String>
+
+Conversions:
+f.keySet() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/test.java
new file mode 100644
index 000000000000..815f0ed1ab3a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t20/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ Map<String, String> f;
+ void foo() {
+ Set<String> s = f.keySet();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t20/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t20/before/test.java
new file mode 100644
index 000000000000..9609791bb138
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t20/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ HashMap<Integer, Integer> f;
+ void foo() {
+ Set<Integer> s = f.keySet();
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/Test.items
new file mode 100644
index 000000000000..53630275ac1c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/Test.items
@@ -0,0 +1,14 @@
+Types:
+PsiField:f : java.util.Map<java.lang.String,java.util.Set<java.lang.String>>
+PsiLocalVariable:stringList : java.util.Set<java.lang.String>
+PsiMethodCallExpression:f.get(s) : java.util.Set<java.lang.String>
+PsiMethodCallExpression:stringList.add(s) : boolean
+PsiReferenceExpression:f : java.util.Map<java.lang.String,java.util.Set<java.lang.String>>
+PsiReferenceExpression:stringList : java.util.Set<java.lang.String>
+
+Conversions:
+f.get(s) -> $
+stringList.add(s) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/test.java
new file mode 100644
index 000000000000..34e758cb64d6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t21/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+ Map<String, Set<String>> f;
+ void foo(String s) {
+ Set<String> stringList = f.get(s);
+ stringList.add(s);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t21/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t21/before/test.java
new file mode 100644
index 000000000000..1f647aff2488
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t21/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+class Test {
+ Map<String, List<String>> f;
+ void foo(String s) {
+ List<String> stringList = f.get(s);
+ stringList.add(s);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/Test.items
new file mode 100644
index 000000000000..e8b61ea780ac
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:f : java.lang.Integer
+PsiParameter:s : java.lang.Integer
+PsiReferenceExpression:f : java.lang.Integer
+
+Conversions:
+f -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/test.java
new file mode 100644
index 000000000000..affc2b3da86f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t22/after/test.java
@@ -0,0 +1,8 @@
+class Test {
+ Integer f;
+ void foo(Integer s) {}
+
+ void bar() {
+ foo(f);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t22/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t22/before/test.java
new file mode 100644
index 000000000000..24b0b43cb5a2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t22/before/test.java
@@ -0,0 +1,8 @@
+class Test {
+ String f;
+ void foo(String... s) {}
+
+ void bar() {
+ foo(f);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/Test.items
new file mode 100644
index 000000000000..99507129472e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/Test.items
@@ -0,0 +1,22 @@
+Types:
+PsiField:f : HashMap<java.lang.String,java.util.List<java.lang.String>>
+PsiLocalVariable:set : java.util.List<java.lang.String>
+PsiMethodCallExpression:f.get(s) : java.util.List<java.lang.String>
+PsiMethodCallExpression:f.put(s, set) : java.util.List<java.lang.String>
+PsiMethodCallExpression:set.add(s1) : boolean
+PsiReferenceExpression:f : HashMap<java.lang.String,java.util.List<java.lang.String>>
+PsiReferenceExpression:f : HashMap<java.lang.String,java.util.List<java.lang.String>>
+PsiReferenceExpression:set : java.util.List<java.lang.String>
+PsiReferenceExpression:set : java.util.List<java.lang.String>
+PsiReferenceExpression:set : java.util.List<java.lang.String>
+PsiReferenceExpression:set : java.util.List<java.lang.String>
+
+Conversions:
+f.get(s) -> $
+f.put(s, set) -> $
+set -> $
+set.add(s1) -> $
+
+New expression type changes:
+Fails:
+new HashSet<String>()->java.util.List<java.lang.String>
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/test.java
new file mode 100644
index 000000000000..df9ad40dc0e9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t23/after/test.java
@@ -0,0 +1,15 @@
+import java.util.*;
+class Test {
+ HashMap<String, List<String>> f;
+
+ void foo(String s, String s1) {
+ List<String> set = f.get(s);
+ if (set == null) {
+ set = new HashSet<String>();
+ f.put(s, set);
+ }
+ set.add(s1);
+ }
+}
+
+class HashMap<K, V> extends java.util.HashMap<K, V>{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t23/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t23/before/test.java
new file mode 100644
index 000000000000..a99eafcc46dc
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t23/before/test.java
@@ -0,0 +1,15 @@
+import java.util.*;
+class Test {
+ HashMap<String, Set<String>> f;
+
+ void foo(String s, String s1) {
+ Set<String> set = f.get(s);
+ if (set == null) {
+ set = new HashSet<String>();
+ f.put(s, set);
+ }
+ set.add(s1);
+ }
+}
+
+class HashMap<K, V> extends java.util.HashMap<K, V>{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/Test.items
new file mode 100644
index 000000000000..21962d201ce2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : D
+PsiReferenceExpression:f : D
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/test.java
new file mode 100644
index 000000000000..6e0abdb55348
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t24/after/test.java
@@ -0,0 +1,14 @@
+public class Test {
+ D f;
+ C foo() {
+ return null;
+ }
+}
+class B extends Test {
+ C foo() {
+ return f;
+ }
+}
+
+class C {}
+class D extends C{}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t24/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t24/before/test.java
new file mode 100644
index 000000000000..536dfc3ebd30
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t24/before/test.java
@@ -0,0 +1,14 @@
+public class Test {
+ C f;
+ C foo() {
+ return null;
+ }
+}
+class B extends Test {
+ C foo() {
+ return f;
+ }
+}
+
+class C {}
+class D extends C{}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/Test.items
new file mode 100644
index 000000000000..21962d201ce2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : D
+PsiReferenceExpression:f : D
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/test.java
new file mode 100644
index 000000000000..b06e456332d8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t25/after/test.java
@@ -0,0 +1,15 @@
+public class Test {
+ D f;
+ C foo() {
+ return f;
+ }
+}
+
+class B extends Test {
+ C foo() {
+ return null;
+ }
+}
+
+class C {}
+class D extends C{}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t25/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t25/before/test.java
new file mode 100644
index 000000000000..2994877fade8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t25/before/test.java
@@ -0,0 +1,15 @@
+public class Test {
+ C f;
+ C foo() {
+ return f;
+ }
+}
+
+class B extends Test {
+ C foo() {
+ return null;
+ }
+}
+
+class C {}
+class D extends C{}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/Test.items
new file mode 100644
index 000000000000..eae7ba330dd9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : D
+PsiParameter:c : D
+PsiParameter:c : D
+PsiReferenceExpression:c : D
+PsiReferenceExpression:f : D
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/test.java
new file mode 100644
index 000000000000..ee47caa11464
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t26/after/test.java
@@ -0,0 +1,15 @@
+class Test {
+ D f;
+ void foo(D c) {
+ f = c;
+ }
+}
+
+class B extends Test {
+ void foo(D c) {
+
+ }
+}
+
+class C {}
+class D extends C{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t26/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t26/before/test.java
new file mode 100644
index 000000000000..581f5fa3bc83
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t26/before/test.java
@@ -0,0 +1,15 @@
+class Test {
+ C f;
+ void foo(C c) {
+ f = c;
+ }
+}
+
+class B extends Test {
+ void foo(C c) {
+
+ }
+}
+
+class C {}
+class D extends C{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/Test.items
new file mode 100644
index 000000000000..eae7ba330dd9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : D
+PsiParameter:c : D
+PsiParameter:c : D
+PsiReferenceExpression:c : D
+PsiReferenceExpression:f : D
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/test.java
new file mode 100644
index 000000000000..5eb0cb2d97b9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t27/after/test.java
@@ -0,0 +1,13 @@
+class Test {
+ D f;
+ void foo(D c) {}
+}
+
+class B extends Test {
+ void foo(D c) {
+ f = c;
+ }
+}
+
+class C {}
+class D extends C{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t27/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t27/before/test.java
new file mode 100644
index 000000000000..a18da122856d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t27/before/test.java
@@ -0,0 +1,13 @@
+class Test {
+ C f;
+ void foo(C c) {}
+}
+
+class B extends Test {
+ void foo(C c) {
+ f = c;
+ }
+}
+
+class C {}
+class D extends C{} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/Test.items
new file mode 100644
index 000000000000..80d6c0c3bf37
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/Test.items
@@ -0,0 +1,13 @@
+Types:
+PsiField:f : java.lang.String[]
+PsiMethodCallExpression:f.size() : int
+PsiMethodCallExpression:f.toArray(new String[f.size()]) : java.lang.String[]
+PsiReferenceExpression:f : java.lang.String[]
+PsiReferenceExpression:f : java.lang.String[]
+
+Conversions:
+f.size() -> $qualifier$.length $qualifier$.size()
+f.toArray(new String[f.size()]) -> $qualifier$ $qualifier$.toArray($expr$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/test.java
new file mode 100644
index 000000000000..0b1e27daa0ee
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t28/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ String[] f;
+ String[] get() {
+ return f;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t28/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t28/before/test.java
new file mode 100644
index 000000000000..43c040a3baf4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t28/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<String> f;
+ String[] get() {
+ return f.toArray(new String[f.size()]);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/Test.items
new file mode 100644
index 000000000000..5b040a6aaa19
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiMethod:get : java.util.List<java.lang.String>
+
+Conversions:
+f.toArray(new String[f.size()]) -> $qualifier$ $qualifier$.toArray($expr$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/test.java
new file mode 100644
index 000000000000..23a1f11f461e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t29/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<String> f;
+ List<String> get() {
+ return f;
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t29/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t29/before/test.java
new file mode 100644
index 000000000000..43c040a3baf4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t29/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<String> f;
+ String[] get() {
+ return f.toArray(new String[f.size()]);
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/Test.items
new file mode 100644
index 000000000000..cfd748933e5d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:f : java.lang.String[]
+PsiMethodCallExpression:f.size() : int
+PsiReferenceExpression:f : java.lang.String[]
+
+Conversions:
+f.size() -> $qualifier$.length $qualifier$.size()
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/test.java
new file mode 100644
index 000000000000..28f71fc98c82
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t30/after/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+class Test {
+ String[] f;
+ void foo() {
+ for (int i = 0; i < f.length; i++) {
+
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t30/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t30/before/test.java
new file mode 100644
index 000000000000..5317e2164e7b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t30/before/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+class Test {
+ List<String> f;
+ void foo() {
+ for (int i = 0; i < f.size(); i++) {
+
+ }
+ }
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/Test.items
new file mode 100644
index 000000000000..7459a22f27d0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.lang.Object
+PsiReferenceExpression:f : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
+f->java.lang.Object
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/test.java
new file mode 100644
index 000000000000..ec7fb8e9807d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t31/after/test.java
@@ -0,0 +1,8 @@
+class Test {
+ Object f;
+ void foo(){}
+
+ void bar() {
+ f.foo();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t31/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t31/before/test.java
new file mode 100644
index 000000000000..b8c08fdfd786
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t31/before/test.java
@@ -0,0 +1,8 @@
+class Test {
+ Test f;
+ void foo(){}
+
+ void bar() {
+ f.foo();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/Test.items
new file mode 100644
index 000000000000..5638ea15f4a6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:i : int
+
+Conversions:
+#bar(long) -> PsiMethod:bar
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/test.java
new file mode 100644
index 000000000000..27e7eeb25258
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t32/after/test.java
@@ -0,0 +1,7 @@
+/**
+* {@link #bar(int)}
+*/
+class Test {
+
+ void bar(int i) {}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t32/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t32/before/test.java
new file mode 100644
index 000000000000..a98179d5054c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t32/before/test.java
@@ -0,0 +1,7 @@
+/**
+* {@link #bar(long)}
+*/
+class Test {
+
+ void bar(long i) {}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/Test.items
new file mode 100644
index 000000000000..df8f4d2c09d4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:l : java.util.List<java.lang.Integer>
+PsiNewExpression:new ArrayList<String>() : java.util.ArrayList<java.lang.Integer>
+PsiReferenceExpression:l : java.util.List<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+new ArrayList<String>() -> java.util.ArrayList<java.lang.Integer>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/test.java
new file mode 100644
index 000000000000..126292ad9322
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t33/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<Integer> l;
+ void foo() {
+ l = new ArrayList<>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t33/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t33/before/test.java
new file mode 100644
index 000000000000..f604f9185e2d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t33/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<String> l;
+ void foo() {
+ l = new ArrayList<String>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/Test.items
new file mode 100644
index 000000000000..d9f0bafc62d7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:l : java.util.AbstractList<java.lang.String>
+PsiNewExpression:new ArrayList<String>() : java.util.ArrayList<java.lang.String>
+PsiReferenceExpression:l : java.util.AbstractList<java.lang.String>
+
+Conversions:
+
+New expression type changes:
+new ArrayList<String>() -> java.util.ArrayList<java.lang.String>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/test.java
new file mode 100644
index 000000000000..954f507013c6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t34/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ AbstractList<String> l;
+ void foo() {
+ l = new ArrayList<>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t34/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t34/before/test.java
new file mode 100644
index 000000000000..f604f9185e2d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t34/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List<String> l;
+ void foo() {
+ l = new ArrayList<String>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/Test.items
new file mode 100644
index 000000000000..2b28dc8c0984
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:myParent : TestImpl
+PsiParameter:parent : TestImpl
+PsiParameter:parent : TestImpl
+PsiReferenceExpression:myParent : TestImpl
+PsiReferenceExpression:parent : TestImpl
+PsiReferenceExpression:parent : TestImpl
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/test.java
new file mode 100644
index 000000000000..b575a53519c4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t35/after/test.java
@@ -0,0 +1,13 @@
+class Test {
+ TestImpl myParent;
+
+ public Test(TestImpl parent) {
+ myParent = parent;
+ }
+
+ class TestImpl extends Test {
+ public TestImpl(TestImpl parent) {
+ super(parent);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t35/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t35/before/test.java
new file mode 100644
index 000000000000..83f66b0bea7c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t35/before/test.java
@@ -0,0 +1,13 @@
+class Test {
+ Test myParent;
+
+ public Test(Test parent) {
+ myParent = parent;
+ }
+
+ class TestImpl extends Test {
+ public TestImpl(Test parent) {
+ super(parent);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/Test.items
new file mode 100644
index 000000000000..521251a0dd37
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:i : byte
+PsiReferenceExpression:i : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/test.java
new file mode 100644
index 000000000000..8fd62fdc775d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t36/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void foo(byte i) {
+ long j = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t36/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t36/before/test.java
new file mode 100644
index 000000000000..1cbff3a1272c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t36/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void foo(int i) {
+ long j = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/Test.items
new file mode 100644
index 000000000000..26c064a26ffa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiParameter:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/test.java
new file mode 100644
index 000000000000..032dc398e040
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t37/after/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(int i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t37/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t37/before/test.java
new file mode 100644
index 000000000000..2cc80bd340ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t37/before/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(short i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/Test.items
new file mode 100644
index 000000000000..ce5df8ea5fcb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiParameter:i : long
+PsiReferenceExpression:i : long
+PsiReferenceExpression:i : long
+PsiReferenceExpression:i : long
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/test.java
new file mode 100644
index 000000000000..7ef08a9041c0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t38/after/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(long i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t38/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t38/before/test.java
new file mode 100644
index 000000000000..7ef08a9041c0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t38/before/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(long i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/Test.items
new file mode 100644
index 000000000000..3c746805c0f1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiParameter:i : byte
+PsiReferenceExpression:i : byte
+PsiReferenceExpression:i : byte
+PsiReferenceExpression:i : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/test.java
new file mode 100644
index 000000000000..0b59f99cc084
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t39/after/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(byte i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t39/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t39/before/test.java
new file mode 100644
index 000000000000..7ef08a9041c0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t39/before/test.java
@@ -0,0 +1,7 @@
+class Test {
+ void foo(long i) {
+ int i1 = i + 1;
+ int i2 = i - 1;
+ int i3 = i >> 1;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/Test.items
new file mode 100644
index 000000000000..2aff3bd8c623
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:l : java.util.ArrayList
+PsiReferenceExpression:l : java.util.ArrayList
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/test.java
new file mode 100644
index 000000000000..83cae108fdd9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t40/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ ArrayList l;
+ void foo() {
+ l = new ArrayList();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t40/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t40/before/test.java
new file mode 100644
index 000000000000..dd72766db414
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t40/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List l;
+ void foo() {
+ l = new ArrayList();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/Test.items
new file mode 100644
index 000000000000..583812d7778b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:l : java.util.ArrayList
+PsiNewExpression:new ArrayList<String>() : java.util.ArrayList<java.lang.String>
+PsiReferenceExpression:l : java.util.ArrayList
+
+Conversions:
+
+New expression type changes:
+new ArrayList<String>() -> java.util.ArrayList<java.lang.String>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/test.java
new file mode 100644
index 000000000000..3ac0475a9e96
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t41/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ ArrayList l;
+ void foo() {
+ l = new ArrayList<String>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t41/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t41/before/test.java
new file mode 100644
index 000000000000..8b8b5018717b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t41/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List l;
+ void foo() {
+ l = new ArrayList<String>();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/Test.items
new file mode 100644
index 000000000000..d1417fa9ad32
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:l : java.util.ArrayList<java.lang.String>
+PsiNewExpression:new ArrayList() : java.util.ArrayList
+PsiReferenceExpression:l : java.util.ArrayList<java.lang.String>
+
+Conversions:
+
+New expression type changes:
+new ArrayList() -> java.util.ArrayList
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/test.java
new file mode 100644
index 000000000000..0dd8c405b1d9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t42/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ ArrayList<String> l;
+ void foo() {
+ l = new ArrayList();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t42/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t42/before/test.java
new file mode 100644
index 000000000000..dd72766db414
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t42/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+class Test {
+ List l;
+ void foo() {
+ l = new ArrayList();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/Test.items
new file mode 100644
index 000000000000..b1e94aa2143b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:o : java.lang.Long
+
+Conversions:
+l -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/test.java
new file mode 100644
index 000000000000..c386bc247acd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t43/after/test.java
@@ -0,0 +1,4 @@
+class Test {
+ long l;
+ Long o = l;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t43/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t43/before/test.java
new file mode 100644
index 000000000000..d7e1595d92bb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t43/before/test.java
@@ -0,0 +1,4 @@
+class Test {
+ long l;
+ Object o = l;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/Test.items
new file mode 100644
index 000000000000..3cae6713c3b0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:i : byte
+PsiReferenceExpression:i : byte
+
+Conversions:
+l -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/test.java
new file mode 100644
index 000000000000..60a560399b71
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t44/after/test.java
@@ -0,0 +1,7 @@
+class Test {
+ long l;
+ byte i;
+ void foo() {
+ l = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t44/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t44/before/test.java
new file mode 100644
index 000000000000..4dee20b44e33
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t44/before/test.java
@@ -0,0 +1,7 @@
+class Test {
+ long l;
+ int i;
+ void foo() {
+ l = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/Test.items
new file mode 100644
index 000000000000..c97169454693
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:i : byte
+PsiField:l : byte
+PsiReferenceExpression:i : byte
+PsiReferenceExpression:l : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/test.java
new file mode 100644
index 000000000000..45fcb1f6eb1f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t45/after/test.java
@@ -0,0 +1,7 @@
+class Test {
+ byte l;
+ byte i;
+ void foo() {
+ l = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t45/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t45/before/test.java
new file mode 100644
index 000000000000..4dee20b44e33
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t45/before/test.java
@@ -0,0 +1,7 @@
+class Test {
+ long l;
+ int i;
+ void foo() {
+ l = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/Test.items
new file mode 100644
index 000000000000..934d4a09ec3b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:j : int
+
+Conversions:
+i -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/test.java
new file mode 100644
index 000000000000..f77f19689836
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t46/after/test.java
@@ -0,0 +1,4 @@
+class Test {
+ byte i;
+ int j = i;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t46/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t46/before/test.java
new file mode 100644
index 000000000000..5256726fdd95
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t46/before/test.java
@@ -0,0 +1,4 @@
+class Test {
+ byte i;
+ long j = i;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/Test.items
new file mode 100644
index 000000000000..d39a160ee9a7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:o : int
+
+Conversions:
+
+New expression type changes:
+Fails:
+null->int
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/test.java
new file mode 100644
index 000000000000..99f4d773fd24
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t47/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ int o = null;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t47/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t47/before/test.java
new file mode 100644
index 000000000000..308305e1cb41
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t47/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Object o = null;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/Test.items
new file mode 100644
index 000000000000..fedb3311ad6b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiLocalVariable:set : java.util.Set<B>
+PsiParameter:s : java.util.AbstractSet<B>
+PsiReferenceExpression:s : java.util.AbstractSet<B>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/test.java
new file mode 100644
index 000000000000..60e1a9ddd8c7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t48/after/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+class Test {
+ void foo(AbstractSet<B> s) {
+ Set<B> set = s;
+ }
+
+ class A {}
+ class B extends A{}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t48/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t48/before/test.java
new file mode 100644
index 000000000000..e859716610c8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t48/before/test.java
@@ -0,0 +1,9 @@
+import java.util.*;
+class Test {
+ void foo(AbstractSet<A> s) {
+ Set<A> set = s;
+ }
+
+ class A {}
+ class B extends A{}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/Test.items
new file mode 100644
index 000000000000..b65d6bce02d1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:f : java.util.Set<B>
+PsiParameter:s : java.util.AbstractSet<B>
+PsiReferenceExpression:f : java.util.Set<B>
+PsiReferenceExpression:s : java.util.AbstractSet<B>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/test.java
new file mode 100644
index 000000000000..91c41afa26e2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t49/after/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+ Set<B> f;
+ void foo(AbstractSet<B> s) {
+ f = s;
+ }
+
+ class A {}
+ class B extends A{}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t49/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t49/before/test.java
new file mode 100644
index 000000000000..8a2a9a9054ce
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t49/before/test.java
@@ -0,0 +1,10 @@
+import java.util.*;
+class Test {
+ Set<A> f;
+ void foo(AbstractSet<A> s) {
+ f = s;
+ }
+
+ class A {}
+ class B extends A{}
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/Test.items
new file mode 100644
index 000000000000..895bdd4d4118
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:c : java.util.Set<? extends JButton>
+PsiField:c1 : java.util.Set<? extends JButton>
+PsiReferenceExpression:c : java.util.Set<? extends JButton>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/test.java
new file mode 100644
index 000000000000..50d5fb0229ca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t50/after/test.java
@@ -0,0 +1,5 @@
+import java.util.*;
+class Test {
+ Set<? extends JButton> c;
+ Set<? extends JButton> c1 = c;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t50/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t50/before/test.java
new file mode 100644
index 000000000000..05b20ee8b1fe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t50/before/test.java
@@ -0,0 +1,5 @@
+import java.util.*;
+class Test {
+ Set<? extends JComponent> c;
+ Set<? extends JComponent> c1 = c;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/Test.items
new file mode 100644
index 000000000000..81f430c2e8ab
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:f : java.lang.Object[]
+PsiNewExpression:new String[] {"a"} : java.lang.Object[]
+
+Conversions:
+"a" -> $
+
+New expression type changes:
+new String[] {"a"} -> java.lang.Object[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/test.java
new file mode 100644
index 000000000000..bbd211f73928
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t51/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Object[] f = new Object[] {"a"};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t51/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t51/before/test.java
new file mode 100644
index 000000000000..7a9a090c342f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t51/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ String[] f = new String[] {"a"};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/Test.items
new file mode 100644
index 000000000000..fae3f5aa0b83
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.lang.Object[]
+PsiNewExpression:new Set() : java.util.Set
+PsiNewExpression:new Set[] { new Set() } : java.lang.Object[]
+
+Conversions:
+
+New expression type changes:
+new Set() -> java.util.Set
+new Set[] { new Set() } -> java.lang.Object[]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/test.java
new file mode 100644
index 000000000000..034f9e2a7285
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t52/after/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Object[] f = new Object[] { new Set() };
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t52/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t52/before/test.java
new file mode 100644
index 000000000000..abf3b7a12aff
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t52/before/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set[] f = new Set[] { new Set() };
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/Test.items
new file mode 100644
index 000000000000..6f10a470aef3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : java.util.Set<java.lang.String>[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+new double[0]->java.util.Set<java.lang.String>[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/test.java
new file mode 100644
index 000000000000..52d1899803c8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t53/after/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set<String>[] f = new double[0];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t53/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t53/before/test.java
new file mode 100644
index 000000000000..50be5aada106
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t53/before/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ double[] f = new double[0];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/Test.items
new file mode 100644
index 000000000000..584021476055
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.Set<? extends java.lang.Integer>
+PsiNewExpression:new Set<Object>() : java.util.Set<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+new Set<Object>() -> java.util.Set<java.lang.Integer>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/test.java
new file mode 100644
index 000000000000..11cbc3fe7520
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t54/after/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set<? extends Integer> f = new Set<>();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t54/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t54/before/test.java
new file mode 100644
index 000000000000..96573db084dd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t54/before/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set<Object> f = new Set<Object>();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/Test.items
new file mode 100644
index 000000000000..465e20e4a213
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.Set<?>
+PsiNewExpression:new Set<Object>() : java.util.Set<java.lang.Object>
+
+Conversions:
+
+New expression type changes:
+new Set<Object>() -> java.util.Set<java.lang.Object>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/test.java
new file mode 100644
index 000000000000..c895ff398fa6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t55/after/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set<?> f = new Set<>();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t55/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t55/before/test.java
new file mode 100644
index 000000000000..96573db084dd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t55/before/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+class Test {
+ Set<Object> f = new Set<Object>();
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/Test.items
new file mode 100644
index 000000000000..05ed851f0ce0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiParameter:i : double
+PsiReferenceExpression:i : double
+PsiReferenceExpression:i : double
+
+Conversions:
+
+New expression type changes:
+Fails:
+i->double
+i->double
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/test.java
new file mode 100644
index 000000000000..2f5cc73acbbb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t56/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ void foo(double i) {
+ int[] a = new int[i];
+ System.out.println(a[i]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t56/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t56/before/test.java
new file mode 100644
index 000000000000..0f9888806c18
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t56/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ void foo(int i) {
+ int[] a = new int[i];
+ System.out.println(a[i]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/Test.items
new file mode 100644
index 000000000000..af2ecf9c114e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:i : byte
+PsiReferenceExpression:i : byte
+PsiReferenceExpression:i : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/test.java
new file mode 100644
index 000000000000..ce9df2fbb45d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t57/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ void foo(byte i) {
+ int[] a = new int[i];
+ System.out.println(a[i]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t57/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t57/before/test.java
new file mode 100644
index 000000000000..0f9888806c18
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t57/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ void foo(int i) {
+ int[] a = new int[i];
+ System.out.println(a[i]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/Test.items
new file mode 100644
index 000000000000..19b07a44c139
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : java.lang.Object
+
+Conversions:
+new String[1] -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/test.java
new file mode 100644
index 000000000000..ff4055ac3129
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t58/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Object f = new String[1];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t58/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t58/before/test.java
new file mode 100644
index 000000000000..8df4d62d721a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t58/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ String[] f = new String[1];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/Test.items
new file mode 100644
index 000000000000..ea0dda8061b2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : java.lang.Cloneable
+
+Conversions:
+new String[1] -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/test.java
new file mode 100644
index 000000000000..78a09afee42b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t59/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Cloneable f = new String[1];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t59/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t59/before/test.java
new file mode 100644
index 000000000000..8df4d62d721a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t59/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ String[] f = new String[1];
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/Test.items
new file mode 100644
index 000000000000..88822343977c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:p : java.lang.Object
+PsiReferenceExpression:p : java.lang.Object
+
+Conversions:
+i -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/test.java
new file mode 100644
index 000000000000..9ab940eaf425
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t60/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ Object p;
+ void foo(int... i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t60/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t60/before/test.java
new file mode 100644
index 000000000000..26172c13d2e7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t60/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ int[] p;
+ void foo(int... i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/Test.items
new file mode 100644
index 000000000000..830074d65d6b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiLocalVariable:p : int[]
+PsiParameter:i : int...
+PsiReferenceExpression:i : int[]
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/test.java
new file mode 100644
index 000000000000..1b05fce5b5b9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t61/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void foo(int... i) {
+ int[] p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t61/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t61/before/test.java
new file mode 100644
index 000000000000..e9f49f1c3846
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t61/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void foo(int i) {
+ int p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/Test.items
new file mode 100644
index 000000000000..88822343977c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:p : java.lang.Object
+PsiReferenceExpression:p : java.lang.Object
+
+Conversions:
+i -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/test.java
new file mode 100644
index 000000000000..9ab940eaf425
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t62/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ Object p;
+ void foo(int... i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t62/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t62/before/test.java
new file mode 100644
index 000000000000..26172c13d2e7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t62/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ int[] p;
+ void foo(int... i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/Test.items
new file mode 100644
index 000000000000..69dcdaf945c5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiField:p : double[]
+PsiParameter:i : double[]
+PsiReferenceExpression:i : double[]
+PsiReferenceExpression:p : double[]
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/test.java
new file mode 100644
index 000000000000..9602f0b3d59f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t63/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ double[] p;
+ void foo(double[] i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t63/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t63/before/test.java
new file mode 100644
index 000000000000..26172c13d2e7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t63/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ int[] p;
+ void foo(int... i) {
+ p = i;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/Test.items
new file mode 100644
index 000000000000..8ae72a21d857
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiLocalVariable:p : int
+PsiParameter:i : int
+PsiReferenceExpression:i : int
+
+Conversions:
+
+New expression type changes:
+Fails:
+foo(1, 2)->int
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/test.java
new file mode 100644
index 000000000000..29f4004383eb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t64/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(int i) {
+ int p = i;
+ }
+
+ void bar() {
+ foo(1, 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t64/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t64/before/test.java
new file mode 100644
index 000000000000..5583e3c06a5d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t64/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(int... i) {
+ int[] p = i;
+ }
+
+ void bar() {
+ foo(1, 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/Test.items
new file mode 100644
index 000000000000..a1201587163f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiLocalVariable:p : java.lang.String
+PsiParameter:i : java.lang.String
+PsiReferenceExpression:i : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+1->java.lang.String
+2->java.lang.String
+foo(1, 2)->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/test.java
new file mode 100644
index 000000000000..3532ce557f8c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t65/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(String i) {
+ String p = i;
+ }
+
+ void bar() {
+ foo(1, 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t65/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t65/before/test.java
new file mode 100644
index 000000000000..5583e3c06a5d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t65/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(int... i) {
+ int[] p = i;
+ }
+
+ void bar() {
+ foo(1, 2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/Test.items
new file mode 100644
index 000000000000..f8bf3a92ff7d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiLocalVariable:p : int
+PsiParameter:i : int
+PsiReferenceExpression:i : int
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/test.java
new file mode 100644
index 000000000000..56608039cf5e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t66/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(int i) {
+ int p = i;
+ }
+
+ void bar() {
+ foo(1);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t66/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t66/before/test.java
new file mode 100644
index 000000000000..45ea51dddf11
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t66/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ void foo(int... i) {
+ int[] p = i;
+ }
+
+ void bar() {
+ foo(1);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/Test.items
new file mode 100644
index 000000000000..0e5e72eb6f30
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:myForAccess : java.lang.String
+PsiMethod:forAccess : java.lang.String
+PsiMethodCallExpression:this.forAccess() : java.lang.String
+PsiParameter:p : java.lang.String
+PsiReferenceExpression:myForAccess : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/test.java
new file mode 100644
index 000000000000..8a4fda4a0fac
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t67/after/test.java
@@ -0,0 +1,9 @@
+class Test {
+ private String myForAccess;
+ private String forAccess() {
+ return myForAccess;
+ }
+ public void methMemAcc(String p) {
+ p = this.forAccess();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t67/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t67/before/test.java
new file mode 100644
index 000000000000..57a1c5db091b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t67/before/test.java
@@ -0,0 +1,9 @@
+class Test {
+ private Object myForAccess;
+ private Object forAccess() {
+ return myForAccess;
+ }
+ public void methMemAcc(Object p) {
+ p = this.forAccess();
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/Test.items
new file mode 100644
index 000000000000..e31709e870fb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/Test.items
@@ -0,0 +1,17 @@
+Types:
+PsiArrayInitializerExpression:{p} : double[]
+PsiArrayInitializerExpression:{p} : double[]
+PsiArrayInitializerExpression:{{p},{p}} : double[][]
+PsiLocalVariable:a : double[][]
+PsiNewExpression:new int[][]{{p},{p}} : double[][]
+PsiParameter:p : double
+PsiReferenceExpression:p : double
+PsiReferenceExpression:p : double
+
+Conversions:
+p -> $
+p -> $
+
+New expression type changes:
+new int[][]{{p},{p}} -> double[][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/test.java
new file mode 100644
index 000000000000..f9d9a9257c5d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t68/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void foo(double p) {
+ double[][] a = new double[][]{{p},{p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t68/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t68/before/test.java
new file mode 100644
index 000000000000..9f84d15cc993
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t68/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void foo(int p) {
+ int[][] a = new int[][]{{p},{p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/Test.items
new file mode 100644
index 000000000000..6471629f221e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : byte
+PsiReferenceExpression:p : byte
+PsiReferenceExpression:p : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/test.java
new file mode 100644
index 000000000000..bba00df7f5ed
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t69/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void foo(byte p) {
+ int[][] a = new int[][]{{p},{p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t69/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t69/before/test.java
new file mode 100644
index 000000000000..9f84d15cc993
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t69/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void foo(int p) {
+ int[][] a = new int[][]{{p},{p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/Test.items
new file mode 100644
index 000000000000..9811dea4870e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/Test.items
@@ -0,0 +1,18 @@
+Types:
+PsiArrayInitializerExpression:{p} : float[]
+PsiArrayInitializerExpression:{p} : float[]
+PsiArrayInitializerExpression:{{p}, {p}} : float[][]
+PsiField:a : float[][]
+PsiNewExpression:new int[][]{{p}, {p}} : float[][]
+PsiParameter:p : float
+PsiReferenceExpression:a : float[][]
+PsiReferenceExpression:p : float
+PsiReferenceExpression:p : float
+
+Conversions:
+p -> $
+p -> $
+
+New expression type changes:
+new int[][]{{p}, {p}} -> float[][]
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/test.java
new file mode 100644
index 000000000000..7ef5f832a7d9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t70/after/test.java
@@ -0,0 +1,6 @@
+class Test {
+ float[][] a;
+ public void foo(float p) {
+ a = new float[][]{{p}, {p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t70/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t70/before/test.java
new file mode 100644
index 000000000000..d98804a2576f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t70/before/test.java
@@ -0,0 +1,6 @@
+class Test {
+ int[][] a;
+ public void foo(int p) {
+ a = new int[][]{{p}, {p}};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/Test.items
new file mode 100644
index 000000000000..f65db392b622
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : java.lang.Class<? extends java.lang.Number>
+
+Conversions:
+byte.class -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/test.java
new file mode 100644
index 000000000000..be0143bbaafb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t71/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Class<? extends Number> f = byte.class;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t71/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t71/before/test.java
new file mode 100644
index 000000000000..e3c0a3aecee2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t71/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Class f = byte.class;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/Test.items
new file mode 100644
index 000000000000..cacd1729289d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f : java.lang.Class<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+Fails:
+byte.class->java.lang.Class<java.lang.Integer>
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/test.java
new file mode 100644
index 000000000000..ace9fbcc92a8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t72/after/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Class<Integer> f = byte.class;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t72/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t72/before/test.java
new file mode 100644
index 000000000000..e3c0a3aecee2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t72/before/test.java
@@ -0,0 +1,3 @@
+class Test {
+ Class f = byte.class;
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/Test.items
new file mode 100644
index 000000000000..f46b39d67281
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiArrayInitializerExpression:{} : java.util.Set<java.awt.Component>[]
+PsiField:f : java.util.Set<java.awt.Component>[][]
+
+Conversions:
+
+New expression type changes:
+Fails:
+new Set[][]{{}}->java.util.Set<java.awt.Component>[][]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/test.java
new file mode 100644
index 000000000000..da9d9b2e6fe8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t73/after/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+import javax.swing.*;
+import java.awt.*;
+class Test {
+ Set<Component>[][] f = new Set[][]{{}};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t73/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t73/before/test.java
new file mode 100644
index 000000000000..b07764b2c29f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t73/before/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+import javax.swing.*;
+import java.awt.*;
+class Test {
+ Set<JComponent>[][] f = new Set[][]{{}};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/Test.items
new file mode 100644
index 000000000000..236f769a7b98
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/Test.items
@@ -0,0 +1,22 @@
+Types:
+PsiLocalVariable:v1 : float
+PsiLocalVariable:v2 : float
+PsiLocalVariable:v3 : float
+PsiLocalVariable:v4 : float
+PsiLocalVariable:vu1 : float
+PsiLocalVariable:vu2 : float
+PsiLocalVariable:vu3 : float
+PsiParameter:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+PsiReferenceExpression:pi : float
+
+Conversions:
+
+New expression type changes:
+Fails:
+~pi->float
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/test.java
new file mode 100644
index 000000000000..25d776d7d8c6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t74/after/test.java
@@ -0,0 +1,11 @@
+class Test {
+ public void meth(float pi) {
+ float v1 = pi++;
+ float v2 = pi--;
+ float v3 = ++pi;
+ float v4 = --pi;
+ float vu1 = -pi;
+ float vu2 = +pi;
+ float vu3 = ~pi;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t74/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t74/before/test.java
new file mode 100644
index 000000000000..c6e83eedc1bd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t74/before/test.java
@@ -0,0 +1,11 @@
+class Test {
+ public void meth(int pi) {
+ int v1 = pi++;
+ int v2 = pi--;
+ int v3 = ++pi;
+ int v4 = --pi;
+ int vu1 = -pi;
+ int vu2 = +pi;
+ int vu3 = ~pi;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/Test.items
new file mode 100644
index 000000000000..9c3eb7b369e3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/Test.items
@@ -0,0 +1,38 @@
+Types:
+PsiLocalVariable:vn4 : java.lang.String
+PsiParameter:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
+pn->java.lang.String
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/test.java
new file mode 100644
index 000000000000..750c3d1d51a4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t75/after/test.java
@@ -0,0 +1,12 @@
+class Test {
+ public void meth(String pn) {
+ int vn1 = pn * pn;
+ int vn2 = pn / pn;
+ int vn3 = pn % pn;
+ String vn4 = pn + pn;
+ int vn5 = pn - pn;
+ int vn6 = pn << pn;
+ int vn7 = pn >> pn;
+ int vn8 = pn >>> pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t75/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t75/before/test.java
new file mode 100644
index 000000000000..fdde94165b43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t75/before/test.java
@@ -0,0 +1,12 @@
+class Test {
+ public void meth(byte pn) {
+ int vn1 = pn * pn;
+ int vn2 = pn / pn;
+ int vn3 = pn % pn;
+ int vn4 = pn + pn;
+ int vn5 = pn - pn;
+ int vn6 = pn << pn;
+ int vn7 = pn >> pn;
+ int vn8 = pn >>> pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/Test.items
new file mode 100644
index 000000000000..7a2163c3200b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/Test.items
@@ -0,0 +1,37 @@
+Types:
+PsiLocalVariable:vn1 : float
+PsiLocalVariable:vn2 : float
+PsiLocalVariable:vn3 : float
+PsiLocalVariable:vn4 : float
+PsiLocalVariable:vn5 : float
+PsiLocalVariable:vn6 : float
+PsiLocalVariable:vn7 : float
+PsiLocalVariable:vn8 : float
+PsiParameter:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+PsiReferenceExpression:pn : float
+
+Conversions:
+
+New expression type changes:
+Fails:
+pn->float
+pn->float
+pn->float
+pn->float
+pn->float
+pn->float
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/test.java
new file mode 100644
index 000000000000..3e6b69cf7c94
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t76/after/test.java
@@ -0,0 +1,12 @@
+class Test {
+ public void meth(float pn) {
+ float vn1 = pn * pn;
+ float vn2 = pn / pn;
+ float vn3 = pn % pn;
+ float vn4 = pn + pn;
+ float vn5 = pn - pn;
+ float vn6 = pn << pn;
+ float vn7 = pn >> pn;
+ float vn8 = pn >>> pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t76/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t76/before/test.java
new file mode 100644
index 000000000000..fdde94165b43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t76/before/test.java
@@ -0,0 +1,12 @@
+class Test {
+ public void meth(byte pn) {
+ int vn1 = pn * pn;
+ int vn2 = pn / pn;
+ int vn3 = pn % pn;
+ int vn4 = pn + pn;
+ int vn5 = pn - pn;
+ int vn6 = pn << pn;
+ int vn7 = pn >> pn;
+ int vn8 = pn >>> pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/Test.items
new file mode 100644
index 000000000000..dc0f44202f9b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:pn : java.lang.Object
+PsiReferenceExpression:pn : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
+pn->java.lang.Object
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/test.java
new file mode 100644
index 000000000000..4e8733a49d43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t77/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(Object pn, int p) {
+ p += pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t77/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t77/before/test.java
new file mode 100644
index 000000000000..252a45c4acc5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t77/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(int pn, int p) {
+ p += pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/Test.items
new file mode 100644
index 000000000000..f935ec3be774
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiParameter:p : java.lang.String
+PsiParameter:pn : java.lang.String
+PsiReferenceExpression:p : java.lang.String
+PsiReferenceExpression:pn : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/test.java
new file mode 100644
index 000000000000..573deb573d11
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t78/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(String pn, String p) {
+ p += pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t78/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t78/before/test.java
new file mode 100644
index 000000000000..252a45c4acc5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t78/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(int pn, int p) {
+ p += pn;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/Test.items
new file mode 100644
index 000000000000..9e7dba8b794e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : byte
+PsiReferenceExpression:p : byte
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/test.java
new file mode 100644
index 000000000000..37ec2cb0f5fd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t79/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(byte p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t79/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t79/before/test.java
new file mode 100644
index 000000000000..30db2da5fa91
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t79/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(int p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/Test.items
new file mode 100644
index 000000000000..55661712f811
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : double
+PsiReferenceExpression:p : double
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/test.java
new file mode 100644
index 000000000000..5fe4738b6a5e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t80/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(double p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t80/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t80/before/test.java
new file mode 100644
index 000000000000..30db2da5fa91
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t80/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(int p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/Test.items
new file mode 100644
index 000000000000..f89012c7c140
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:o : A
+PsiReferenceExpression:o : A
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/test.java
new file mode 100644
index 000000000000..55deae9424fa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t81/after/test.java
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {}
+
+class Test {
+ void foo(A o) {
+ if (o instanceof B){}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t81/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t81/before/test.java
new file mode 100644
index 000000000000..8bccf86ced7b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t81/before/test.java
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {}
+
+class Test {
+ void foo(Object o) {
+ if (o instanceof B){}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/Test.items
new file mode 100644
index 000000000000..5164a4b2f6d9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:o : C
+PsiReferenceExpression:o : C
+
+Conversions:
+
+New expression type changes:
+Fails:
+o->C
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/test.java
new file mode 100644
index 000000000000..83b747a3cb27
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t82/after/test.java
@@ -0,0 +1,11 @@
+class C{}
+
+class A {}
+
+class B extends A {}
+
+class Test {
+ void foo(C o) {
+ if (o instanceof B){}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t82/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t82/before/test.java
new file mode 100644
index 000000000000..cb617f44766f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t82/before/test.java
@@ -0,0 +1,11 @@
+class C{}
+
+class A {}
+
+class B extends A {}
+
+class Test {
+ void foo(Object o) {
+ if (o instanceof B){}
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/Test.items
new file mode 100644
index 000000000000..9f0dab259a44
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiParameter:p : java.lang.Object
+PsiReferenceExpression:p : java.lang.Object
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/test.java
new file mode 100644
index 000000000000..2a6715c81d3f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t83/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(Object p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t83/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t83/before/test.java
new file mode 100644
index 000000000000..30db2da5fa91
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t83/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ public void meth(int p) {
+ float f = (float)p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/Test.items
new file mode 100644
index 000000000000..5f64399bef41
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiLocalVariable:f : java.util.Set<? extends java.util.Set>
+PsiParameter:p : java.util.Set<? extends java.util.Set>
+PsiReferenceExpression:p : java.util.Set<? extends java.util.Set>
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/test.java
new file mode 100644
index 000000000000..b055ef3a4df9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t84/after/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class Test {
+ public void meth(Set<? extends Set> p) {
+ Set<? extends Set> f = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t84/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t84/before/test.java
new file mode 100644
index 000000000000..7c85f93d7a57
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t84/before/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+class Test {
+ public void meth(Set p) {
+ Set<Set> f = p;
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/Test.items
new file mode 100644
index 000000000000..76d7b14baa5d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:str : java.lang.Integer
+PsiMethod:get : java.lang.Integer
+PsiReferenceExpression:str : java.lang.Integer
+PsiReferenceExpression:str : java.lang.Integer
+PsiReferenceExpression:str : java.lang.Integer
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/test.java
new file mode 100644
index 000000000000..c43a426e5277
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t85/after/test.java
@@ -0,0 +1,8 @@
+public class Test {
+
+ Integer str;
+ Integer get(boolean f) {
+ return f ? str : str + str;
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t85/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t85/before/test.java
new file mode 100644
index 000000000000..adde8623a884
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t85/before/test.java
@@ -0,0 +1,8 @@
+public class Test {
+
+ String str;
+ String get(boolean f) {
+ return f ? str : str + str;
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/Test.items
new file mode 100644
index 000000000000..c2f8f1dd9fa6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/Test.items
@@ -0,0 +1,18 @@
+Types:
+PsiArrayAccessExpression:array[i] : java.lang.String
+PsiArrayAccessExpression:array[i] : java.lang.String
+PsiLocalVariable:array : java.util.List<java.lang.String>
+PsiMethod:getArray : java.util.List<java.lang.String>
+PsiMethodCallExpression:getArray() : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array.length : int
+
+Conversions:
+array.length -> $qualifier$.size() $qualifier$.length
+array[i] -> $qualifier$.get($idx$) $qualifier$[$idx$]
+array[i] -> $qualifier$.set($idx$, $expr$) $qualifier$[$idx$] = $expr$ array[i] = ""
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/test.java
new file mode 100644
index 000000000000..25f8b851603d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t86/after/test.java
@@ -0,0 +1,16 @@
+import java.util.List;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ for (int i = 0; i < array.size(); i++) {
+ System.out.println(array.get(i));
+ array.set(i, "");
+ }
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t86/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t86/before/test.java
new file mode 100644
index 000000000000..880c69463055
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t86/before/test.java
@@ -0,0 +1,16 @@
+import java.util.List;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ for (int i = 0; i < array.length; i++) {
+ System.out.println(array[i]);
+ array[i] = "";
+ }
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/Test.items
new file mode 100644
index 000000000000..45193ce9dcf4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiLocalVariable:array : java.lang.String[]
+PsiMethod:getArray : java.lang.String[]
+PsiMethodCallExpression:getArray() : java.lang.String[]
+PsiReferenceExpression:array : java.lang.String[]
+
+Conversions:
+array -> Arrays.sort($qualifier$) Collections.sort($qualifier$) Collections.sort(array)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/test.java
new file mode 100644
index 000000000000..f0e5159bfcfd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t87/after/test.java
@@ -0,0 +1,13 @@
+import java.util.*;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ Arrays.sort(array);
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t87/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t87/before/test.java
new file mode 100644
index 000000000000..12a28fa3084c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t87/before/test.java
@@ -0,0 +1,13 @@
+import java.util.*;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ Collections.sort(array);
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/Test.items
new file mode 100644
index 000000000000..60ae50f9c699
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/Test.items
@@ -0,0 +1,15 @@
+Types:
+PsiLocalVariable:array : java.util.List<java.lang.String>
+PsiMethod:getArray : java.util.List<java.lang.String>
+PsiMethodCallExpression:getArray() : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+
+Conversions:
+array -> Collections.sort($qualifier$, $expr$) Arrays.sort($qualifier$, $expr$) Arrays.sort(array, new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return 0;
+ }
+ })
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/test.java
new file mode 100644
index 000000000000..4be724c5d907
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t88/after/test.java
@@ -0,0 +1,18 @@
+import java.util.*;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ Collections.sort(array, new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return 0;
+ }
+ });
+
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t88/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t88/before/test.java
new file mode 100644
index 000000000000..ce19bd33f20e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t88/before/test.java
@@ -0,0 +1,18 @@
+import java.util.*;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ Arrays.sort(array, new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return 0;
+ }
+ });
+
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/Test.items
new file mode 100644
index 000000000000..069dfb76e5c3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiLocalVariable:array : java.lang.String[]
+PsiMethod:getArray : java.lang.String[]
+PsiMethodCallExpression:getArray() : java.lang.String[]
+PsiReferenceExpression:array : java.lang.String[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+array->java.lang.String[]
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/test.java
new file mode 100644
index 000000000000..5a625c53c286
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t89/after/test.java
@@ -0,0 +1,13 @@
+import java.util.*;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ Collections.checkedList(array, String.class);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t89/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t89/before/test.java
new file mode 100644
index 000000000000..c12161d8c76d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t89/before/test.java
@@ -0,0 +1,13 @@
+import java.util.*;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ Collections.checkedList(array, String.class);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/Test.items
new file mode 100644
index 000000000000..721469c186fa
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:l : java.util.List<A>
+PsiMethodCallExpression:b.foo() : java.util.Map<java.lang.String,java.lang.String>
+PsiParameter:b : A
+PsiReferenceExpression:b : A
+PsiReferenceExpression:l : java.util.List<A>
+
+Conversions:
+b.foo() -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/test.java
new file mode 100644
index 000000000000..06c072088b02
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t90/after/test.java
@@ -0,0 +1,24 @@
+import java.util.*;
+public class Test {
+ List<A> l;
+
+ @Override
+ Map<String, String> foo() {
+ HashMap<String, String> m = new HashMap<String, String>();
+ for (A b : l) {
+ Map<String, String> map = b.foo();
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ if (!m.containsKey(entry.getKey())) {
+ m.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ return m;
+ }
+}
+
+class A {
+ Map<String, String> foo(){return null;}
+}
+
+class B extends A {} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t90/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t90/before/test.java
new file mode 100644
index 000000000000..80afdc6aa08b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t90/before/test.java
@@ -0,0 +1,24 @@
+import java.util.*;
+public class Test {
+ List<B> l;
+
+ @Override
+ Map<String, String> foo() {
+ HashMap<String, String> m = new HashMap<String, String>();
+ for (B b : l) {
+ Map<String, String> map = b.foo();
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ if (!m.containsKey(entry.getKey())) {
+ m.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ return m;
+ }
+}
+
+class A {
+ Map<String, String> foo(){return null;}
+}
+
+class B extends A {} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/Test.items
new file mode 100644
index 000000000000..9b53aeaf2084
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiMethod:foo : java.lang.String[]
+
+Conversions:
+"" -> new java.lang.String[]{$qualifier$} $qualifier$ ""
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/test.java
new file mode 100644
index 000000000000..9575d720b844
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t91/after/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ String[] foo(){
+ return new String[]{""};
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t91/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t91/before/test.java
new file mode 100644
index 000000000000..e916bd0a5dab
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t91/before/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ String foo(){
+ return "";
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/Test.items
new file mode 100644
index 000000000000..bf241c7966a7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.List<java.lang.Integer>
+PsiNewExpression:new ArrayList<String>(){} : java.util.ArrayList<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+new ArrayList<String>(){} -> java.util.ArrayList<java.lang.Integer>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/test.java
new file mode 100644
index 000000000000..f70bc9515dea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t92/after/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+public class Test {
+ List<Integer> f = new ArrayList<Integer>(){};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t92/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t92/before/test.java
new file mode 100644
index 000000000000..89ae1f7d3101
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t92/before/test.java
@@ -0,0 +1,4 @@
+import java.util.*;
+public class Test {
+ List<String> f = new ArrayList<String>(){};
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/Test.items
new file mode 100644
index 000000000000..ea2fc9440478
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:f : java.util.Map<java.lang.Boolean,java.lang.String>
+PsiParameter:b : boolean
+PsiReferenceExpression:b : boolean
+PsiReferenceExpression:f : java.util.Map<java.lang.Boolean,java.lang.String>
+
+Conversions:
+f -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/test.java
new file mode 100644
index 000000000000..6b714f8e8862
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t93/after/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ Map<Boolean, String> f;
+
+ void foo(boolean b) {
+ f.put(b, null);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t93/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t93/before/test.java
new file mode 100644
index 000000000000..292b5f9f0361
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t93/before/test.java
@@ -0,0 +1,8 @@
+import java.util.*;
+public class Test {
+ Map<Boolean, String> f;
+
+ void foo(Boolean b) {
+ f.put(b, null);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/Test.items
new file mode 100644
index 000000000000..76ae2a02000b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/Test.items
@@ -0,0 +1,13 @@
+Types:
+PsiLocalVariable:array : java.lang.String[]
+PsiMethod:getArray : java.lang.String[]
+PsiMethodCallExpression:getArray() : java.lang.String[]
+PsiReferenceExpression:array : java.lang.String[]
+PsiReferenceExpression:array : java.lang.String[]
+
+Conversions:
+array -> Arrays.binarySearch($qualifier$, $key$) Collections.binarySearch($qualifier$, $key$) Collections.binarySearch(array, "")
+array -> Arrays.sort($qualifier$) Collections.sort($qualifier$) Collections.sort(array)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/test.java
new file mode 100644
index 000000000000..d8df3e65dd43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t94/after/test.java
@@ -0,0 +1,14 @@
+import java.util.*;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ Arrays.binarySearch(array, "");
+ Arrays.sort(array);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t94/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t94/before/test.java
new file mode 100644
index 000000000000..99bf050d6f00
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t94/before/test.java
@@ -0,0 +1,14 @@
+import java.util.*;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ Collections.binarySearch(array, "");
+ Collections.sort(array);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/Test.items
new file mode 100644
index 000000000000..d3f8033938ea
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/Test.items
@@ -0,0 +1,13 @@
+Types:
+PsiLocalVariable:array : java.util.List<java.lang.String>
+PsiMethod:getArray : java.util.List<java.lang.String>
+PsiMethodCallExpression:getArray() : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+
+Conversions:
+array -> Collections.binarySearch($qualifier$, $key$) Arrays.binarySearch($qualifier$, $key$) Arrays.binarySearch(array, "")
+array -> Collections.sort($qualifier$) Arrays.sort($qualifier$) Arrays.sort(array)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/test.java
new file mode 100644
index 000000000000..99bf050d6f00
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t95/after/test.java
@@ -0,0 +1,14 @@
+import java.util.*;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo() {
+ List<String> array = getArray();
+ Collections.binarySearch(array, "");
+ Collections.sort(array);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t95/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t95/before/test.java
new file mode 100644
index 000000000000..d8df3e65dd43
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t95/before/test.java
@@ -0,0 +1,14 @@
+import java.util.*;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo() {
+ String[] array = getArray();
+ Arrays.binarySearch(array, "");
+ Arrays.sort(array);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/Test.items
new file mode 100644
index 000000000000..d107b7626a41
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f1 : java.lang.String
+PsiField:f2 : java.lang.String
+PsiReferenceExpression:f1 : java.lang.String
+
+Conversions:
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/test.java
new file mode 100644
index 000000000000..25357fd46118
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t96/after/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ String f1 = null;
+ String f2 = f1;
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t96/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t96/before/test.java
new file mode 100644
index 000000000000..55d7110ccb83
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t96/before/test.java
@@ -0,0 +1,5 @@
+public class Test {
+ Integer f1 = null;
+ Integer f2 = f1;
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/Test.items
new file mode 100644
index 000000000000..1d376856a7ac
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/Test.items
@@ -0,0 +1,8 @@
+Types:
+PsiField:f1 : int
+
+Conversions:
+
+New expression type changes:
+Fails:
+{0}->int
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/test.java
new file mode 100644
index 000000000000..61687e78d725
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t97/after/test.java
@@ -0,0 +1,4 @@
+public class Test {
+ int f1 = {0};
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t97/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t97/before/test.java
new file mode 100644
index 000000000000..f33899c2c3d7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t97/before/test.java
@@ -0,0 +1,4 @@
+public class Test {
+ Integer[] f1 = {0};
+
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/Test.items
new file mode 100644
index 000000000000..9b5e0b6b54e9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/Test.items
@@ -0,0 +1,21 @@
+Types:
+PsiArrayAccessExpression:array[i] : java.lang.String
+PsiArrayAccessExpression:array[i] : java.lang.String
+PsiArrayAccessExpression:array[i] : java.lang.String
+PsiLocalVariable:array : java.util.List<java.lang.String>
+PsiMethod:getArray : java.util.List<java.lang.String>
+PsiMethodCallExpression:getArray() : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array : java.util.List<java.lang.String>
+PsiReferenceExpression:array.length : int
+
+Conversions:
+array.length -> $qualifier$.size() $qualifier$.length
+array[i] -> $qualifier$.get($idx$) $qualifier$[$idx$]
+array[i] -> $qualifier$.get($idx$) $qualifier$[$idx$]
+array[i] -> $qualifier$.get($idx$) $qualifier$[$idx$]
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/test.java
new file mode 100644
index 000000000000..86e1e0b4f6c2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t98/after/test.java
@@ -0,0 +1,17 @@
+import java.util.List;
+public class Test {
+
+ List<String> getArray(){
+ return null;
+ }
+
+ void foo(String param) {
+ List<String> array = getArray();
+ for (int i = 0; i < array.size(); i++) {
+ System.out.println(array.get(i));
+ String str = array.get(i);
+ param = array.get(i);
+ }
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t98/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t98/before/test.java
new file mode 100644
index 000000000000..b79f9495d4ac
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t98/before/test.java
@@ -0,0 +1,17 @@
+import java.util.List;
+public class Test {
+
+ String[] getArray(){
+ return null;
+ }
+
+ void foo(String param) {
+ String[] array = getArray();
+ for (int i = 0; i < array.length; i++) {
+ System.out.println(array[i]);
+ String str = array[i];
+ param = array[i];
+ }
+ }
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/Test.items
new file mode 100644
index 000000000000..93ca5aa6a01e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:f : java.util.Set<java.util.List<int[]>>
+PsiNewExpression:new Set<List<char[]>>() : java.util.Set<java.util.List<int[]>>
+
+Conversions:
+
+New expression type changes:
+new Set<List<char[]>>() -> java.util.Set<java.util.List<int[]>>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/test.java
new file mode 100644
index 000000000000..1f7b49a490d9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t99/after/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ Set<List<int[]>> f = new Set<>();
+
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/t99/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/t99/before/test.java
new file mode 100644
index 000000000000..7ae6a2b492ba
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/t99/before/test.java
@@ -0,0 +1,6 @@
+import java.util.*;
+public class Test {
+ Set<List<char[]>> f = new Set<List<char[]>>();
+
+
+}
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/Test.items
new file mode 100644
index 000000000000..ab263cc2b7a6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:list : java.util.Collection<java.lang.Integer>
+PsiNewExpression:new ArrayList<>(2) : java.util.ArrayList<java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+new ArrayList<>(2) -> java.util.ArrayList<java.lang.Integer>
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/test.java
new file mode 100644
index 000000000000..7d25d562b91d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/after/test.java
@@ -0,0 +1,9 @@
+import java.lang.annotation.*;
+import java.util.*;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { }
+
+class Test {
+ Collection<@TA Integer> list = new ArrayList<>(2);
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/before/test.java b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/before/test.java
new file mode 100644
index 000000000000..6cc51471d8d8
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigration/typeAnno/before/test.java
@@ -0,0 +1,9 @@
+import java.lang.annotation.*;
+import java.util.*;
+
+@Target(value = ElementType.TYPE_USE)
+public @interface TA { }
+
+class Test {
+ ArrayList<@TA Integer> list = new ArrayList<>(2);
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.items
new file mode 100644
index 000000000000..9d1b1894378f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.items
@@ -0,0 +1,25 @@
+Types:
+PsiAssignmentExpression:i += 2 : java.util.concurrent.atomic.AtomicInteger
+PsiAssignmentExpression:i -= 5 : java.util.concurrent.atomic.AtomicInteger
+PsiBinaryExpression:i + 9 : int
+PsiBinaryExpression:i - 9 : int
+PsiBinaryExpression:i == 0 : boolean
+PsiField:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+
+Conversions:
+0 -> new java.util.concurrent.atomic.AtomicInteger($val$) $val$
+9 -> $qualifier$.set($val$) $qualifier$ = $val$ i = 9
+i + 9 -> $qualifier$.get() + $val$ $qualifier$+$val$
+i += 2 -> $qualifier$.getAndAdd(($val$)) $qualifier$ += $val$
+i - 9 -> $qualifier$.get() - $val$ $qualifier$-$val$
+i -= 5 -> $qualifier$.getAndAdd(-($val$)) $qualifier$ -= $val$
+i == 0 -> $qualifier$.get() == $val$ $qualifier$==$val$
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.java
new file mode 100644
index 000000000000..5c16607a8b70
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/after/Test.java
@@ -0,0 +1,16 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+class Test {
+ AtomicInteger i = new AtomicInteger(0);
+
+ void foo() {
+ i.getAndAdd((2));
+ i.getAndAdd(-(5));
+ if (i.get() == 0) {
+ i.set(9);
+ }
+
+ System.out.println(i.get() + 9);
+ System.out.println(i.get() - 9);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/before/Test.java
new file mode 100644
index 000000000000..b96f02057dfd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directAssignments/before/Test.java
@@ -0,0 +1,14 @@
+class Test {
+ int i = 0;
+
+ void foo() {
+ i += 2;
+ i -= 5;
+ if (i == 0) {
+ i = 9;
+ }
+
+ System.out.println(i + 9);
+ System.out.println(i - 9);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.items
new file mode 100644
index 000000000000..e0e121ecf00d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.items
@@ -0,0 +1,19 @@
+Types:
+PsiAssignmentExpression:b += 0 : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiBinaryExpression:b == 0 : boolean
+PsiField:b : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiPostfixExpression:b++ : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicReference<java.lang.Byte>
+
+Conversions:
+0 -> new java.util.concurrent.atomic.AtomicReference<java.lang.Byte>((byte)$val$) $val$
+b += 0 -> $qualifier$.set(new Byte((byte)($qualifier$.get() + $val$))) $qualifier$+=$val$
+b -> $qualifier$.get() $qualifier$ b
+b == 0 -> $qualifier$.get() == $val$ $qualifier$==$val$
+b++ -> $qualifier$.getAndSet(new Byte((byte)($qualifier$.get() + 1))) $qualifier$++
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.java
new file mode 100644
index 000000000000..a1dbfc714326
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/after/Test.java
@@ -0,0 +1,14 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ AtomicReference<Byte> b = new AtomicReference<Byte>((byte) 0);
+
+ void bar() {
+ if (b.get() == 0) {
+ b.getAndSet(new Byte((byte) (b.get() + 1)));
+ b.set(new Byte((byte) (b.get() + 0)));
+ //System.out.println(b + 10);
+ System.out.println(b.get());
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/before/Test.java
new file mode 100644
index 000000000000..fa494c28a3c4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directByte/before/Test.java
@@ -0,0 +1,12 @@
+class Test {
+ byte b = 0;
+
+ void bar() {
+ if (b == 0) {
+ b++;
+ b += 0;
+ //System.out.println(b + 10);
+ System.out.println(b);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.items
new file mode 100644
index 000000000000..95f366691485
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:b : java.util.concurrent.atomic.AtomicBoolean
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicBoolean
+PsiReferenceExpression:b : java.util.concurrent.atomic.AtomicBoolean
+
+Conversions:
+b -> $qualifier$.get() $qualifier$ b
+true -> $qualifier$.set($val$) $qualifier$ = $val$ b = true
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.java
new file mode 100644
index 000000000000..02fc40276a86
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/after/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicBoolean;
+
+class Test {
+ AtomicBoolean b;
+
+ void foo() {
+ if (b.get()) {
+ b.set(true);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/before/Test.java
new file mode 100644
index 000000000000..ef5413600c40
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directConditions/before/Test.java
@@ -0,0 +1,9 @@
+class Test {
+ boolean b;
+
+ void foo() {
+ if (b) {
+ b = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.items
new file mode 100644
index 000000000000..add3ea1f98e3
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiField:lst : java.util.concurrent.atomic.AtomicReference<java.util.List<java.lang.String>>
+PsiReferenceExpression:lst : java.util.concurrent.atomic.AtomicReference<java.util.List<java.lang.String>>
+
+Conversions:
+lst -> $qualifier$.get() $qualifier$ lst
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.java
new file mode 100644
index 000000000000..4db9a5619849
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/after/Test.java
@@ -0,0 +1,12 @@
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ AtomicReference<List<String>> lst;
+
+ void foo() {
+ for (String s : lst.get()) {
+ System.out.println(s);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/before/Test.java
new file mode 100644
index 000000000000..1d40f4082444
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directForeach/before/Test.java
@@ -0,0 +1,11 @@
+import java.util.*;
+
+class Test {
+ List<String> lst;
+
+ void foo() {
+ for (String s : lst) {
+ System.out.println(s);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.items
new file mode 100644
index 000000000000..852aa470a285
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.items
@@ -0,0 +1,25 @@
+Types:
+PsiField:i : java.util.concurrent.atomic.AtomicInteger
+PsiPostfixExpression:i++ : java.util.concurrent.atomic.AtomicInteger
+PsiPostfixExpression:i++ : java.util.concurrent.atomic.AtomicInteger
+PsiPostfixExpression:i-- : java.util.concurrent.atomic.AtomicInteger
+PsiPrefixExpression:++i : java.util.concurrent.atomic.AtomicInteger
+PsiPrefixExpression:--i : java.util.concurrent.atomic.AtomicInteger
+PsiPrefixExpression:--i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+PsiReferenceExpression:i : java.util.concurrent.atomic.AtomicInteger
+
+Conversions:
+++i -> $qualifier$.incrementAndGet() ++$qualifier$
+--i -> $qualifier$.decrementAndGet() --$qualifier$
+--i -> $qualifier$.decrementAndGet() --$qualifier$
+i++ -> $qualifier$.getAndIncrement() $qualifier$++
+i++ -> $qualifier$.getAndIncrement() $qualifier$++
+i-- -> $qualifier$.getAndDecrement() $qualifier$--
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.java
new file mode 100644
index 000000000000..bdcf7171016b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/after/Test.java
@@ -0,0 +1,14 @@
+import java.util.concurrent.atomic.AtomicInteger;
+
+class Test {
+ AtomicInteger i;
+
+ void foo() {
+ i.getAndIncrement();
+ i.incrementAndGet();
+ i.getAndDecrement();
+ i.decrementAndGet();
+ System.out.println(i.getAndIncrement());
+ System.out.println(i.decrementAndGet());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/before/Test.java
new file mode 100644
index 000000000000..be6aa55d5f29
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIncrementDecrement/before/Test.java
@@ -0,0 +1,12 @@
+class Test {
+ int i;
+
+ void foo() {
+ i++;
+ ++i;
+ i--;
+ --i;
+ System.out.println(i++);
+ System.out.println(--i);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.items
new file mode 100644
index 000000000000..69a66c34a6cb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.items
@@ -0,0 +1,34 @@
+Types:
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiArrayAccessExpression:a[0] : int
+PsiField:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+PsiReferenceExpression:a : java.util.concurrent.atomic.AtomicIntegerArray
+
+Conversions:
+a[0] -> $qualifier$.decrementAndGet($idx$) --$qualifier$[$idx$] --a[0]
+a[0] -> $qualifier$.get($idx$) $qualifier$[$idx$] a[0]
+a[0] -> $qualifier$.get($idx$) $qualifier$[$idx$] a[0]
+a[0] -> $qualifier$.getAndAdd($idx$, ($val$)) $qualifier$[$idx$] += $val$ a[0] += (2)
+a[0] -> $qualifier$.getAndDecrement($idx$) $qualifier$[$idx$]-- a[0]--
+a[0] -> $qualifier$.getAndIncrement($idx$) $qualifier$[$idx$]++ a[0]++
+a[0] -> $qualifier$.incrementAndGet($idx$) ++$qualifier$[$idx$] ++a[0]
+a[0] -> $qualifier$.set($idx$, $qualifier$.get($idx$) * $val$) $qualifier$[$idx$]*=$val$ a[0] *= 2
+new int[0] -> new java.util.concurrent.atomic.AtomicIntegerArray($val$) $val$ new int[0]
+new int[1] -> new java.util.concurrent.atomic.AtomicIntegerArray($val$) $val$ new int[1]
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.java
new file mode 100644
index 000000000000..8dbba12048fe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/after/Test.java
@@ -0,0 +1,20 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+class Test {
+ AtomicIntegerArray a = new AtomicIntegerArray(new int[1]);
+
+
+ void foo() {
+ a.getAndIncrement(0);
+ System.out.println(a.incrementAndGet(0));
+ a.getAndDecrement(0);
+ if (a.decrementAndGet(0) == 0) {
+ a.getAndAdd(0, ((2)));
+ a.set(0, a.get(0) * 2);
+ if (a.get(0) == 0) {
+ System.out.println(a.get(0) + 7);
+ }
+ }
+ a = new AtomicIntegerArray(new int[0]);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/before/Test.java
new file mode 100644
index 000000000000..5d39cf2963c6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directIntArray/before/Test.java
@@ -0,0 +1,18 @@
+class Test {
+ int[] a = new int[1];
+
+
+ void foo() {
+ a[0]++;
+ System.out.println(++a[0]);
+ a[0]--;
+ if (--a[0] == 0) {
+ a[0] += (2);
+ a[0] *= 2;
+ if (a[0] == 0) {
+ System.out.println(a[0] + 7);
+ }
+ }
+ a = new int[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.items
new file mode 100644
index 000000000000..0d306b0b4747
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:s : java.util.concurrent.atomic.AtomicReference<java.lang.String>
+PsiReferenceExpression:s : java.util.concurrent.atomic.AtomicReference<java.lang.String>
+PsiReferenceExpression:s : java.util.concurrent.atomic.AtomicReference<java.lang.String>
+
+Conversions:
+"" -> new java.util.concurrent.atomic.AtomicReference<java.lang.String>($val$) $val$
+s -> $qualifier$.get() $qualifier$ s
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.java
new file mode 100644
index 000000000000..cb32e0ba130b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/after/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ AtomicReference<String> s = new AtomicReference<String>("");
+
+ void foo() {
+ if (s == null) {
+ System.out.println(s.get());
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/before/Test.java
new file mode 100644
index 000000000000..1770416a0295
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directString/before/Test.java
@@ -0,0 +1,9 @@
+class Test {
+ String s = "";
+
+ void foo() {
+ if (s == null) {
+ System.out.println(s);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.items
new file mode 100644
index 000000000000..b90b4a347f40
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.items
@@ -0,0 +1,14 @@
+Types:
+PsiArrayAccessExpression:s[0] : java.lang.String
+PsiArrayAccessExpression:s[0] : java.lang.String
+PsiField:s : java.util.concurrent.atomic.AtomicReferenceArray<java.lang.String>
+PsiReferenceExpression:s : java.util.concurrent.atomic.AtomicReferenceArray<java.lang.String>
+PsiReferenceExpression:s : java.util.concurrent.atomic.AtomicReferenceArray<java.lang.String>
+
+Conversions:
+new String[2] -> new java.util.concurrent.atomic.AtomicReferenceArray<java.lang.String>($val$) $val$ new String[2]
+s[0] -> $qualifier$.get($idx$) $qualifier$[$idx$] s[0]
+s[0] -> $qualifier$.set($idx$, $val$) $qualifier$[$idx$] = $val$ s[0] = ""
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.java
new file mode 100644
index 000000000000..42415d0c3141
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/after/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+class Test {
+ AtomicReferenceArray<String> s = new AtomicReferenceArray<String>(new String[2]);
+
+ void foo() {
+ s.set(0, "");
+ System.out.println(s.get(0));
+
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/before/Test.java
new file mode 100644
index 000000000000..4f19feba6479
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/directStringArray/before/Test.java
@@ -0,0 +1,9 @@
+class Test {
+ String[] s = new String[2];
+
+ void foo() {
+ s[0] = "";
+ System.out.println(s[0]);
+
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.items
new file mode 100644
index 000000000000..767993764c48
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.items
@@ -0,0 +1,26 @@
+Types:
+PsiField:i : int
+PsiMethodCallExpression:i.addAndGet(-(9)) : int
+PsiMethodCallExpression:i.addAndGet(9) : int
+PsiMethodCallExpression:i.get() : int
+PsiMethodCallExpression:i.getAndAdd(-5) : int
+PsiMethodCallExpression:i.getAndAdd(2) : int
+PsiMethodCallExpression:i.set(9) : void
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+
+Conversions:
+i.addAndGet(-(9)) -> $qualifier$ + $delta$ $qualifier$.addAndGet($delta$)
+i.addAndGet(9) -> $qualifier$ + $delta$ $qualifier$.addAndGet($delta$)
+i.get() -> $qualifier$ $qualifier$.get()
+i.getAndAdd(-5) -> $qualifier$ += $val$ $qualifier$.getAndAdd($val$)
+i.getAndAdd(2) -> $qualifier$ += $val$ $qualifier$.getAndAdd($val$)
+i.set(9) -> $qualifier$ = $val$ $qualifier$.set($val$)
+new AtomicInteger(0) -> $qualifier$ new $type$($qualifier$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.java
new file mode 100644
index 000000000000..1372ccee2b27
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/after/Test.java
@@ -0,0 +1,15 @@
+import java.util.concurrent.atomic.AtomicInteger;
+class Test {
+ int i = 0;
+
+ void foo() {
+ i += 2;
+ i += -5;
+ if (i == 0) {
+ i = 9;
+ }
+
+ System.out.println(i + 9);
+ System.out.println(i + -(9));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/before/Test.java
new file mode 100644
index 000000000000..cfd312daa073
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseAssignments/before/Test.java
@@ -0,0 +1,15 @@
+import java.util.concurrent.atomic.AtomicInteger;
+class Test {
+ AtomicInteger i = new AtomicInteger(0);
+
+ void foo() {
+ i.getAndAdd(2);
+ i.getAndAdd(-5);
+ if (i.get() == 0) {
+ i.set(9);
+ }
+
+ System.out.println(i.addAndGet(9));
+ System.out.println(i.addAndGet(-(9)));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.items
new file mode 100644
index 000000000000..8585bda9e020
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.items
@@ -0,0 +1,26 @@
+Types:
+PsiField:b : byte
+PsiMethodCallExpression:b.get() : java.lang.Byte
+PsiMethodCallExpression:b.get() : java.lang.Byte
+PsiMethodCallExpression:b.get() : java.lang.Byte
+PsiMethodCallExpression:b.get() : java.lang.Byte
+PsiMethodCallExpression:b.getAndSet(new Byte((byte) (b.get() + 1))) : java.lang.Byte
+PsiMethodCallExpression:b.set(new Byte((byte) (b.get() + 0))) : void
+PsiReferenceExpression:b : byte
+PsiReferenceExpression:b : byte
+PsiReferenceExpression:b : byte
+PsiReferenceExpression:b : byte
+PsiReferenceExpression:b : byte
+PsiReferenceExpression:b : byte
+
+Conversions:
+b.get() -> $qualifier$ $qualifier$.get()
+b.get() -> $qualifier$ $qualifier$.get()
+b.get() -> $qualifier$ $qualifier$.get()
+b.get() -> $qualifier$ $qualifier$.get()
+b.getAndSet(new Byte((byte) (b.get() + 1))) -> $qualifier$ = $val$ $qualifier$.getAndSet($val$)
+b.set(new Byte((byte) (b.get() + 0))) -> $qualifier$ = $val$ $qualifier$.set($val$)
+new AtomicReference<Byte>((byte) 0) -> $qualifier$ new $type$($qualifier$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.java
new file mode 100644
index 000000000000..28445dd31728
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/after/Test.java
@@ -0,0 +1,14 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ byte b = (byte) 0;
+
+ void bar() {
+ if (b == 0) {
+ b = new Byte((byte) (b + 1));
+ b = new Byte((byte) (b + 0));
+ //System.out.println(b + 10);
+ System.out.println(b);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/before/Test.java
new file mode 100644
index 000000000000..a1dbfc714326
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseByte/before/Test.java
@@ -0,0 +1,14 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ AtomicReference<Byte> b = new AtomicReference<Byte>((byte) 0);
+
+ void bar() {
+ if (b.get() == 0) {
+ b.getAndSet(new Byte((byte) (b.get() + 1)));
+ b.set(new Byte((byte) (b.get() + 0)));
+ //System.out.println(b + 10);
+ System.out.println(b.get());
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.items
new file mode 100644
index 000000000000..3594508bebe5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.items
@@ -0,0 +1,13 @@
+Types:
+PsiField:b : boolean
+PsiMethodCallExpression:b.get() : boolean
+PsiMethodCallExpression:b.set(true) : void
+PsiReferenceExpression:b : boolean
+PsiReferenceExpression:b : boolean
+
+Conversions:
+b.get() -> $qualifier$ $qualifier$.get()
+b.set(true) -> $qualifier$ = $val$ $qualifier$.set($val$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.java
new file mode 100644
index 000000000000..92f515c35936
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/after/Test.java
@@ -0,0 +1,10 @@
+import java.util.concurrent.atomic.AtomicBoolean;
+class Test {
+ boolean b;
+
+ void foo() {
+ if (b) {
+ b = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/before/Test.java
new file mode 100644
index 000000000000..5464f705ddeb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseConditions/before/Test.java
@@ -0,0 +1,10 @@
+import java.util.concurrent.atomic.AtomicBoolean;
+class Test {
+ AtomicBoolean b;
+
+ void foo() {
+ if (b.get()) {
+ b.set(true);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.items
new file mode 100644
index 000000000000..cba5bc10f359
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.items
@@ -0,0 +1,25 @@
+Types:
+PsiField:i : int
+PsiMethodCallExpression:i.decrementAndGet() : int
+PsiMethodCallExpression:i.decrementAndGet() : int
+PsiMethodCallExpression:i.getAndDecrement() : int
+PsiMethodCallExpression:i.getAndIncrement() : int
+PsiMethodCallExpression:i.getAndIncrement() : int
+PsiMethodCallExpression:i.incrementAndGet() : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+PsiReferenceExpression:i : int
+
+Conversions:
+i.decrementAndGet() -> --$qualifier$ $qualifier$.decrementAndGet()
+i.decrementAndGet() -> --$qualifier$ $qualifier$.decrementAndGet()
+i.getAndDecrement() -> $qualifier$-- $qualifier$.getAndDecrement()
+i.getAndIncrement() -> $qualifier$++ $qualifier$.getAndIncrement()
+i.getAndIncrement() -> $qualifier$++ $qualifier$.getAndIncrement()
+i.incrementAndGet() -> ++$qualifier$ $qualifier$.incrementAndGet()
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.java
new file mode 100644
index 000000000000..dd70e550a751
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/after/Test.java
@@ -0,0 +1,13 @@
+import java.util.concurrent.atomic.AtomicInteger;
+class Test {
+ int i;
+
+ void foo() {
+ i++;
+ ++i;
+ i--;
+ --i;
+ System.out.println(i++);
+ System.out.println(--i);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/before/Test.java
new file mode 100644
index 000000000000..853e5387aca9
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIncrementDecrement/before/Test.java
@@ -0,0 +1,13 @@
+import java.util.concurrent.atomic.AtomicInteger;
+class Test {
+ AtomicInteger i;
+
+ void foo() {
+ i.getAndIncrement();
+ i.incrementAndGet();
+ i.getAndDecrement();
+ i.decrementAndGet();
+ System.out.println(i.getAndIncrement());
+ System.out.println(i.decrementAndGet());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.items
new file mode 100644
index 000000000000..55c1c7bc2574
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.items
@@ -0,0 +1,35 @@
+Types:
+PsiField:a : int[]
+PsiMethodCallExpression:a.addAndGet(0, 7) : int
+PsiMethodCallExpression:a.decrementAndGet(0) : int
+PsiMethodCallExpression:a.get(0) : int
+PsiMethodCallExpression:a.get(0) : int
+PsiMethodCallExpression:a.getAndAdd(0, ((2))) : int
+PsiMethodCallExpression:a.getAndDecrement(0) : int
+PsiMethodCallExpression:a.getAndIncrement(0) : int
+PsiMethodCallExpression:a.incrementAndGet(0) : int
+PsiMethodCallExpression:a.set(0, a.get(0) * 2) : void
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+PsiReferenceExpression:a : int[]
+
+Conversions:
+a.addAndGet(0, 7) -> $qualifier$[$idx$] + $delta$ $qualifier$.addAndGet($idx$, $delta$)
+a.decrementAndGet(0) -> --$qualifier$[$idx$] $qualifier$.decrementAndGet($idx$)
+a.get(0) -> $qualifier$[$idx$] $qualifier$.get($idx$)
+a.get(0) -> $qualifier$[$idx$] $qualifier$.get($idx$)
+a.getAndAdd(0, ((2))) -> $qualifier$[$idx$] += $val$ $qualifier$.getAndAdd($idx$, $val$)
+a.getAndDecrement(0) -> $qualifier$[$idx$]-- $qualifier$.getAndDecrement($idx$)
+a.getAndIncrement(0) -> $qualifier$[$idx$]++ $qualifier$.getAndIncrement($idx$)
+a.incrementAndGet(0) -> ++$qualifier$[$idx$] $qualifier$.incrementAndGet($idx$)
+a.set(0, a.get(0) * 2) -> $qualifier$[$idx$] = $val$ $qualifier$.set($idx$, $val$)
+new AtomicIntegerArray(new int[1]) -> $qualifier$ new $type$($qualifier$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.java
new file mode 100644
index 000000000000..401714230d3c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/after/Test.java
@@ -0,0 +1,19 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+class Test {
+ int[] a = new int[1];
+
+
+ void foo() {
+ a[0]++;
+ System.out.println(++a[0]);
+ a[0]--;
+ if (--a[0] == 0) {
+ a[0] += ((2));
+ a[0] = a[0] * 2;
+ if (a[0] == 0) {
+ System.out.println(a[0] + 7);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/before/Test.java
new file mode 100644
index 000000000000..df31528b9d7e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseIntArray/before/Test.java
@@ -0,0 +1,19 @@
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+class Test {
+ AtomicIntegerArray a = new AtomicIntegerArray(new int[1]);
+
+
+ void foo() {
+ a.getAndIncrement(0);
+ System.out.println(a.incrementAndGet(0));
+ a.getAndDecrement(0);
+ if (a.decrementAndGet(0) == 0) {
+ a.getAndAdd(0, ((2)));
+ a.set(0, a.get(0) * 2);
+ if (a.get(0) == 0) {
+ System.out.println(a.addAndGet(0, 7));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.items
new file mode 100644
index 000000000000..7c23d49d8bfd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiField:s : java.lang.String
+PsiMethodCallExpression:s.get() : java.lang.String
+PsiReferenceExpression:s : java.lang.String
+PsiReferenceExpression:s : java.lang.String
+
+Conversions:
+new AtomicReference<String>("") -> $qualifier$ new $type$($qualifier$)
+s.get() -> $qualifier$ $qualifier$.get()
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.java
new file mode 100644
index 000000000000..a0106ff8d66f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/after/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ String s = "";
+
+ void foo() {
+ if (s == null) {
+ System.out.println(s);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/before/Test.java
new file mode 100644
index 000000000000..cb32e0ba130b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseString/before/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReference;
+
+class Test {
+ AtomicReference<String> s = new AtomicReference<String>("");
+
+ void foo() {
+ if (s == null) {
+ System.out.println(s.get());
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.items
new file mode 100644
index 000000000000..eaf82b5cc2e6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.items
@@ -0,0 +1,14 @@
+Types:
+PsiField:s : java.lang.String[]
+PsiMethodCallExpression:s.get(0) : java.lang.String
+PsiMethodCallExpression:s.set(0, "") : void
+PsiReferenceExpression:s : java.lang.String[]
+PsiReferenceExpression:s : java.lang.String[]
+
+Conversions:
+new AtomicReferenceArray<String>(new String[2]) -> $qualifier$ new $type$($qualifier$)
+s.get(0) -> $qualifier$[$idx$] $qualifier$.get($idx$)
+s.set(0, "") -> $qualifier$[$idx$] = $val$ $qualifier$.set($idx$, $val$)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.java
new file mode 100644
index 000000000000..0c64ea445f01
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/after/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+class Test {
+ String[] s = new String[2];
+
+ void foo() {
+ s[0] = "";
+ System.out.println(s[0]);
+
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/before/Test.java
new file mode 100644
index 000000000000..fbc97bc2eb36
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByAtomic/reverseStringArray/before/Test.java
@@ -0,0 +1,11 @@
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+class Test {
+ AtomicReferenceArray<String> s = new AtomicReferenceArray<String>(new String[2]);
+
+ void foo() {
+ s.set(0, "");
+ System.out.println(s.get(0));
+
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.items
new file mode 100644
index 000000000000..e01b4b5e1f8b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.items
@@ -0,0 +1,22 @@
+Types:
+PsiBinaryExpression:i == 0 : boolean
+PsiField:i : java.lang.ThreadLocal<java.lang.Byte>
+PsiPostfixExpression:i++ : java.lang.ThreadLocal<java.lang.Byte>
+PsiPostfixExpression:i-- : java.lang.ThreadLocal<java.lang.Byte>
+PsiPrefixExpression:++i : java.lang.ThreadLocal<java.lang.Byte>
+PsiPrefixExpression:--i : java.lang.ThreadLocal<java.lang.Byte>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Byte>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Byte>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Byte>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Byte>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Byte>
+
+Conversions:
+++i -> $qualifier$.set(new java.lang.Byte((byte)($qualifier$.get() + 1))) ++$qualifier$
+--i -> $qualifier$.set(new java.lang.Byte((byte)($qualifier$.get() - 1))) --$qualifier$
+i == 0 -> $qualifier$.get() == $val$ $qualifier$==$val$
+i++ -> $qualifier$.set(new java.lang.Byte((byte)($qualifier$.get() + 1))) $qualifier$++
+i-- -> $qualifier$.set(new java.lang.Byte((byte)($qualifier$.get() - 1))) $qualifier$--
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.java
new file mode 100644
index 000000000000..61b88dbefceb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/after/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ ThreadLocal<Byte> i;
+
+ void foo() {
+ i.set(new Byte((byte) (i.get() + 1)));
+ i.set(new Byte((byte) (i.get() + 1)));
+ i.set(new Byte((byte) (i.get() - 1)));
+ i.set(new Byte((byte) (i.get() - 1)));
+ if (i.get() == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/before/Test.java
new file mode 100644
index 000000000000..dd3fb1bca60d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directByte/before/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ byte i;
+
+ void foo() {
+ i++;
+ ++i;
+ i--;
+ --i;
+ if (i == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.items
new file mode 100644
index 000000000000..1bffd7037cb6
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.items
@@ -0,0 +1,22 @@
+Types:
+PsiBinaryExpression:i == 0 : boolean
+PsiField:i : java.lang.ThreadLocal<java.lang.Integer>
+PsiPostfixExpression:i++ : java.lang.ThreadLocal<java.lang.Integer>
+PsiPostfixExpression:i-- : java.lang.ThreadLocal<java.lang.Integer>
+PsiPrefixExpression:++i : java.lang.ThreadLocal<java.lang.Integer>
+PsiPrefixExpression:--i : java.lang.ThreadLocal<java.lang.Integer>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Integer>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Integer>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Integer>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Integer>
+PsiReferenceExpression:i : java.lang.ThreadLocal<java.lang.Integer>
+
+Conversions:
+++i -> $qualifier$.set($qualifier$.get() + 1) ++$qualifier$
+--i -> $qualifier$.set($qualifier$.get() - 1) --$qualifier$
+i == 0 -> $qualifier$.get() == $val$ $qualifier$==$val$
+i++ -> $qualifier$.set($qualifier$.get() + 1) $qualifier$++
+i-- -> $qualifier$.set($qualifier$.get() - 1) $qualifier$--
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.java
new file mode 100644
index 000000000000..627739bc4b1c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/after/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ ThreadLocal<Integer> i;
+
+ void foo() {
+ i.set(i.get() + 1);
+ i.set(i.get() + 1);
+ i.set(i.get() - 1);
+ i.set(i.get() - 1);
+ if (i.get() == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/before/Test.java
new file mode 100644
index 000000000000..9039f28e9617
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directInt/before/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ int i;
+
+ void foo() {
+ i++;
+ ++i;
+ i--;
+ --i;
+ if (i == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.items
new file mode 100644
index 000000000000..29d4312a8580
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiField:myS : java.lang.ThreadLocal<java.lang.String>
+PsiReferenceExpression:myS : java.lang.ThreadLocal<java.lang.String>
+PsiReferenceExpression:myS : java.lang.ThreadLocal<java.lang.String>
+
+Conversions:
+myS -> $qualifier$.get() $qualifier$ myS
+
+New expression type changes:
+Fails:
+""->java.lang.ThreadLocal<java.lang.String>
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.java
new file mode 100644
index 000000000000..949869096327
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/after/Test.java
@@ -0,0 +1,9 @@
+class Test {
+ ThreadLocal<String> myS = "";
+
+ void foo() {
+ if (myS == null) {
+ System.out.println(myS.get());
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/before/Test.java
new file mode 100644
index 000000000000..8ee02790f113
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/directString/before/Test.java
@@ -0,0 +1,9 @@
+class Test {
+ String myS = "";
+
+ void foo() {
+ if (myS == null) {
+ System.out.println(myS);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.items b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.items
new file mode 100644
index 000000000000..09a2a211ae6a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.items
@@ -0,0 +1,22 @@
+Types:
+PsiBinaryExpression:i == 0 : boolean
+PsiField:i : java.lang.ThreadLocal
+PsiPostfixExpression:i++ : java.lang.ThreadLocal
+PsiPostfixExpression:i-- : java.lang.ThreadLocal
+PsiPrefixExpression:++i : java.lang.ThreadLocal
+PsiPrefixExpression:--i : java.lang.ThreadLocal
+PsiReferenceExpression:i : java.lang.ThreadLocal
+PsiReferenceExpression:i : java.lang.ThreadLocal
+PsiReferenceExpression:i : java.lang.ThreadLocal
+PsiReferenceExpression:i : java.lang.ThreadLocal
+PsiReferenceExpression:i : java.lang.ThreadLocal
+
+Conversions:
+++i -> $qualifier$.set(new java.lang.Integer(((java.lang.Integer)$qualifier$.get()).intValue() + 1)) ++$qualifier$
+--i -> $qualifier$.set(new java.lang.Integer(((java.lang.Integer)$qualifier$.get()).intValue() - 1)) --$qualifier$
+i == 0 -> ((java.lang.Integer)$qualifier$.get()).intValue() == $val$ $qualifier$==$val$
+i++ -> $qualifier$.set(new java.lang.Integer(((java.lang.Integer)$qualifier$.get()).intValue() + 1)) $qualifier$++
+i-- -> $qualifier$.set(new java.lang.Integer(((java.lang.Integer)$qualifier$.get()).intValue() - 1)) $qualifier$--
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.java
new file mode 100644
index 000000000000..81e5fe05d6dd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/after/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ ThreadLocal i;
+
+ void foo() {
+ i.set(new Integer(((Integer) i.get()).intValue() + 1));
+ i.set(new Integer(((Integer) i.get()).intValue() + 1));
+ i.set(new Integer(((Integer) i.get()).intValue() - 1));
+ i.set(new Integer(((Integer) i.get()).intValue() - 1));
+ if (((Integer) i.get()).intValue() == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/before/Test.java b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/before/Test.java
new file mode 100644
index 000000000000..9039f28e9617
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/typeMigrationByThreadLocal/languageLevel/before/Test.java
@@ -0,0 +1,11 @@
+class Test {
+ int i;
+
+ void foo() {
+ i++;
+ ++i;
+ i--;
+ --i;
+ if (i == 0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/Test.items
new file mode 100644
index 000000000000..b39d716277ba
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.ArrayList<? extends java.lang.Integer>
+PsiReferenceExpression:p : java.util.ArrayList<? extends java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[0]->java.util.ArrayList<? extends java.lang.Integer>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/test.java
new file mode 100644
index 000000000000..16a620ef2e6d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Integer> p) {
+ p[0] = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/before/test.java
new file mode 100644
index 000000000000..4a148c3bd6fe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentExtends/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ p[0] = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/Test.items
new file mode 100644
index 000000000000..8ee86c529545
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiArrayAccessExpression:p[0] : java.lang.Integer
+PsiParameter:p : java.util.ArrayList<? super java.lang.Integer>
+PsiReferenceExpression:p : java.util.ArrayList<? super java.lang.Integer>
+
+Conversions:
+p[0] -> $qualifier$.set($idx$, $expr$) $qualifier$[$idx$] = $expr$ p[0] = new Integer(0)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/test.java
new file mode 100644
index 000000000000..25cab7a9d34c
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Integer> p) {
+ p.set(0, new Integer(0));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/before/test.java
new file mode 100644
index 000000000000..4a148c3bd6fe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentSuper/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ p[0] = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/Test.items
new file mode 100644
index 000000000000..e2bbfc48b834
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.ArrayList<?>
+PsiReferenceExpression:p : java.util.ArrayList<?>
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[0]->java.util.ArrayList<?>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/test.java
new file mode 100644
index 000000000000..4804293a696e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<?> p) {
+ p[0] = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/before/test.java
new file mode 100644
index 000000000000..4a148c3bd6fe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/assignmentUnbounded/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ p[0] = new Integer(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/Test.items
new file mode 100644
index 000000000000..455ebca21125
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.lang.Number
+PsiParameter:p : java.util.ArrayList<? extends java.lang.Number>
+PsiReferenceExpression:p : java.util.ArrayList<? extends java.lang.Number>
+
+Conversions:
+p.get(0) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/test.java
new file mode 100644
index 000000000000..b403162051ad
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Number> p, Number p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/before/test.java
new file mode 100644
index 000000000000..649da301cc82
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerExtends/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<Number> p, Number p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/Test.items
new file mode 100644
index 000000000000..e4f5c3fc2088
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.lang.Object
+PsiParameter:p : java.util.ArrayList<? super java.lang.Number>
+PsiParameter:p2 : java.lang.Object
+PsiReferenceExpression:p : java.util.ArrayList<? super java.lang.Number>
+PsiReferenceExpression:p2 : java.lang.Object
+
+Conversions:
+p.get(0) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/test.java
new file mode 100644
index 000000000000..2c315ea3a723
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p, Object p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/before/test.java
new file mode 100644
index 000000000000..649da301cc82
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerSuper/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<Number> p, Number p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/Test.items
new file mode 100644
index 000000000000..a0b14b30985e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/Test.items
@@ -0,0 +1,12 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.lang.Object
+PsiParameter:p : java.util.ArrayList<?>
+PsiParameter:p2 : java.lang.Object
+PsiReferenceExpression:p : java.util.ArrayList<?>
+PsiReferenceExpression:p2 : java.lang.Object
+
+Conversions:
+p.get(0) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/test.java
new file mode 100644
index 000000000000..f10b5e2ae860
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<?> p, Object p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/before/test.java
new file mode 100644
index 000000000000..649da301cc82
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/consumerUnbounded/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<Number> p, Number p2) {
+ p2 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/Test.items
new file mode 100644
index 000000000000..1ac8dc86d9ca
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.lang.Number
+PsiParameter:p : java.lang.Integer[]
+PsiReferenceExpression:p : java.lang.Integer[]
+
+Conversions:
+p.get(0) -> $qualifier$[$i$] $qualifier$.get($i$) p.get(0)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/test.java
new file mode 100644
index 000000000000..bfe5eb68baba
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ Number n = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/before/test.java
new file mode 100644
index 000000000000..bbddcc1a4d79
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToChildType/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Number> p) {
+ Number n = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/Test.items
new file mode 100644
index 000000000000..a4ea13d41b29
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.lang.Object[]
+PsiReferenceExpression:p : java.lang.Object[]
+
+Conversions:
+
+New expression type changes:
+Fails:
+p->java.lang.Object[]
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/test.java
new file mode 100644
index 000000000000..96208756fe87
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Object[] p) {
+ Number n = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/before/test.java
new file mode 100644
index 000000000000..bbddcc1a4d79
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToSuperType/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Number> p) {
+ Number n = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/Test.items
new file mode 100644
index 000000000000..a0fd8df506c4
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.get(0) : java.lang.Number
+PsiParameter:p : java.lang.Number[]
+PsiReferenceExpression:p : java.lang.Number[]
+
+Conversions:
+p.get(0) -> $qualifier$[$i$] $qualifier$.get($i$) p.get(0)
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/test.java
new file mode 100644
index 000000000000..33a962b96171
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Number[] p) {
+ Number n = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/before/test.java
new file mode 100644
index 000000000000..bbddcc1a4d79
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getAssignmentExtendsToType/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Number> p) {
+ Number n = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/Test.items
new file mode 100644
index 000000000000..d68b720f5d5b
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiArrayAccessExpression:p[0] : java.lang.Integer
+PsiParameter:p : java.util.ArrayList<? extends java.lang.Integer>
+PsiReferenceExpression:p : java.util.ArrayList<? extends java.lang.Integer>
+
+Conversions:
+p[0] -> $qualifier$.get($idx$) $qualifier$[$idx$]
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/test.java
new file mode 100644
index 000000000000..529d4942a2ce
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Integer> p) {
+ Integer p1 = p.get(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/before/test.java
new file mode 100644
index 000000000000..685d78f23f3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getExtends/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ Integer p1 = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/Test.items
new file mode 100644
index 000000000000..5300a386dc23
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.ArrayList<? super java.lang.Integer>
+PsiReferenceExpression:p : java.util.ArrayList<? super java.lang.Integer>
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[0]->java.util.ArrayList<? super java.lang.Integer>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/test.java
new file mode 100644
index 000000000000..eebb4c1f2dbb
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Integer> p) {
+ Integer p1 = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/before/test.java
new file mode 100644
index 000000000000..685d78f23f3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getSuper/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ Integer p1 = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/Test.items
new file mode 100644
index 000000000000..e2bbfc48b834
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:p : java.util.ArrayList<?>
+PsiReferenceExpression:p : java.util.ArrayList<?>
+
+Conversions:
+
+New expression type changes:
+Fails:
+p[0]->java.util.ArrayList<?>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/test.java
new file mode 100644
index 000000000000..9ab43aa01dbe
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<?> p) {
+ Integer p1 = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/before/test.java
new file mode 100644
index 000000000000..685d78f23f3d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/getUnbounded/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ Integer p1 = p[0];
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/Test.items
new file mode 100644
index 000000000000..bf63b11ab5b2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiParameter:p : java.util.ArrayList<?>
+PsiReferenceExpression:p : java.util.ArrayList<?>
+PsiReferenceExpression:p.length : int
+
+Conversions:
+p.length -> $qualifier$.size() $qualifier$.length
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/test.java
new file mode 100644
index 000000000000..4f0770adbfb5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<?> p) {
+ System.out.println(p.size());
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/before/test.java
new file mode 100644
index 000000000000..e8758383dd0a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/lengthSize/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Integer[] p) {
+ System.out.println(p.length);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/Test.items
new file mode 100644
index 000000000000..fe9d55b37cda
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.add(new Integer(8)) : boolean
+PsiParameter:p : java.util.Set<? super java.lang.Integer>
+PsiReferenceExpression:p : java.util.Set<? super java.lang.Integer>
+
+Conversions:
+p.add(new Integer(8)) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/test.java
new file mode 100644
index 000000000000..25825f1f78c0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Set<? super Integer> p) {
+ p.add(new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/before/test.java
new file mode 100644
index 000000000000..d8cf544f6fde
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerCollectionChanged/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p) {
+ p.add(new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/Test.items
new file mode 100644
index 000000000000..8b996f4d00e1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:p.set(0, new Integer(8)) : java.lang.Number
+PsiParameter:p : java.util.ArrayList<? extends java.lang.Number>
+PsiReferenceExpression:p : java.util.ArrayList<? extends java.lang.Number>
+
+Conversions:
+p.set(0, new Integer(8)) -> $
+
+New expression type changes:
+Fails:
+new Integer(8)->? extends java.lang.Number
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/test.java
new file mode 100644
index 000000000000..f8f4f761d73a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? extends Number> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/before/test.java
new file mode 100644
index 000000000000..b5e9a24ad373
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtends/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/Test.items
new file mode 100644
index 000000000000..88976428ea99
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:p.add(new Integer(8)) : boolean
+PsiParameter:p : java.util.Set<? extends java.lang.Object>
+PsiReferenceExpression:p : java.util.Set<? extends java.lang.Object>
+
+Conversions:
+p.add(new Integer(8)) -> $
+
+New expression type changes:
+Fails:
+new Integer(8)->? extends java.lang.Object
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/test.java
new file mode 100644
index 000000000000..0c24d5791d14
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(Set<? extends Object> p) {
+ p.add(new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/before/test.java
new file mode 100644
index 000000000000..d8cf544f6fde
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsCollectionChanged/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p) {
+ p.add(new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/Test.items
new file mode 100644
index 000000000000..f2f5bb75a60f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:p1.add(p2) : boolean
+PsiParameter:p1 : java.util.List<? extends java.lang.Number>
+PsiReferenceExpression:p1 : java.util.List<? extends java.lang.Number>
+
+Conversions:
+p1.add(p2) -> $
+
+New expression type changes:
+Fails:
+p2->? extends java.lang.Number
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/test.java
new file mode 100644
index 000000000000..5d4d6fda25a2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<? extends Number> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/before/test.java
new file mode 100644
index 000000000000..a2e2cb2ae329
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerExtendsFailToStopAtWildcard/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<Number> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/Test.items
new file mode 100644
index 000000000000..9d9b2e2a447f
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:p1.add(p2) : boolean
+PsiParameter:p1 : java.util.List<? super java.lang.Integer>
+PsiReferenceExpression:p1 : java.util.List<? super java.lang.Integer>
+
+Conversions:
+p1.add(p2) -> $
+
+New expression type changes:
+Fails:
+p2->? super java.lang.Integer
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/test.java
new file mode 100644
index 000000000000..bbc30114137e
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<? super Integer> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/before/test.java
new file mode 100644
index 000000000000..a2e2cb2ae329
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerFailToStopAtWildcard/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<Number> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/Test.items
new file mode 100644
index 000000000000..2f3689b42ba5
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p1.add(p2) : boolean
+PsiParameter:p1 : java.util.List<? super java.lang.Number>
+PsiReferenceExpression:p1 : java.util.List<? super java.lang.Number>
+
+Conversions:
+p1.add(p2) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/test.java
new file mode 100644
index 000000000000..353f0432f59d
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<? super Number> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/before/test.java
new file mode 100644
index 000000000000..a2e2cb2ae329
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerStopAtWildcard/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<Number> p1, Number p2){
+ p1.add(p2);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/Test.items
new file mode 100644
index 000000000000..b0c91006b9d1
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:p.set(0, new Integer(8)) : java.lang.Object
+PsiParameter:p : java.util.ArrayList<? super java.lang.Integer>
+PsiReferenceExpression:p : java.util.ArrayList<? super java.lang.Integer>
+
+Conversions:
+p.set(0, new Integer(8)) -> $
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/test.java
new file mode 100644
index 000000000000..0769f09a7b7a
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Integer> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/before/test.java
new file mode 100644
index 000000000000..b5e9a24ad373
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerSuper/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/Test.items
new file mode 100644
index 000000000000..e2b8ee35fcd2
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/Test.items
@@ -0,0 +1,11 @@
+Types:
+PsiMethodCallExpression:p.set(0, new Integer(8)) : java.lang.Object
+PsiParameter:p : java.util.ArrayList<?>
+PsiReferenceExpression:p : java.util.ArrayList<?>
+
+Conversions:
+p.set(0, new Integer(8)) -> $
+
+New expression type changes:
+Fails:
+new Integer(8)->?
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/test.java
new file mode 100644
index 000000000000..37a2f8fcac83
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<?> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/before/test.java
new file mode 100644
index 000000000000..b5e9a24ad373
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/producerUnbounded/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ArrayList<? super Number> p) {
+ p.set(0, new Integer(8));
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/Test.items
new file mode 100644
index 000000000000..7ae170499472
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:l.substring(0) : java.lang.String
+PsiParameter:l : java.lang.ThreadLocal<? extends java.lang.String>
+PsiReferenceExpression:l : java.lang.ThreadLocal<? extends java.lang.String>
+
+Conversions:
+l.substring(0) -> $qualifier$.get() $qualifier$ l
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/test.java
new file mode 100644
index 000000000000..5275db851a70
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void method(ThreadLocal<? extends String> l) {
+ l.get().substring(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/before/test.java
new file mode 100644
index 000000000000..8805129f7191
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerExtends/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void method(String l) {
+ l.substring(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/Test.items
new file mode 100644
index 000000000000..d05d101463c7
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:l : java.lang.ThreadLocal<? super java.lang.String>
+PsiReferenceExpression:l : java.lang.ThreadLocal<? super java.lang.String>
+
+Conversions:
+
+New expression type changes:
+Fails:
+l->java.lang.ThreadLocal<? super java.lang.String>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/test.java
new file mode 100644
index 000000000000..beb0d0ebef46
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/after/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void method(ThreadLocal<? super String> l) {
+ l.substring(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/before/test.java
new file mode 100644
index 000000000000..8805129f7191
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalConsumerSuper/before/test.java
@@ -0,0 +1,5 @@
+class Test {
+ void method(String l) {
+ l.substring(0);
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/Test.items
new file mode 100644
index 000000000000..47a89e441962
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiParameter:l : java.lang.ThreadLocal<java.util.List<? extends java.lang.String>>
+PsiReferenceExpression:l : java.lang.ThreadLocal<java.util.List<? extends java.lang.String>>
+
+Conversions:
+
+New expression type changes:
+Fails:
+l->java.lang.ThreadLocal<java.util.List<? extends java.lang.String>>
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/test.java
new file mode 100644
index 000000000000..93724be5c0dd
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ThreadLocal<List<? extends String>> l) {
+ l.add("");
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/before/test.java
new file mode 100644
index 000000000000..8df669c77899
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerExtends/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<String> l) {
+ l.add("");
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/Test.items b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/Test.items
new file mode 100644
index 000000000000..736189db2585
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/Test.items
@@ -0,0 +1,10 @@
+Types:
+PsiMethodCallExpression:l.add("") : boolean
+PsiParameter:l : java.lang.ThreadLocal<java.util.List<? super java.lang.String>>
+PsiReferenceExpression:l : java.lang.ThreadLocal<java.util.List<? super java.lang.String>>
+
+Conversions:
+l.add("") -> $qualifier$.get() $qualifier$ l
+
+New expression type changes:
+Fails:
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/test.java
new file mode 100644
index 000000000000..fb3b568ca1b0
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/after/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(ThreadLocal<List<? super String>> l) {
+ l.get().add("");
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/before/test.java b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/before/test.java
new file mode 100644
index 000000000000..8df669c77899
--- /dev/null
+++ b/plugins/typeMigration/testData/refactoring/wildcard/threadLocalProducerSuper/before/test.java
@@ -0,0 +1,7 @@
+import java.util.*;
+
+class Test {
+ void method(List<String> l) {
+ l.add("");
+ }
+} \ No newline at end of file
diff --git a/plugins/typeMigration/typeMigration.iml b/plugins/typeMigration/typeMigration.iml
new file mode 100644
index 000000000000..ac3679760ed4
--- /dev/null
+++ b/plugins/typeMigration/typeMigration.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="util" />
+ <orderEntry type="module" module-name="lang-api" />
+ <orderEntry type="module" module-name="lang-impl" />
+ <orderEntry type="module" module-name="openapi" />
+ <orderEntry type="module" module-name="structuralsearch" />
+ <orderEntry type="module" module-name="java-impl" />
+ <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ <orderEntry type="module" module-name="structuralsearch-java" />
+ </component>
+</module>
+
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/AbstractCreationTool.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/AbstractCreationTool.java
index 00f3039e39a8..62a3cdc7f7a5 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/AbstractCreationTool.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/AbstractCreationTool.java
@@ -137,4 +137,8 @@ public abstract class AbstractCreationTool extends TargetingTool {
myToolProvider.loadDefaultTool();
}
}
+
+ @Override
+ protected void handleKeyEvent() {
+ }
} \ No newline at end of file
diff --git a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java
index 900fe2703ecb..02cbffd50b38 100644
--- a/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java
+++ b/plugins/ui-designer-core/src/com/intellij/designer/designSurface/tools/TargetingTool.java
@@ -125,7 +125,7 @@ public abstract class TargetingTool extends InputTool {
}
}
- private void handleKeyEvent() {
+ protected void handleKeyEvent() {
if (myContext != null) {
updateContext();
showFeedback();
diff --git a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java
index defecc586594..228930ece929 100644
--- a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java
+++ b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java
@@ -27,7 +27,6 @@ import com.intellij.uiDesigner.lw.LwRootContainer;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.asm4.ClassReader;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.DirtyFilesHolder;
@@ -43,6 +42,7 @@ import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping;
import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.uiDesigner.model.JpsUiDesignerConfiguration;
import org.jetbrains.jps.uiDesigner.model.JpsUiDesignerExtensionService;
+import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.*;
import java.util.*;
diff --git a/plugins/ui-designer/jps-plugin/testSrc/org/jetbrains/jps/uiDesigner/build/FormsBuilderTest.java b/plugins/ui-designer/jps-plugin/testSrc/org/jetbrains/jps/uiDesigner/build/FormsBuilderTest.java
index 1bac0246be7e..0096498061d1 100644
--- a/plugins/ui-designer/jps-plugin/testSrc/org/jetbrains/jps/uiDesigner/build/FormsBuilderTest.java
+++ b/plugins/ui-designer/jps-plugin/testSrc/org/jetbrains/jps/uiDesigner/build/FormsBuilderTest.java
@@ -18,10 +18,6 @@ package org.jetbrains.jps.uiDesigner.build;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.uiDesigner.core.AbstractLayout;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.MethodVisitor;
-import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jps.builders.JpsBuildTestCase;
import org.jetbrains.jps.incremental.java.JavaBuilder;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
@@ -29,6 +25,10 @@ import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.uiDesigner.compiler.FormsInstrumenter;
import org.jetbrains.jps.uiDesigner.model.JpsUiDesignerExtensionService;
import org.jetbrains.jps.util.JpsPathUtil;
+import org.jetbrains.org.objectweb.asm.ClassReader;
+import org.jetbrains.org.objectweb.asm.ClassVisitor;
+import org.jetbrains.org.objectweb.asm.MethodVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.IOException;
@@ -124,7 +124,7 @@ public class FormsBuilderTest extends JpsBuildTestCase {
assertTrue(file.getAbsolutePath() + " not found", file.exists());
final Ref<Boolean> instrumented = Ref.create(false);
- ClassVisitor visitor = new ClassVisitor(Opcodes.ASM4) {
+ ClassVisitor visitor = new ClassVisitor(Opcodes.ASM5) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("$$$setupUI$$$")) {
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
index de22555f9b70..a5cd762fcf15 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaDirectoryService;
+import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiDirectory;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.util.IncorrectOperationException;
@@ -92,4 +93,18 @@ public abstract class AbstractCreateFormAction extends CreateElementActionBase i
protected String getActionName(final PsiDirectory directory, final String newName) {
return UIDesignerBundle.message("progress.creating.class", JavaDirectoryService.getInstance().getPackage(directory).getQualifiedName(), newName);
}
-}
+
+ protected class JavaNameValidator extends MyInputValidator {
+ private final Project myProject;
+
+ public JavaNameValidator(Project project, PsiDirectory directory) {
+ super(project, directory);
+ myProject = project;
+ }
+
+ @Override
+ public boolean checkInput(String inputString) {
+ return inputString.length() > 0 && JavaPsiFacade.getInstance(myProject).getNameHelper().isQualifiedName(inputString);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateDialogAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateDialogAction.java
index 1b90f76942ea..78715ddf72b8 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateDialogAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateDialogAction.java
@@ -45,7 +45,7 @@ public final class CreateDialogAction extends AbstractCreateFormAction {
@NotNull
protected PsiElement[] invokeDialog(final Project project, final PsiDirectory directory) {
- final MyInputValidator validator = new MyInputValidator(project, directory);
+ final MyInputValidator validator = new JavaNameValidator(project, directory);
final MyContentPane contentPane = new MyContentPane();
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java
index 04a9fd8bb513..9e296251bc11 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/CreateFormAction.java
@@ -68,7 +68,7 @@ public class CreateFormAction extends AbstractCreateFormAction {
@NotNull
protected PsiElement[] invokeDialog(Project project, PsiDirectory directory) {
- final MyInputValidator validator = new MyInputValidator(project, directory);
+ final MyInputValidator validator = new JavaNameValidator(project, directory);
final DialogWrapper dialog = new MyDialog(project, validator);
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceContributor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceContributor.java
index 72bc1f716993..a0d9d181efb3 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceContributor.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/binding/FormReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,13 +18,15 @@ package com.intellij.uiDesigner.binding;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
import com.intellij.psi.PsiPlainTextFile;
+import org.jetbrains.annotations.NotNull;
+
import static com.intellij.patterns.PlatformPatterns.psiFile;
/**
* @author yole
*/
public class FormReferenceContributor extends PsiReferenceContributor {
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(psiFile(PsiPlainTextFile.class), new FormReferenceProvider());
}
}
diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/make/PreviewNestedFormLoader.java b/plugins/ui-designer/src/com/intellij/uiDesigner/make/PreviewNestedFormLoader.java
index 88dd5f9b12e6..4ee096e4d9c8 100644
--- a/plugins/ui-designer/src/com/intellij/uiDesigner/make/PreviewNestedFormLoader.java
+++ b/plugins/ui-designer/src/com/intellij/uiDesigner/make/PreviewNestedFormLoader.java
@@ -27,9 +27,9 @@ import com.intellij.uiDesigner.lw.LwRootContainer;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.asm4.ClassWriter;
-import org.jetbrains.asm4.MethodVisitor;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
+import org.jetbrains.org.objectweb.asm.MethodVisitor;
+import org.jetbrains.org.objectweb.asm.Opcodes;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -72,10 +72,7 @@ public class PreviewNestedFormLoader extends PsiNestedFormLoader {
@NonNls MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "java/lang/Object",
- "<init>",
- "()V");
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
diff --git a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java
index a45dfeb88204..358f381c9f4a 100644
--- a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java
+++ b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java
@@ -34,7 +34,7 @@ import com.intellij.util.ui.UIUtil;
import com.sun.tools.javac.Main;
import gnu.trove.TIntObjectHashMap;
import junit.framework.TestCase;
-import org.jetbrains.asm4.ClassWriter;
+import org.jetbrains.org.objectweb.asm.ClassWriter;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
diff --git a/plugins/ui-designer/ui-designer.iml b/plugins/ui-designer/ui-designer.iml
index 49c19873c4b1..e6a868e99465 100644
--- a/plugins/ui-designer/ui-designer.iml
+++ b/plugins/ui-designer/ui-designer.iml
@@ -19,7 +19,7 @@
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="icons" />
<orderEntry type="library" name="jgoodies-forms" level="project" />
- <orderEntry type="library" name="asm4" level="project" />
+ <orderEntry type="library" name="asm5" level="project" />
<orderEntry type="module" module-name="java-i18n" exported="" />
<orderEntry type="module" module-name="idea-ui" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/FileAssociationsManager.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/FileAssociationsManager.java
index 939109753e11..48fd91a19285 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/FileAssociationsManager.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/FileAssociationsManager.java
@@ -15,17 +15,18 @@
*/
package org.intellij.lang.xpath.xslt.associations;
-import com.intellij.psi.PsiFile;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SimpleModificationTracker;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
-public abstract class FileAssociationsManager {
+public abstract class FileAssociationsManager extends SimpleModificationTracker {
public static final FileType[] XML_FILES = new FileType[]{ StdFileTypes.XML, StdFileTypes.XHTML };
public static final List<FileType> XML_FILES_LIST = Arrays.asList(XML_FILES);
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java
index 7b339e17378d..2ab73ba0976d 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/associations/impl/FileAssociationsManagerImpl.java
@@ -15,17 +15,13 @@
*/
package org.intellij.lang.xpath.xslt.associations.impl;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.psi.util.PsiUtilCore;
-import org.intellij.lang.xpath.xslt.associations.FileAssociationsManager;
-
import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
@@ -33,20 +29,20 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.psi.util.PsiUtilCore;
+import org.intellij.lang.xpath.xslt.associations.FileAssociationsManager;
+import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jdom.Element;
-
import java.util.*;
-class FileAssociationsManagerImpl extends FileAssociationsManager implements ProjectComponent, JDOMExternalizable, ModificationTracker {
+class FileAssociationsManagerImpl extends FileAssociationsManager implements ProjectComponent, JDOMExternalizable {
private static final Logger LOG = Logger.getInstance(FileAssociationsManagerImpl.class);
private final Project myProject;
private final VirtualFilePointerManager myFilePointerManager;
private final Map<VirtualFilePointer, VirtualFilePointerContainer> myAssociations;
- private long myModCount;
private boolean myTempCopy;
public FileAssociationsManagerImpl(Project project, VirtualFilePointerManager filePointerManager) {
@@ -121,7 +117,7 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Pro
}
private void touch() {
- myModCount++;
+ incModificationCount();
if (!myTempCopy) {
final ProjectView view = ProjectView.getInstance(myProject);
if (view != null) {
@@ -264,8 +260,4 @@ class FileAssociationsManagerImpl extends FileAssociationsManager implements Pro
}
return false;
}
-
- public long getModificationCount() {
- return myModCount;
- }
}
diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java
index 6cb553f431e5..0ff49d08f81f 100644
--- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java
+++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -49,13 +49,13 @@ public class XsltReferenceContributor {
}
public static class XPath extends PsiReferenceContributor {
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(psiElement(XPath2TypeElement.class), SchemaTypeProvider.INSTANCE);
}
}
public static class XML extends PsiReferenceContributor {
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(
psiElement(XmlAttributeValue.class).withParent(
xmlAttribute().withLocalName("name", "href", "mode", "elements", "exclude-result-prefixes", "extension-element-prefixes", "stylesheet-prefix").withParent(
diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java
index dd1469437633..3d3b8dcc87cc 100644
--- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java
+++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java
@@ -297,7 +297,7 @@ public class XPathEvalAction extends XPathAction {
});
}
- public static void showUsageView(final Project project, MyUsageTarget usageTarget, Factory<UsageSearcher> searcherFactory, final EditExpressionAction editAction) {
+ public static void showUsageView(@NotNull final Project project, MyUsageTarget usageTarget, Factory<UsageSearcher> searcherFactory, final EditExpressionAction editAction) {
final UsageViewPresentation presentation = new UsageViewPresentation();
presentation.setTargetsNodeText("Expression");
presentation.setCodeUsages(false);
diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java
index 4231f2cf42b9..6384e04f1f99 100644
--- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java
+++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java
@@ -54,7 +54,7 @@ public class FindByXPathAction extends AnAction {
}
}
- private void executeSearch(final Project project, final Module module) {
+ private void executeSearch(@NotNull final Project project, final Module module) {
final Config settings = XPathAppComponent.getInstance().getConfig();
final XPathProjectComponent projectComponent = XPathProjectComponent.getInstance(project);
diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.form b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.form
index c87e145b593f..ff5481019391 100644
--- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.form
+++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.form
@@ -58,7 +58,7 @@
</constraints>
<properties/>
</component>
- <component id="add6e" class="com.intellij.openapi.ui.ComboBox" binding="myModuleSelection">
+ <component id="add6e" class="com.intellij.application.options.ModulesComboBox" binding="myModuleSelection">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.java
index 554f54daf5c2..4e15b28864d0 100644
--- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.java
+++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/ScopePanel.java
@@ -20,14 +20,12 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.ComboBox;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.DocumentAdapter;
-import com.intellij.ui.ListCellRendererWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,7 +44,7 @@ public class ScopePanel extends JPanel implements Disposable{
private JRadioButton myWholeProjectScope;
private JRadioButton myModuleScope;
- private ComboBox myModuleSelection;
+ private ModulesComboBox myModuleSelection;
private JRadioButton myDirectoryScope;
private TextFieldWithBrowseButton myDirectory;
@@ -91,16 +89,7 @@ public class ScopePanel extends JPanel implements Disposable{
myCustomScope.addItemListener(stateListener);
myCustomScope.setSelected(scope.getScopeType() == SearchScope.ScopeType.CUSTOM);
- myModuleSelection.setModel(createModel(ModuleManager.getInstance(myProject).getModules()));
- myModuleSelection.setRenderer(new ListCellRendererWrapper<Module>() {
- @Override
- public void customize(JList list, Module m, int index, boolean selected, boolean hasFocus) {
- if (m != null) {
- setIcon(ModuleType.get(m).getIcon());
- setText(m.getName());
- }
- }
- });
+ myModuleSelection.fillModules(myProject);
Module m;
if (scope.getModuleName() != null) {
@@ -111,7 +100,7 @@ public class ScopePanel extends JPanel implements Disposable{
m = currentModule;
}
if (m != null) {
- myModuleSelection.setSelectedItem(m);
+ myModuleSelection.setSelectedModule(m);
}
myModuleSelection.addItemListener(scopeListener);
@@ -148,7 +137,7 @@ public class ScopePanel extends JPanel implements Disposable{
@Nullable
private String getModuleName() {
- final Module module = ((Module)myModuleSelection.getSelectedItem());
+ final Module module = myModuleSelection.getSelectedModule();
return module != null ? module.getName() : null;
}
diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/SearchScope.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/SearchScope.java
index b4815f1dbd73..775d90280d07 100644
--- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/SearchScope.java
+++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/SearchScope.java
@@ -83,6 +83,7 @@ public class SearchScope implements JDOMExternalizable {
myCustomScope = customScope;
}
+ @NotNull
public String getName() {
switch (getScopeType()) {
case PROJECT:
diff --git a/python/build/pycharm_community_build.gant b/python/build/pycharm_community_build.gant
index 7efb4e385a6f..3b793ec4498f 100644
--- a/python/build/pycharm_community_build.gant
+++ b/python/build/pycharm_community_build.gant
@@ -173,7 +173,7 @@ public layoutCommunity(String classesPath, Set usedJars) {
String tarRoot = isEap() ? "pycharm-community-$buildNumber" : "pycharm-community-${p("component.version.major")}.${p("component.version.minor")}"
buildTarGz(tarRoot, "$paths.artifacts/pycharmPC-${buildNumber}.tar", [paths.distAll, paths.distUnix])
- String macAppRoot = isEap() ? "PyCharm CE ${p("component.version.major")}.${p("component.version.minor")} EAP.app" : "PyCharm CE.app"
+ String macAppRoot = isEap() ? "PyCharm CE ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm CE.app/Contents"
buildMacZip(macAppRoot, "${paths.artifacts}/pycharmPC-${buildNumber}.sit", [paths.distAll], paths.distMac)
}
@@ -181,22 +181,6 @@ private layoutPlugins(layouts) {
dir("plugins") {
layouts.layoutPlugin("rest")
layouts.layoutPlugin("python-rest")
- /*
- layouts.layoutPlugin("pycharm-flask")
- layouts.layoutPlugin("pycharm-numpy")
- layouts.layoutPlugin("textmate") {
- dir("themes") {
- fileset(dir: "${home}/plugins/textmate/lib/themes/", includes: "*.tmTheme")
- }
- fileset(dir: "${home}/plugins/textmate/lib") {
- include(name: "jcodings.jar")
- include(name: "joni.jar")
- }
- }
- layouts.layoutPlugin("puppet")
- layouts.layoutPlugin("fileWatcher")
- layouts.layoutPlugin("ini4idea")
- */
}
layouts.layoutCommunityPlugins(ch)
diff --git a/python/build/python_plugin_build.gant b/python/build/python_plugin_build.gant
index dc37d14f4480..702ab301f863 100644
--- a/python/build/python_plugin_build.gant
+++ b/python/build/python_plugin_build.gant
@@ -95,6 +95,7 @@ target(name: "compile", description: "Compile module python") {
dirset(dir: "${pluginHome}") {
include(name: "resources")
include(name: "src")
+ include(name: "gen")
include(name: "pluginSrc")
include(name: "pydevSrc")
include(name: "openapi/src")
diff --git a/python/gen/icons/PythonIcons.java b/python/gen/icons/PythonIcons.java
index 4e91858a0969..b4c59bdb3b30 100644
--- a/python/gen/icons/PythonIcons.java
+++ b/python/gen/icons/PythonIcons.java
@@ -45,6 +45,7 @@ public class PythonIcons {
public static final Icon PropertyGetter = load("/icons/com/jetbrains/python/propertyGetter.png"); // 16x16
public static final Icon PropertySetter = load("/icons/com/jetbrains/python/propertySetter.png"); // 16x16
public static final Icon Pypy = load("/icons/com/jetbrains/python/pypy.png"); // 16x16
+ public static final Icon Python_logo = load("/icons/com/jetbrains/python/python-logo.png"); // 32x32
public static final Icon Python = load("/icons/com/jetbrains/python/python.png"); // 16x16
public static final Icon Python_24 = load("/icons/com/jetbrains/python/python_24.png"); // 24x24
public static final Icon PythonClosed = load("/icons/com/jetbrains/python/pythonClosed.png"); // 16x16
diff --git a/python/helpers/packaging_tool.py b/python/helpers/packaging_tool.py
index c66cbcba2fe2..9101a16be1b3 100644
--- a/python/helpers/packaging_tool.py
+++ b/python/helpers/packaging_tool.py
@@ -21,7 +21,7 @@ def exit(retcode):
def usage():
- sys.stderr.write('Usage: packaging_tool.py <list|install|uninstall|pyvenv>\n')
+ sys.stderr.write('Usage: packaging_tool.py <list|search|install|uninstall|pyvenv>\n')
sys.stderr.flush()
exit(ERROR_WRONG_USAGE)
@@ -58,6 +58,13 @@ def do_install(pkgs):
error_no_pip()
return pip.main(['install'] + pkgs)
+def do_search(pkgs):
+ try:
+ import pip
+ except ImportError:
+ error_no_pip()
+ return pip.main(['search'] + pkgs)
+
def do_uninstall(pkgs):
try:
@@ -115,6 +122,11 @@ def main():
if len(sys.argv) != 2:
usage()
do_list()
+ elif cmd == 'search':
+ if len(sys.argv) < 2:
+ usage()
+ pkgs = sys.argv[2:]
+ do_search(pkgs)
elif cmd == 'install':
if len(sys.argv) < 2:
usage()
diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py
index 0e96b9c2c720..3af1961a0e09 100644
--- a/python/helpers/pycharm_generator_utils/module_redeclarator.py
+++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py
@@ -120,7 +120,7 @@ class ModuleRedeclarator(object):
init = None
try:
if self.split_modules:
- mod_path = self.outfile.strip(".py")
+ mod_path = module_to_package_name(self.outfile)
fname = build_output_name(mod_path, "__init__")
init = fopen(fname, "w")
@@ -1093,3 +1093,7 @@ class ModuleRedeclarator(object):
for mod_name in sorted_no_case(self.hidden_imports.keys()):
out(0, 'import ', mod_name, ' as ', self.hidden_imports[mod_name])
out(0, "") # empty line after group
+
+
+def module_to_package_name(module_name):
+ return re.sub(r"(.*)\.py$", r"\1", module_name)
diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py
index 4a509d053619..2077903ea091 100644
--- a/python/helpers/pydev/pydevd.py
+++ b/python/helpers/pydev/pydevd.py
@@ -814,7 +814,7 @@ class PyDB:
del self.exception_set[exception]
self.always_exception_set.remove(exception)
except:
- pydev_log.debug("Error while removing exception"%sys.exc_info()[0]);
+ pydev_log.debug("Error while removing exception %s"%sys.exc_info()[0]);
update_exception_hook(self)
elif cmd_id == CMD_LOAD_SOURCE:
diff --git a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.form b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.form
index 108b9af1902f..b732b517538b 100644
--- a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.form
+++ b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.form
@@ -80,7 +80,7 @@
<text value="Pro&amp;ject:"/>
</properties>
</component>
- <component id="195cd" class="javax.swing.JComboBox" binding="myModuleCombo">
+ <component id="195cd" class="com.intellij.application.options.ModulesComboBox" binding="myModuleCombo">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
index 94e991240001..3b590371e610 100644
--- a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
+++ b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer;
import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
@@ -40,7 +41,6 @@ import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
import com.jetbrains.python.configuration.PyConfigureInterpretersLinkPanel;
import com.jetbrains.python.run.AbstractPyCommonOptionsForm;
-import com.intellij.application.options.ModuleListCellRenderer;
import com.jetbrains.python.run.PyCommonOptionsFormData;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkType;
@@ -64,7 +64,7 @@ public class PyIdeCommonOptionsForm implements AbstractPyCommonOptionsForm {
private JComboBox myInterpreterComboBox;
private JBLabel myPythonInterpreterJBLabel;
private JLabel myProjectLabel;
- private JComboBox myModuleCombo;
+ private ModulesComboBox myModuleCombo;
private JPanel myConfigureInterpretersPanel;
private String mySelectedSdkHome = null;
private PathMappingsComponent myPathMappingsComponent;
@@ -97,15 +97,15 @@ public class PyIdeCommonOptionsForm implements AbstractPyCommonOptionsForm {
else {
final List<Module> validModules = data.getValidModules();
Module selection = validModules.size() > 0 ? validModules.get(0) : null;
- myModuleCombo.setModel(new CollectionComboBoxModel(validModules, selection));
- myModuleCombo.setRenderer(new ModuleListCellRenderer());
+ myModuleCombo.setModules(validModules);
+ myModuleCombo.setSelectedModule(selection);
myModuleCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- updateDefaultInterpreter((Module)myModuleCombo.getSelectedItem());
+ updateDefaultInterpreter(myModuleCombo.getSelectedModule());
}
});
- updateDefaultInterpreter((Module)myModuleCombo.getSelectedItem());
+ updateDefaultInterpreter(myModuleCombo.getSelectedModule());
}
setAnchor(myEnvsComponent.getLabel());
@@ -200,7 +200,7 @@ public class PyIdeCommonOptionsForm implements AbstractPyCommonOptionsForm {
@Nullable
@Override
public Module getModule() {
- final Module selectedItem = (Module)myModuleCombo.getSelectedItem();
+ final Module selectedItem = myModuleCombo.getSelectedModule();
if (selectedItem != null) {
return selectedItem;
}
@@ -213,7 +213,7 @@ public class PyIdeCommonOptionsForm implements AbstractPyCommonOptionsForm {
@Override
public void setModule(Module module) {
- myModuleCombo.setSelectedItem(module);
+ myModuleCombo.setSelectedModule(module);
updateDefaultInterpreter(module);
}
diff --git a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
index 2d89427c1bdf..3010b74486fa 100644
--- a/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
+++ b/python/ide/src/com/jetbrains/python/PythonSdkChooserCombo.java
@@ -19,20 +19,16 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkType;
-import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.util.NullableConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
-import com.jetbrains.python.sdk.PyDetectedSdk;
+import com.jetbrains.python.sdk.PySdkListCellRenderer;
import com.jetbrains.python.sdk.PySdkService;
import com.jetbrains.python.sdk.PythonSdkDetailsStep;
-import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -58,14 +54,7 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton {
}
final JComboBox comboBox = getComboBox();
comboBox.setModel(new CollectionComboBoxModel(sdks, initialSelection));
- comboBox.setRenderer(new SdkListCellRenderer("<no interpreter>") {
- @Override
- protected Icon getSdkIcon(Sdk sdk) {
- final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(sdk);
- final Icon icon = flavor != null ? flavor.getIcon() : ((SdkType)sdk.getSdkType()).getIcon();
- return sdk instanceof PyDetectedSdk ? IconLoader.getTransparentIcon(icon) : icon;
- }
- });
+ comboBox.setRenderer(new PySdkListCellRenderer(true));
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showOptions(project);
diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
index b2a7d915aaa2..fc165b8893f6 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java
@@ -188,7 +188,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
}
};
mySdkCombo.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
- mySdkCombo.setRenderer(new PySdkListCellRenderer());
+ mySdkCombo.setRenderer(new PySdkListCellRenderer(false));
final PackagesNotificationPanel notificationsArea = new PackagesNotificationPanel(myProject);
final JComponent notificationsComponent = notificationsArea.getComponent();
@@ -407,7 +407,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable {
items.add(PySdkListCellRenderer.SEPARATOR);
items.add(SHOW_ALL);
- mySdkCombo.setRenderer(new PySdkListCellRenderer());
+ mySdkCombo.setRenderer(new PySdkListCellRenderer(false));
//noinspection unchecked
mySdkCombo.setModel(new CollectionComboBoxModel(items, selection));
}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java b/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
index 1c1a6635e93d..33169a79d267 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonPathEditor.java
@@ -300,7 +300,7 @@ public class PythonPathEditor extends SdkPathEditor {
}
- private static class PythonPathListCellRenderer extends ListCellRendererWrapper<VirtualFile> {
+ private class PythonPathListCellRenderer extends ListCellRendererWrapper<VirtualFile> {
private final PathListModel model;
public PythonPathListCellRenderer(final ListCellRenderer listCellRenderer, PathListModel model) {
@@ -314,7 +314,11 @@ public class PythonPathEditor extends SdkPathEditor {
if (suffix.length() > 0) {
suffix = " " + suffix;
}
- setText(value != null ? value.getPresentableUrl() + suffix : "");
+ setText(value != null ? getPresentablePath(value) + suffix : "");
}
}
+
+ protected String getPresentablePath(VirtualFile value) {
+ return value.getPresentableUrl();
+ }
}
diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
index 6ff0a2e36c3e..b0ca6dbff65f 100644
--- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
+++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java
@@ -45,6 +45,7 @@ import com.intellij.ui.components.JBList;
import com.intellij.util.NullableConsumer;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.FactoryMap;
+import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import com.jetbrains.python.sdk.*;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
@@ -286,8 +287,9 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
myModifiedModificators.add(modificator);
}
final Sdk oldSdk = myProjectSdksModel.findSdk(sdk);
- if (oldSdk == null)
+ if (oldSdk == null) {
myProjectSdksModel.addSdk(sdk);
+ }
refreshSdkList();
mySdkList.setSelectedValue(sdk, true);
mySdkListChanged = true;
@@ -452,15 +454,10 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
return LocalFileSystem.getInstance().refreshAndFindFileByPath(sdkName);
}
});
- sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null, null);
+ sdk =
+ SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null, null);
}
- final PythonPathEditor pathEditor =
- new PythonPathEditor("Classes", OrderRootType.CLASSES, FileChooserDescriptorFactory.createAllButJarContentsDescriptor()) {
- @Override
- protected void onReloadButtonClicked() {
- reloadSdk();
- }
- };
+ final PythonPathEditor pathEditor = createPathEditor(sdk);
final SdkModificator sdkModificator = myModificators.get(sdk);
PythonPathDialog dialog = new PythonPathDialog(myProject, pathEditor);
@@ -476,4 +473,40 @@ public class PythonSdkDetailsDialog extends DialogWrapper {
updateOkButton();
}
}
+
+ private PythonPathEditor createPathEditor(final Sdk sdk) {
+ if (PySdkUtil.isRemote(sdk)) {
+ return new PythonPathEditor("Classes", OrderRootType.CLASSES, FileChooserDescriptorFactory.createAllButJarContentsDescriptor()) {
+ private final PyRemoteSdkAdditionalDataBase myRemoteSdkData = (PyRemoteSdkAdditionalDataBase) sdk.getSdkAdditionalData();
+ @Override
+ protected void onReloadButtonClicked() {
+ reloadSdk();
+ }
+
+ @Override
+ protected String getPresentablePath(VirtualFile value) {
+ String path = value.getPath();
+ return myRemoteSdkData.getPathMappings().convertToRemote(path);
+ }
+
+ @Override
+ protected void addToolbarButtons(ToolbarDecorator toolbarDecorator) {
+ toolbarDecorator.setAddActionUpdater(new AnActionButtonUpdater() {
+ @Override
+ public boolean isEnabled(AnActionEvent e) {
+ return false; //TODO: implement adding remote path
+ }
+ });
+ }
+ };
+ }
+ else {
+ return new PythonPathEditor("Classes", OrderRootType.CLASSES, FileChooserDescriptorFactory.createAllButJarContentsDescriptor()) {
+ @Override
+ protected void onReloadButtonClicked() {
+ reloadSdk();
+ }
+ };
+ }
+ }
}
diff --git a/images/src/org/intellij/images/actions/ColorPickerForImageAction.java b/python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectAction.java
index ea70d4eb9cb8..85f649c6f6cf 100644
--- a/images/src/org/intellij/images/actions/ColorPickerForImageAction.java
+++ b/python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -13,17 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.intellij.images.actions;
+package com.jetbrains.python.newProject;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.ui.ShowColorPickerAction;
-/**
- * @author Konstantin Bulenkov
- */
-public class ColorPickerForImageAction extends ShowColorPickerAction {
- @Override
- public void update(AnActionEvent e) {
- EditExternallyAction.doUpdate(e);
+public class PyCharmNewProjectAction extends AnAction {
+
+ public void actionPerformed(final AnActionEvent e) {
+ final PyCharmNewProjectDialog dlg = new PyCharmNewProjectDialog();
+ dlg.show();
}
}
diff --git a/python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectDialog.java b/python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectDialog.java
new file mode 100644
index 000000000000..d186f33620e5
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/PyCharmNewProjectDialog.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject;
+
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.wm.impl.welcomeScreen.CardActionsPanel;
+import com.jetbrains.python.newProject.actions.PyCharmNewProjectStep;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class PyCharmNewProjectDialog extends DialogWrapper {
+ public PyCharmNewProjectDialog() {
+ super(ProjectManager.getInstance().getDefaultProject());
+ setTitle(" "); // hack to make native fileChooser work on Mac. See MacFileChooserDialogImpl.MAIN_THREAD_RUNNABLE
+ init();
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ PyCharmNewProjectDialog.this.close(OK_EXIT_CODE);
+ }
+ };
+ final DefaultActionGroup root = new PyCharmNewProjectStep(runnable);
+
+ return new CardActionsPanel(root) {
+
+ @Override
+ public Dimension getPreferredSize() {
+ return getMinimumSize();
+ }
+
+ @Override
+ public Dimension getMinimumSize() {
+ return new Dimension(650, 450);
+ }
+ };
+ }
+
+ @Override
+ protected String getHelpId() {
+ return null;
+ }
+
+ @NotNull
+ protected Action[] createActions() {
+ return new Action[0];
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/PythonBaseProjectGenerator.java b/python/ide/src/com/jetbrains/python/newProject/PythonBaseProjectGenerator.java
new file mode 100644
index 000000000000..a862956c7cea
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/PythonBaseProjectGenerator.java
@@ -0,0 +1,82 @@
+package com.jetbrains.python.newProject;
+
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.remote.RemoteSdkCredentials;
+import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
+import com.jetbrains.python.remote.RemoteProjectSettings;
+import icons.PythonIcons;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+
+public class PythonBaseProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator {
+ @NotNull
+ @Nls
+ @Override
+ public String getName() {
+ return "Pure Python";
+ }
+
+ @Nullable
+ @Override
+ public Object showGenerationSettings(VirtualFile baseDir) throws ProcessCanceledException {
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public JComponent getSettingsPanel(File baseDir) throws ProcessCanceledException {
+ return null;
+ }
+
+ @Override
+ public Object getProjectSettings() {
+ return new PyNewProjectSettings();
+ }
+
+ @Nullable
+ @Override
+ public Icon getLogo() {
+ return PythonIcons.Python.Python_logo;
+ }
+
+ @Override
+ public void generateProject(@NotNull final Project project, @NotNull VirtualFile baseDir, final Object settings,
+ @NotNull final Module module) {
+ if (settings instanceof RemoteProjectSettings) {
+ PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
+ assert manager != null;
+ manager.createDeployment(project, baseDir, (RemoteProjectSettings)settings,
+ (RemoteSdkCredentials)((RemoteProjectSettings)settings).getSdk().getSdkAdditionalData());
+ }
+ else if (settings instanceof PyNewProjectSettings) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ ModuleRootModificationUtil.setModuleSdk(module, ((PyNewProjectSettings)settings).getSdk());
+ }
+ });
+ }
+ }
+
+ @NotNull
+ @Override
+ public ValidationResult validate(@NotNull String baseDirPath) {
+ /*if (PythonSdkType.isRemote(myProjectAction.getSdk())) {
+ if (PythonRemoteInterpreterManager.getInstance() == null) {
+ return new ValidationResult(PythonRemoteInterpreterManager.WEB_DEPLOYMENT_PLUGIN_IS_DISABLED);
+ }
+ }*/
+ return ValidationResult.OK;
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectAction.java b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectAction.java
deleted file mode 100644
index a58fdd641dbf..000000000000
--- a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectAction.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.newProject;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.SdkAdditionalData;
-import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
-import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.platform.DirectoryProjectGenerator;
-import com.intellij.platform.NewDirectoryProjectAction;
-import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
-import com.jetbrains.python.sdk.PyDetectedSdk;
-import com.jetbrains.python.sdk.PySdkService;
-import com.jetbrains.python.sdk.PythonSdkAdditionalData;
-import com.jetbrains.python.sdk.PythonSdkType;
-
-import java.util.List;
-
-/**
- * User : catherine
- */
-public class PythonNewDirectoryProjectAction extends NewDirectoryProjectAction {
- private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.newProject.PythonNewDirectoryProjectAction");
- private Sdk mySdk;
- private boolean myInstallFramework;
-
- public void actionPerformed(final AnActionEvent e) {
- Project project = e.getData(CommonDataKeys.PROJECT);
- if (project == null) {
- project = ProjectManager.getInstance().getDefaultProject();
- }
- PythonNewDirectoryProjectDialog dlg = new PythonNewDirectoryProjectDialog(project);
- dlg.show();
- if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) return;
- mySdk = dlg.getSdk();
- final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
- if (mySdk instanceof PyDetectedSdk) {
- VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
- @Override
- public VirtualFile compute() {
- return LocalFileSystem.getInstance().refreshAndFindFileByPath(mySdk.getName());
- }
- });
- PySdkService.getInstance().solidifySdk(mySdk);
- mySdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null, null);
- model.addSdk(mySdk);
- try {
- model.apply();
- }
- catch (ConfigurationException exception) {
- LOG.error("Error adding detected python interpreter " + exception.getMessage());
- }
- }
- mySdk = model.findSdk(mySdk);
- myInstallFramework = dlg.installFramework();
- Project newProject = generateProject(project, dlg);
- if (newProject != null) {
- SdkConfigurationUtil.setDirectoryProjectSdk(newProject, mySdk);
- final List<Sdk> sdks = PythonSdkType.getAllSdks();
- for (Sdk sdk : sdks) {
- final SdkAdditionalData additionalData = sdk.getSdkAdditionalData();
- if (additionalData instanceof PythonSdkAdditionalData) {
- ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
- }
- }
- }
- }
-
- @Override
- protected Object showSettings(DirectoryProjectGenerator generator, VirtualFile baseDir)
- throws ProcessCanceledException {
- Object settings = super.showSettings(generator, baseDir);
- if (settings instanceof PyNewProjectSettings) {
- ((PyNewProjectSettings)settings).setSdk(mySdk);
- ((PyNewProjectSettings)settings).setInstallFramework(myInstallFramework);
- }
- return settings;
- }
-}
diff --git a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java b/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
deleted file mode 100644
index fe497d4ce320..000000000000
--- a/python/ide/src/com/jetbrains/python/newProject/PythonNewDirectoryProjectDialog.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.newProject;
-
-import com.intellij.facet.ui.ValidationResult;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.platform.DirectoryProjectGenerator;
-import com.intellij.platform.NewDirectoryProjectDialog;
-import com.intellij.remote.RemoteSdkCredentials;
-import com.intellij.ui.ComboboxWithBrowseButton;
-import com.intellij.ui.components.JBCheckBox;
-import com.intellij.ui.components.JBLabel;
-import com.jetbrains.python.PythonSdkChooserCombo;
-import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
-import com.jetbrains.python.configuration.VirtualEnvProjectFilter;
-import com.jetbrains.python.packaging.PyExternalProcessException;
-import com.jetbrains.python.packaging.PyPackage;
-import com.jetbrains.python.packaging.PyPackageManager;
-import com.jetbrains.python.packaging.PyPackageManagerImpl;
-import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
-import com.jetbrains.python.remote.RemoteProjectSettings;
-import com.jetbrains.python.sdk.PythonSdkType;
-import com.jetbrains.python.sdk.flavors.JythonSdkFlavor;
-import com.jetbrains.python.sdk.flavors.PyPySdkFlavor;
-import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
-import icons.PythonIcons;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.List;
-
-/**
- * User : catherine
- */
-public class PythonNewDirectoryProjectDialog extends NewDirectoryProjectDialog {
- private ComboboxWithBrowseButton mySdkCombo;
- private final JCheckBox myFrameworkCheckbox;
- private boolean myInstallFrameworkChanged;
- private final Project myProject;
-
- protected PythonNewDirectoryProjectDialog(Project project) {
- super(project);
- myProject = project;
-
- final List<Sdk> sdks = PyConfigurableInterpreterList.getInstance(myProject).getAllPythonSdks();
- VirtualEnvProjectFilter.removeAllAssociated(sdks);
- final Sdk preferred = sdks.isEmpty() ? null : sdks.iterator().next();
- mySdkCombo = new PythonSdkChooserCombo(project, sdks, new Condition<Sdk>() {
- @Override
- public boolean value(Sdk sdk) {
- return sdk == preferred;
- }
- });
- mySdkCombo.setButtonIcon(PythonIcons.Python.InterpreterGear);
-
- final JLabel label = new JBLabel("Interpreter:", SwingConstants.LEFT) {
- @Override
- public Dimension getMinimumSize() {
- return new JLabel("Project name:").getPreferredSize();
- }
-
- @Override
- public Dimension getPreferredSize() {
- return getMinimumSize();
- }
- };
- label.setLabelFor(mySdkCombo);
- final JPanel placeholder = getPlaceHolder();
- final GridBagConstraints constraints = new GridBagConstraints();
- constraints.gridx = 0;
- constraints.gridy = 0;
- constraints.anchor = GridBagConstraints.WEST;
- constraints.insets = new Insets(0, 0, 0, 10);
- placeholder.add(label, constraints);
-
- constraints.gridx = 1;
- constraints.gridy = 0;
- constraints.fill = GridBagConstraints.BOTH;
- constraints.weightx = 1.0;
- constraints.insets = new Insets(0, 0, 0, 0);
-
- placeholder.add(mySdkCombo, constraints);
-
- final ActionListener listener = new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent event) {
- checkValid();
- }
- };
-
- myFrameworkCheckbox = new JBCheckBox("Install <framework>");
- constraints.gridx = 0;
- constraints.gridy = 1;
- constraints.gridwidth = 2;
- constraints.weightx = 0.0;
- placeholder.add(myFrameworkCheckbox, constraints);
- myFrameworkCheckbox.setVisible(false);
-
- myFrameworkCheckbox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- myInstallFrameworkChanged = true;
- checkValid();
- }
- });
-
- mySdkCombo.addActionListener(listener);
- mySdkCombo.getComboBox().addActionListener(listener);
- myProjectTypeComboBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent event) {
- selectCompatiblePython();
- checkValid();
- }
- });
-
- mySdkCombo.getComboBox().addPropertyChangeListener(new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- checkValid();
- }
- });
-
- final Dimension checkBoxSize = myFrameworkCheckbox.getPreferredSize();
- myRootPane.setPreferredSize(new Dimension(myRootPane.getPreferredSize().width,
- myRootPane.getPreferredSize().height + checkBoxSize.height));
-
- checkValid();
- }
-
- @Override
- protected Object getEmptyProjectGenerator() {
- return new DirectoryProjectGenerator() {
-
- @NotNull
- @Nls
- @Override
- public String getName() {
- return "Empty project";
- }
-
- @Nullable
- @Override
- public Object showGenerationSettings(VirtualFile baseDir) throws ProcessCanceledException {
- if (PythonSdkType.isRemote(getSdk())) {
- PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
- assert manager != null;
- return manager.showRemoteProjectSettingsDialog(baseDir, (RemoteSdkCredentials)getSdk().getSdkAdditionalData());
- }
- else {
- return new PyNewProjectSettings();
- }
- }
-
- @Override
- public void generateProject(@NotNull final Project project,
- @NotNull VirtualFile baseDir,
- final Object settings,
- @NotNull final Module module) {
- if (settings instanceof RemoteProjectSettings) {
- PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
- assert manager != null;
- manager.createDeployment(project, baseDir, (RemoteProjectSettings)settings,
- (RemoteSdkCredentials)getSdk().getSdkAdditionalData());
- }
- else if (settings instanceof PyNewProjectSettings) {
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
- @Override
- public void run() {
- ModuleRootModificationUtil.setModuleSdk(module, ((PyNewProjectSettings)settings).getSdk());
- }
- });
- }
- }
-
- @NotNull
- @Override
- public ValidationResult validate(@NotNull String baseDirPath) {
- if (PythonSdkType.isRemote(getSdk())) {
- if (PythonRemoteInterpreterManager.getInstance() == null) {
- return new ValidationResult(PythonRemoteInterpreterManager.WEB_DEPLOYMENT_PLUGIN_IS_DISABLED);
- }
- }
- return ValidationResult.OK;
- }
- };
- }
-
- @Override
- public void checkValid() {
- super.checkValid();
- Sdk sdk = getSdk();
- if (isOKActionEnabled()) {
- setOKActionEnabled(true);
- setErrorText(null);
- myFrameworkCheckbox.setVisible(false);
-
- DirectoryProjectGenerator generator = getProjectGenerator();
- final boolean isPy3k = sdk != null && PythonSdkType.getLanguageLevelForSdk(sdk).isPy3K();
- if (sdk != null && PythonSdkType.isRemote(sdk) && !acceptsRemoteSdk(generator)) {
- setOKActionEnabled(false);
- setErrorText("Please choose a local interpreter");
- }
- else if (generator instanceof PyFrameworkProjectGenerator) {
- PyFrameworkProjectGenerator frameworkProjectGenerator = (PyFrameworkProjectGenerator)generator;
- String frameworkName = frameworkProjectGenerator.getFrameworkTitle();
- if (sdk != null && !isFrameworkInstalled(sdk)) {
- final PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(sdk);
- final boolean onlyWithCache =
- PythonSdkFlavor.getFlavor(sdk) instanceof JythonSdkFlavor || PythonSdkFlavor.getFlavor(sdk) instanceof PyPySdkFlavor;
- try {
- if (onlyWithCache && packageManager.cacheIsNotNull() || !onlyWithCache) {
- final PyPackage pip = packageManager.findPackage("pip");
- myFrameworkCheckbox.setText("Install " + frameworkName);
- myFrameworkCheckbox.setMnemonic(frameworkName.charAt(0));
- myFrameworkCheckbox.setVisible(pip != null);
- if (!myInstallFrameworkChanged) {
- myFrameworkCheckbox.setSelected(pip != null);
- }
- }
- }
- catch (PyExternalProcessException e) {
- myFrameworkCheckbox.setVisible(false);
- }
- if (!myFrameworkCheckbox.isSelected()) {
- setErrorText("No " + frameworkName + " support installed in selected interpreter");
- setOKActionEnabled(false);
- }
- }
- if (isPy3k && !((PyFrameworkProjectGenerator)generator).supportsPython3()) {
- setErrorText(frameworkName + " is not supported for the selected interpreter");
- setOKActionEnabled(false);
- }
- }
- if (sdk == null) {
- setOKActionEnabled(false);
- setErrorText("No Python interpreter selected");
- }
- }
- }
-
- private void selectCompatiblePython() {
- DirectoryProjectGenerator generator = getProjectGenerator();
- if (generator instanceof PyFrameworkProjectGenerator && !((PyFrameworkProjectGenerator)generator).supportsPython3()) {
- Sdk sdk = getSdk();
- if (sdk != null && PythonSdkType.getLanguageLevelForSdk(sdk).isPy3K()) {
- Sdk python2Sdk = PythonSdkType.findPython2Sdk(null);
- if (python2Sdk != null) {
- mySdkCombo.getComboBox().setSelectedItem(python2Sdk);
- mySdkCombo.getComboBox().repaint();
- }
- }
- }
- }
-
- private boolean isFrameworkInstalled(Sdk sdk) {
- PyFrameworkProjectGenerator projectGenerator = (PyFrameworkProjectGenerator)getProjectGenerator();
-
- return projectGenerator != null && projectGenerator.isFrameworkInstalled(myProject, sdk);
- }
-
- private static boolean acceptsRemoteSdk(DirectoryProjectGenerator generator) {
- if (generator instanceof PyFrameworkProjectGenerator) {
- return ((PyFrameworkProjectGenerator)generator).acceptsRemoteSdk();
- }
- return true;
- }
-
- public boolean installFramework() {
- return myFrameworkCheckbox.isSelected() && myFrameworkCheckbox.isVisible();
- }
-
- public Sdk getSdk() {
- return (Sdk)mySdkCombo.getComboBox().getSelectedItem();
- }
-}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java
new file mode 100644
index 000000000000..d9f3cf24f0e5
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/AbstractProjectSettingsStep.java
@@ -0,0 +1,408 @@
+package com.jetbrains.python.newProject.actions;
+
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.ide.util.projectWizard.WebProjectTemplate;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.impl.ActionButtonWithText;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.wm.impl.welcomeScreen.AbstractActionWithPanel;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.platform.WebProjectGenerator;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.util.NullableConsumer;
+import com.intellij.util.ui.UIUtil;
+import com.jetbrains.python.PythonSdkChooserCombo;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
+import com.jetbrains.python.configuration.VirtualEnvProjectFilter;
+import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import com.jetbrains.python.packaging.PyExternalProcessException;
+import com.jetbrains.python.packaging.PyPackage;
+import com.jetbrains.python.packaging.PyPackageManager;
+import com.jetbrains.python.packaging.PyPackageManagerImpl;
+import com.jetbrains.python.sdk.PythonSdkType;
+import com.jetbrains.python.sdk.flavors.JythonSdkFlavor;
+import com.jetbrains.python.sdk.flavors.PyPySdkFlavor;
+import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
+import icons.PythonIcons;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.List;
+
+abstract public class AbstractProjectSettingsStep extends AbstractActionWithPanel implements DumbAware {
+ protected final DirectoryProjectGenerator myProjectGenerator;
+ private final NullableConsumer<AbstractProjectSettingsStep> myCallback;
+ private PythonSdkChooserCombo mySdkCombo;
+ private boolean myInstallFramework;
+ private TextFieldWithBrowseButton myLocationField;
+ protected final File myProjectDirectory;
+ private ActionButtonWithText myCreateButton;
+ private JLabel myErrorLabel;
+ private AnAction myCreateAction;
+
+ public AbstractProjectSettingsStep(DirectoryProjectGenerator projectGenerator, NullableConsumer<AbstractProjectSettingsStep> callback) {
+ super();
+ myProjectGenerator = projectGenerator;
+ myCallback = callback;
+ myProjectDirectory = FileUtil.findSequentNonexistentFile(new File(ProjectUtil.getBaseDir()), "untitled", "");
+ if (myProjectGenerator instanceof WebProjectTemplate) {
+ ((WebProjectTemplate)myProjectGenerator).getPeer().addSettingsStateListener(new WebProjectGenerator.SettingsStateListener() {
+ @Override
+ public void stateChanged(boolean validSettings) {
+ checkValid();
+ }
+ });
+ }
+ else if (myProjectGenerator instanceof PythonProjectGenerator) {
+ ((PythonProjectGenerator)myProjectGenerator).addSettingsStateListener(new PythonProjectGenerator.SettingsListener() {
+ @Override
+ public void stateChanged() {
+ checkValid();
+ }
+ });
+ }
+
+ myCreateAction = new AnAction("Create", "Create Project", getIcon()) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ boolean isValid = checkValid();
+ if (isValid && myCallback != null)
+ myCallback.consume(AbstractProjectSettingsStep.this);
+ }
+ };
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ }
+
+ @Override
+ public JPanel createPanel() {
+ final JPanel mainPanel = new JPanel(new BorderLayout());
+ final JPanel scrollPanel = new JPanel(new BorderLayout());
+
+ mainPanel.setPreferredSize(new Dimension(mainPanel.getPreferredSize().width, 400));
+ myErrorLabel = new JLabel("");
+ myErrorLabel.setForeground(JBColor.RED);
+ myCreateButton = new Button(myCreateAction, myCreateAction.getTemplatePresentation());
+
+ final JPanel panel = createBasePanel();
+ scrollPanel.add(panel, BorderLayout.NORTH);
+ final JPanel advancedSettings = createAdvancedSettings();
+ if (advancedSettings != null) {
+ scrollPanel.add(advancedSettings, BorderLayout.CENTER);
+ }
+ final JBScrollPane scrollPane = new JBScrollPane(scrollPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
+ ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+ scrollPane.setBorder(null);
+ mainPanel.add(scrollPane, BorderLayout.CENTER);
+
+ final JPanel bottomPanel = new JPanel(new BorderLayout());
+
+
+ myCreateButton.setPreferredSize(new Dimension(mainPanel.getPreferredSize().width, 40));
+ bottomPanel.add(myErrorLabel, BorderLayout.NORTH);
+ bottomPanel.add(myCreateButton, BorderLayout.EAST);
+ mainPanel.add(bottomPanel, BorderLayout.SOUTH);
+ return mainPanel;
+ }
+
+ protected Icon getIcon() {
+ return myProjectGenerator.getLogo();
+ }
+
+ private JPanel createBasePanel() {
+ final JPanel panel = new JPanel(new GridBagLayout());
+ final GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.NORTHWEST;
+ c.weightx = 0;
+ c.insets = new Insets(2, 2, 2, 2);
+ myLocationField = new TextFieldWithBrowseButton();
+ myLocationField.setText(myProjectDirectory.toString());
+
+ final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ myLocationField.addBrowseFolderListener("Select base directory", "Select base directory for the Project",
+ null, descriptor);
+
+ final JLabel locationLabel = new JLabel("Location:");
+ c.gridx = 0;
+ c.gridy = 0;
+ panel.add(locationLabel, c);
+
+ c.gridx = 1;
+ c.gridy = 0;
+ c.weightx = 1.;
+ panel.add(myLocationField, c);
+
+ final JLabel interpreterLabel = new JLabel("Interpreter:", SwingConstants.LEFT) {
+ @Override
+ public Dimension getMinimumSize() {
+ return new JLabel("Project name:").getPreferredSize();
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return getMinimumSize();
+ }
+ };
+ c.gridx = 0;
+ c.gridy = 1;
+ c.weightx = 0;
+ panel.add(interpreterLabel, c);
+
+ final Project project = ProjectManager.getInstance().getDefaultProject();
+ final List<Sdk> sdks = PyConfigurableInterpreterList.getInstance(project).getAllPythonSdks();
+ VirtualEnvProjectFilter.removeAllAssociated(sdks);
+ final Sdk preferred = sdks.isEmpty() ? null : sdks.iterator().next();
+ mySdkCombo = new PythonSdkChooserCombo(project, sdks, new Condition<Sdk>() {
+ @Override
+ public boolean value(Sdk sdk) {
+ return sdk == preferred;
+ }
+ });
+ mySdkCombo.setButtonIcon(PythonIcons.Python.InterpreterGear);
+
+ c.gridx = 1;
+ c.gridy = 1;
+ c.weightx = 1.;
+ panel.add(mySdkCombo, c);
+
+ registerValidators();
+ return panel;
+ }
+
+ protected void registerValidators() {
+
+ myLocationField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent e) {
+ checkValid();
+ }
+ });
+ final ActionListener listener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ checkValid();
+ }
+ };
+ mySdkCombo.getComboBox().addPropertyChangeListener(new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ checkValid();
+ }
+ });
+ myLocationField.getTextField().addActionListener(listener);
+ mySdkCombo.getComboBox().addActionListener(listener);
+ mySdkCombo.addActionListener(listener);
+ }
+
+ public boolean checkValid() {
+ final String projectName = myLocationField.getText();
+ setErrorText(null);
+ myInstallFramework = false;
+
+ if (projectName.trim().isEmpty()) {
+ setErrorText("Project name can't be empty");
+ return false;
+ }
+ if (myLocationField.getText().indexOf('$') >= 0) {
+ setErrorText("Project directory name must not contain the $ character");
+ return false;
+ }
+ if (myProjectGenerator != null) {
+ final String baseDirPath = myLocationField.getTextField().getText();
+ ValidationResult validationResult = myProjectGenerator.validate(baseDirPath);
+ if (!validationResult.isOk()) {
+ setErrorText(validationResult.getErrorMessage());
+ return false;
+ }
+ if (myProjectGenerator instanceof PythonProjectGenerator) {
+ final ValidationResult warningResult = ((PythonProjectGenerator)myProjectGenerator).warningValidation(getSdk());
+ if (!warningResult.isOk()) {
+ setWarningText(warningResult.getErrorMessage());
+ }
+ }
+ if (myProjectGenerator instanceof WebProjectTemplate) {
+ final WebProjectGenerator.GeneratorPeer peer = ((WebProjectTemplate)myProjectGenerator).getPeer();
+ final ValidationInfo validationInfo = peer.validate();
+ if (validationInfo != null && !peer.isBackgroundJobRunning()) {
+ setErrorText(validationInfo.message);
+ return false;
+ }
+ }
+ }
+
+ final Sdk sdk = getSdk();
+
+ final boolean isPy3k = sdk != null && PythonSdkType.getLanguageLevelForSdk(sdk).isPy3K();
+ if (sdk != null && PythonSdkType.isRemote(sdk) && !acceptsRemoteSdk(myProjectGenerator)) {
+ setErrorText("Please choose a local interpreter");
+ return false;
+ }
+ else if (myProjectGenerator instanceof PyFrameworkProjectGenerator) {
+ PyFrameworkProjectGenerator frameworkProjectGenerator = (PyFrameworkProjectGenerator)myProjectGenerator;
+ String frameworkName = frameworkProjectGenerator.getFrameworkTitle();
+ if (sdk != null && !isFrameworkInstalled(sdk)) {
+ final PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(sdk);
+ final boolean onlyWithCache =
+ PythonSdkFlavor.getFlavor(sdk) instanceof JythonSdkFlavor || PythonSdkFlavor.getFlavor(sdk) instanceof PyPySdkFlavor;
+ String warningText = frameworkName + " will be installed on selected interpreter";
+ try {
+ if (onlyWithCache && packageManager.cacheIsNotNull() || !onlyWithCache) {
+ final PyPackage pip = packageManager.findInstalledPackage("pip");
+ myInstallFramework = true;
+ if (pip == null) {
+ warningText = "pip and " + warningText;
+ }
+ setWarningText(warningText);
+ }
+ }
+ catch (PyExternalProcessException ignored) {
+ myInstallFramework = true;
+ warningText = "pip and " + warningText;
+ setWarningText(warningText);
+ }
+ if (!myInstallFramework) {
+ setErrorText("No " + frameworkName + " support installed in selected interpreter");
+ return false;
+ }
+ }
+ if (isPy3k && !((PyFrameworkProjectGenerator)myProjectGenerator).supportsPython3()) {
+ setErrorText(frameworkName + " is not supported for the selected interpreter");
+ return false;
+ }
+ }
+ if (sdk == null) {
+ setErrorText("No Python interpreter selected");
+ return false;
+ }
+ return true;
+ }
+
+ public void setErrorText(@Nullable String text) {
+ myErrorLabel.setText(text);
+ myErrorLabel.setForeground(MessageType.ERROR.getTitleForeground());
+ myErrorLabel.setIcon(text == null ? null : AllIcons.Actions.Lightning);
+ myCreateButton.setEnabled(text == null);
+ }
+
+ public void setWarningText(@Nullable String text) {
+ myErrorLabel.setText("Note: " + text + " ");
+ myErrorLabel.setForeground(MessageType.WARNING.getTitleForeground());
+ }
+
+ public void selectCompatiblePython() {
+ DirectoryProjectGenerator generator = getProjectGenerator();
+ if (generator instanceof PyFrameworkProjectGenerator && !((PyFrameworkProjectGenerator)generator).supportsPython3()) {
+ Sdk sdk = getSdk();
+ if (sdk != null && PythonSdkType.getLanguageLevelForSdk(sdk).isPy3K()) {
+ Sdk python2Sdk = PythonSdkType.findPython2Sdk(null);
+ if (python2Sdk != null) {
+ mySdkCombo.getComboBox().setSelectedItem(python2Sdk);
+ mySdkCombo.getComboBox().repaint();
+ }
+ }
+ }
+ }
+
+ private static boolean acceptsRemoteSdk(DirectoryProjectGenerator generator) {
+ if (generator instanceof PyFrameworkProjectGenerator) {
+ return ((PyFrameworkProjectGenerator)generator).acceptsRemoteSdk();
+ }
+ return true;
+ }
+
+ private boolean isFrameworkInstalled(Sdk sdk) {
+ PyFrameworkProjectGenerator projectGenerator = (PyFrameworkProjectGenerator)getProjectGenerator();
+ return projectGenerator != null && projectGenerator.isFrameworkInstalled(sdk);
+ }
+
+ @Nullable
+ protected JPanel createAdvancedSettings() {
+ return null;
+ }
+
+ public DirectoryProjectGenerator getProjectGenerator() {
+ return myProjectGenerator;
+ }
+
+ private static class Button extends ActionButtonWithText {
+ private final Border myBorder;
+
+ public Button(AnAction action, Presentation presentation) {
+ super(action, presentation, "NewProject", new Dimension(70, 50));
+ myBorder = UIUtil.isUnderDarcula() ? UIUtil.getButtonBorder() : BorderFactory.createLineBorder(UIUtil.getBorderColor());
+ setBorder(myBorder);
+ }
+
+ @Override
+ protected int iconTextSpace() {
+ return 8;
+ }
+
+ @Override
+ public Insets getInsets() {
+ return new Insets(5,10,5,5);
+ }
+
+ @Override
+ protected int horizontalTextAlignment() {
+ return SwingConstants.LEFT;
+ }
+
+ @Override
+ public String getToolTipText() {
+ return null;
+ }
+
+ protected void processMouseEvent(MouseEvent e) {
+ super.processMouseEvent(e);
+ if (e.getID() == MouseEvent.MOUSE_ENTERED) {
+ setBorder(null);
+ }
+ else if (e.getID() == MouseEvent.MOUSE_EXITED) {
+ setBorder(myBorder);
+ }
+ }
+ }
+
+ public Sdk getSdk() {
+ return (Sdk)mySdkCombo.getComboBox().getSelectedItem();
+ }
+
+ public String getProjectLocation() {
+ return myLocationField.getText();
+ }
+
+ public boolean installFramework() {
+ return myInstallFramework;
+ }
+
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java
new file mode 100644
index 000000000000..a0c5f6e52fbf
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/PluginSpecificProjectsStep.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject.actions;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.util.NullableConsumer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class PluginSpecificProjectsStep extends DefaultActionGroup implements DumbAware {
+
+ public PluginSpecificProjectsStep(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
+ @NotNull final List<DirectoryProjectGenerator> projectGenerators) {
+ super("Plugin-specific", true);
+ getTemplatePresentation().setIcon(AllIcons.Nodes.PluginLogo);
+ for (DirectoryProjectGenerator generator : projectGenerators) {
+ add(new ProjectSpecificAction(callback, generator));
+ }
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
new file mode 100644
index 000000000000..950e11e0beca
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificAction.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.util.NullableConsumer;
+import org.jetbrains.annotations.NotNull;
+
+public class ProjectSpecificAction extends DefaultActionGroup implements DumbAware {
+
+ private final ProjectSpecificSettingsStep mySettings;
+
+ public ProjectSpecificAction(@NotNull final NullableConsumer<AbstractProjectSettingsStep> callback,
+ @NotNull final DirectoryProjectGenerator projectGenerator) {
+ super(projectGenerator.getName(), true);
+ getTemplatePresentation().setIcon(projectGenerator.getLogo());
+ mySettings = new ProjectSpecificSettingsStep(projectGenerator, callback);
+ add(mySettings);
+ }
+
+ public Sdk getSdk() {
+ return mySettings.getSdk();
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ super.actionPerformed(e);
+ mySettings.selectCompatiblePython();
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java
new file mode 100644
index 000000000000..ebd0658b072c
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject.actions;
+
+import com.intellij.ide.util.projectWizard.WebProjectTemplate;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.ui.HideableDecorator;
+import com.intellij.util.NullableConsumer;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class ProjectSpecificSettingsStep extends AbstractProjectSettingsStep implements DumbAware {
+
+ public ProjectSpecificSettingsStep(@NotNull final DirectoryProjectGenerator projectGenerator,
+ @NotNull final NullableConsumer<AbstractProjectSettingsStep> callback) {
+ super(projectGenerator, callback);
+ }
+
+ @Override
+ @Nullable
+ protected JPanel createAdvancedSettings() {
+ JComponent advancedSettings = null;
+ if (myProjectGenerator instanceof PythonProjectGenerator)
+ advancedSettings = ((PythonProjectGenerator)myProjectGenerator).getSettingsPanel(myProjectDirectory);
+ else if (myProjectGenerator instanceof WebProjectTemplate) {
+ advancedSettings = ((WebProjectTemplate)myProjectGenerator).getPeer().getComponent();
+ }
+ if (advancedSettings != null) {
+ final JPanel jPanel = new JPanel(new VerticalFlowLayout());
+ final HideableDecorator deco = new HideableDecorator(jPanel, "Mor&e Settings", false);
+ deco.setContentComponent(advancedSettings);
+ return jPanel;
+ }
+ return null;
+ }
+}
diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java
new file mode 100644
index 000000000000..b6134ed5f070
--- /dev/null
+++ b/python/ide/src/com/jetbrains/python/newProject/actions/PyCharmNewProjectStep.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.newProject.actions;
+
+import com.google.common.collect.Lists;
+import com.intellij.ide.GeneralSettings;
+import com.intellij.ide.util.projectWizard.WebProjectTemplate;
+import com.intellij.internal.statistic.UsageTrigger;
+import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkAdditionalData;
+import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
+import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.DirectoryProjectGenerator;
+import com.intellij.platform.PlatformProjectOpenProcessor;
+import com.intellij.projectImport.ProjectOpenedCallback;
+import com.intellij.util.NullableConsumer;
+import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
+import com.jetbrains.python.newProject.PyFrameworkProjectGenerator;
+import com.jetbrains.python.newProject.PyNewProjectSettings;
+import com.jetbrains.python.newProject.PythonBaseProjectGenerator;
+import com.jetbrains.python.newProject.PythonProjectGenerator;
+import com.jetbrains.python.sdk.PyDetectedSdk;
+import com.jetbrains.python.sdk.PySdkService;
+import com.jetbrains.python.sdk.PythonSdkAdditionalData;
+import com.jetbrains.python.sdk.PythonSdkType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+public class PyCharmNewProjectStep extends DefaultActionGroup implements DumbAware {
+ private static final Logger LOG = Logger.getInstance(PyCharmNewProjectStep.class);
+
+ public PyCharmNewProjectStep(@Nullable final Runnable runnable) {
+ super("Select Project Type", true);
+
+ final NullableConsumer<AbstractProjectSettingsStep> callback = new NullableConsumer<AbstractProjectSettingsStep>() {
+ @Override
+ public void consume(@Nullable AbstractProjectSettingsStep settingsStep) {
+ if (runnable != null)
+ runnable.run();
+ if (settingsStep == null) return;
+
+ Sdk sdk = settingsStep.getSdk();
+ final Project project = ProjectManager.getInstance().getDefaultProject();
+ final ProjectSdksModel model = PyConfigurableInterpreterList.getInstance(project).getModel();
+ if (sdk instanceof PyDetectedSdk) {
+ final String name = sdk.getName();
+ VirtualFile sdkHome = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ @Override
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByPath(name);
+ }
+ });
+ PySdkService.getInstance().solidifySdk(sdk);
+ sdk = SdkConfigurationUtil.setupSdk(ProjectJdkTable.getInstance().getAllJdks(), sdkHome, PythonSdkType.getInstance(), true, null,
+ null);
+ model.addSdk(sdk);
+ try {
+ model.apply();
+ }
+ catch (ConfigurationException exception) {
+ LOG.error("Error adding detected python interpreter " + exception.getMessage());
+ }
+ }
+ Project newProject = generateProject(project, settingsStep);
+ if (newProject != null) {
+ SdkConfigurationUtil.setDirectoryProjectSdk(newProject, sdk);
+ final List<Sdk> sdks = PythonSdkType.getAllSdks();
+ for (Sdk s : sdks) {
+ final SdkAdditionalData additionalData = s.getSdkAdditionalData();
+ if (additionalData instanceof PythonSdkAdditionalData) {
+ ((PythonSdkAdditionalData)additionalData).reassociateWithCreatedProject(newProject);
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private Project generateProject(@NotNull final Project project, @NotNull final AbstractProjectSettingsStep settings) {
+ final DirectoryProjectGenerator generator = settings.getProjectGenerator();
+ final File location = new File(settings.getProjectLocation());
+ if (!location.exists() && !location.mkdirs()) {
+ Messages.showErrorDialog(project, "Cannot create directory '" + location + "'", "Create Project");
+ return null;
+ }
+
+ final VirtualFile baseDir = ApplicationManager.getApplication().runWriteAction(new Computable<VirtualFile>() {
+ public VirtualFile compute() {
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(location);
+ }
+ });
+ LOG.assertTrue(baseDir != null, "Couldn't find '" + location + "' in VFS");
+ baseDir.refresh(false, true);
+
+ if (baseDir.getChildren().length > 0) {
+ int rc = Messages.showYesNoDialog(project,
+ "The directory '" + location +
+ "' is not empty. Would you like to create a project from existing sources instead?",
+ "Create New Project", Messages.getQuestionIcon());
+ if (rc == Messages.YES) {
+ return PlatformProjectOpenProcessor.getInstance().doOpenProject(baseDir, null, false);
+ }
+ }
+
+ String generatorName = generator == null ? "empty" : ConvertUsagesUtil.ensureProperKey(generator.getName());
+ UsageTrigger.trigger("NewDirectoryProjectAction." + generatorName);
+
+ GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
+
+ return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
+ @Override
+ public void projectOpened(Project project, Module module) {
+ if (generator != null) {
+ Object projectSettings = null;
+ if (generator instanceof PythonProjectGenerator)
+ projectSettings = ((PythonProjectGenerator)generator).getProjectSettings();
+ else if (generator instanceof WebProjectTemplate) {
+ projectSettings = ((WebProjectTemplate)generator).getPeer().getSettings();
+ }
+ if (projectSettings instanceof PyNewProjectSettings) {
+ ((PyNewProjectSettings)projectSettings).setSdk(settings.getSdk());
+ ((PyNewProjectSettings)projectSettings).setInstallFramework(settings.installFramework());
+ }
+ //noinspection unchecked
+ generator.generateProject(project, baseDir, projectSettings, module);
+ }
+ }
+ }, false);
+ }
+ };
+
+ final ProjectSpecificAction action = new ProjectSpecificAction(callback, new PythonBaseProjectGenerator());
+ add(action);
+
+ final DirectoryProjectGenerator[] generators = Extensions.getExtensions(DirectoryProjectGenerator.EP_NAME);
+ Arrays.sort(generators, new Comparator<DirectoryProjectGenerator>() {
+ @Override
+ public int compare(DirectoryProjectGenerator o1, DirectoryProjectGenerator o2) {
+ if (o1 instanceof PyFrameworkProjectGenerator && !(o2 instanceof PyFrameworkProjectGenerator)) return -1;
+ if (!(o1 instanceof PyFrameworkProjectGenerator) && o2 instanceof PyFrameworkProjectGenerator) return 1;
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+
+ List<DirectoryProjectGenerator> pluginSpecificGenerators = Lists.newArrayList();
+ for (DirectoryProjectGenerator generator : generators) {
+ if (generator instanceof PythonProjectGenerator)
+ add(new ProjectSpecificAction(callback, generator));
+ else
+ pluginSpecificGenerators.add(generator);
+ }
+
+ if (!pluginSpecificGenerators.isEmpty()) {
+ add(new PluginSpecificProjectsStep(callback, pluginSpecificGenerators));
+ }
+ }
+
+ public PyCharmNewProjectStep() {
+ this(null);
+
+ }
+
+}
diff --git a/python/openapi/src/com/jetbrains/python/newProject/PyFrameworkProjectGenerator.java b/python/openapi/src/com/jetbrains/python/newProject/PyFrameworkProjectGenerator.java
index f9dc7a6b204d..08e3402386e9 100644
--- a/python/openapi/src/com/jetbrains/python/newProject/PyFrameworkProjectGenerator.java
+++ b/python/openapi/src/com/jetbrains/python/newProject/PyFrameworkProjectGenerator.java
@@ -15,7 +15,6 @@
*/
package com.jetbrains.python.newProject;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.platform.DirectoryProjectGenerator;
@@ -25,7 +24,7 @@ import com.intellij.platform.DirectoryProjectGenerator;
public interface PyFrameworkProjectGenerator<T> extends DirectoryProjectGenerator<T> {
String getFrameworkTitle();
- boolean isFrameworkInstalled(Project project, Sdk sdk);
+ boolean isFrameworkInstalled(Sdk sdk);
boolean acceptsRemoteSdk();
diff --git a/python/openapi/src/com/jetbrains/python/newProject/PythonProjectGenerator.java b/python/openapi/src/com/jetbrains/python/newProject/PythonProjectGenerator.java
new file mode 100644
index 000000000000..5577959178ce
--- /dev/null
+++ b/python/openapi/src/com/jetbrains/python/newProject/PythonProjectGenerator.java
@@ -0,0 +1,43 @@
+package com.jetbrains.python.newProject;
+
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.io.File;
+import java.util.List;
+
+public abstract class PythonProjectGenerator {
+ private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
+
+ @Nullable
+ public JComponent getSettingsPanel(File baseDir) throws ProcessCanceledException {
+ return null;
+ }
+
+ public Object getProjectSettings() {
+ return new PyNewProjectSettings();
+ }
+
+ public ValidationResult warningValidation(@Nullable final Sdk sdk) {
+ return ValidationResult.OK;
+ }
+
+ public void addSettingsStateListener(@NotNull SettingsListener listener) {
+ myListeners.add(listener);
+ }
+
+ public interface SettingsListener {
+ void stateChanged();
+ }
+
+ public void fireStateChanged() {
+ for (SettingsListener listener : myListeners) {
+ listener.stateChanged();
+ }
+ }
+}
diff --git a/python/openapi/src/com/jetbrains/python/packaging/PyPackageManager.java b/python/openapi/src/com/jetbrains/python/packaging/PyPackageManager.java
index 588efa662e74..3b2080b00ba1 100644
--- a/python/openapi/src/com/jetbrains/python/packaging/PyPackageManager.java
+++ b/python/openapi/src/com/jetbrains/python/packaging/PyPackageManager.java
@@ -17,6 +17,8 @@ package com.jetbrains.python.packaging;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -39,4 +41,9 @@ public abstract class PyPackageManager {
public abstract void showInstallationError(Project project, String title, String description);
public abstract void showInstallationError(Component owner, String title, String description);
public abstract void refresh();
+ @Nullable
+ public abstract PyPackage findInstalledPackage(String name) throws PyExternalProcessException;
+
+ public abstract boolean findPackage(@NotNull final String name);
+
}
diff --git a/python/openapi/src/com/jetbrains/python/packaging/PyPackageManagers.java b/python/openapi/src/com/jetbrains/python/packaging/PyPackageManagers.java
index 796bc47286ac..9f598748aa7b 100644
--- a/python/openapi/src/com/jetbrains/python/packaging/PyPackageManagers.java
+++ b/python/openapi/src/com/jetbrains/python/packaging/PyPackageManagers.java
@@ -18,6 +18,7 @@ package com.jetbrains.python.packaging;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -26,10 +27,13 @@ import java.util.List;
* @author yole
*/
public abstract class PyPackageManagers {
+
+ @NotNull
public static PyPackageManagers getInstance() {
return ServiceManager.getService(PyPackageManagers.class);
}
+ @NotNull
public abstract PyPackageManager forSdk(Sdk sdk);
/**
diff --git a/python/openapi/src/com/jetbrains/python/templateLanguages/PyTemplatesUtil.java b/python/openapi/src/com/jetbrains/python/templateLanguages/PyTemplatesUtil.java
new file mode 100644
index 000000000000..e660029fe384
--- /dev/null
+++ b/python/openapi/src/com/jetbrains/python/templateLanguages/PyTemplatesUtil.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.templateLanguages;
+
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.jetbrains.python.packaging.PyExternalProcessException;
+import com.jetbrains.python.packaging.PyPackage;
+import com.jetbrains.python.packaging.PyPackageManager;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class PyTemplatesUtil {
+ private PyTemplatesUtil(){}
+
+ public static ValidationResult checkInstalled(@Nullable final Sdk sdk, @NotNull final TemplateLanguagePanel templatesPanel,
+ @NotNull final String prefix) {
+ if (sdk == null) return ValidationResult.OK;
+ String templateBinding = null;
+ @NonNls String language = templatesPanel.getTemplateLanguage();
+ if (language != null) {
+ if (language.equals(TemplatesService.JINJA2)) language = "jinja";
+ templateBinding = prefix + language.toLowerCase();
+ }
+ final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
+ if (templateBinding != null) {
+ if (TemplatesService.ALL_TEMPLATE_BINDINGS.contains(templateBinding)) {
+ try {
+ final PyPackage installedPackage = packageManager.findInstalledPackage(templateBinding);
+ if (installedPackage == null)
+ return new ValidationResult(templateBinding + " will be installed on selected interpreter");
+ }
+ catch (PyExternalProcessException ignored) {
+ }
+ }
+ }
+ if (language != null) {
+ try {
+ final PyPackage installedPackage = packageManager.findInstalledPackage(language);
+ if (installedPackage == null) {
+ return new ValidationResult(language + " will be installed on selected interpreter");
+ }
+ }
+ catch (PyExternalProcessException ignored) {
+ }
+ }
+ return null;
+ }
+
+}
+
diff --git a/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.form b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.form
new file mode 100644
index 000000000000..1ac79c6a0915
--- /dev/null
+++ b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.form
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.python.templateLanguages.TemplateLanguagePanel">
+ <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="617" height="171"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <vspacer id="73c47">
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <component id="37bbe" class="javax.swing.JComboBox" binding="myTemplateLanguage" default-binding="true">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ <component id="e231b" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Template language:"/>
+ </properties>
+ </component>
+ <component id="d243b" class="javax.swing.JLabel" binding="myTemplatesFolderLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Templates folder:"/>
+ </properties>
+ </component>
+ <component id="37ce3" class="javax.swing.JTextField" binding="myTemplatesFolder">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.java b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.java
new file mode 100644
index 000000000000..d2c453e785d2
--- /dev/null
+++ b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateLanguagePanel.java
@@ -0,0 +1,73 @@
+package com.jetbrains.python.templateLanguages;
+
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.ui.components.JBLabel;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+public class TemplateLanguagePanel extends JPanel {
+ private JTextField myTemplatesFolder;
+ private JPanel myMainPanel;
+ private JLabel myTemplatesFolderLabel;
+ private JComboBox myTemplateLanguage;
+
+ private static final String DEFAULT_TEMPLATES_FOLDER = "templates";
+
+ public TemplateLanguagePanel() {
+ super(new BorderLayout());
+ add(myMainPanel, BorderLayout.CENTER);
+ myTemplatesFolderLabel.setLabelFor(myTemplatesFolder);
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+ descriptor.withTreeRootVisible(true);
+ descriptor.setShowFileSystemRoots(true);
+ List<String> templateConfigurations = TemplatesService.getAllTemplateLanguages();
+ for (String configuration : templateConfigurations) {
+ if (!configuration.equals(TemplatesService.WEB2PY))
+ myTemplateLanguage.addItem(configuration);
+ }
+ myTemplatesFolder.setText(DEFAULT_TEMPLATES_FOLDER);
+ }
+
+ public String getTemplatesFolder() {
+ return myTemplatesFolder.getText();
+ }
+
+ public String getTemplateLanguage() {
+ final Object selectedItem = myTemplateLanguage.getSelectedItem();
+ return selectedItem != null ? (String)selectedItem : null;
+ }
+
+ public void setTemplateLanguage(String language) {
+ myTemplateLanguage.setSelectedItem(language);
+ }
+
+ public void saveSettings(TemplateSettingsHolder holder) {
+ holder.setTemplatesFolder(getTemplatesFolder());
+ final Object templateLanguage = getTemplateLanguage();
+ holder.setTemplateLanguage((String)templateLanguage);
+ }
+
+ public void setTemplatesFolder(@NotNull final String folder) {
+ myTemplatesFolder.setText(folder);
+ }
+
+ public Dimension getLabelSize() {
+ return new JBLabel("Template language:").getPreferredSize();
+ }
+
+ public void registerValidators(final FacetValidatorsManager validatorsManager) {
+ myTemplateLanguage.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ validatorsManager.validate();
+ }
+ });
+ }
+}
diff --git a/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateSettingsHolder.java b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateSettingsHolder.java
new file mode 100644
index 000000000000..e6ab03b98aa3
--- /dev/null
+++ b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplateSettingsHolder.java
@@ -0,0 +1,26 @@
+package com.jetbrains.python.templateLanguages;
+
+import com.jetbrains.python.newProject.PyNewProjectSettings;
+import org.jetbrains.annotations.Nullable;
+
+public class TemplateSettingsHolder extends PyNewProjectSettings {
+ private String myTemplatesFolder;
+ private String myTemplateLanguage;
+
+ public String getTemplatesFolder() {
+ return myTemplatesFolder;
+ }
+
+ public void setTemplatesFolder(String templatesFolder) {
+ myTemplatesFolder = templatesFolder;
+ }
+
+ @Nullable
+ public String getTemplateLanguage() {
+ return myTemplateLanguage;
+ }
+
+ public void setTemplateLanguage(@Nullable String templateLanguage) {
+ myTemplateLanguage = templateLanguage;
+ }
+}
diff --git a/python/openapi/src/com/jetbrains/python/templateLanguages/TemplatesService.java b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplatesService.java
index eff10e19bf6a..73603e4b573a 100644
--- a/python/openapi/src/com/jetbrains/python/templateLanguages/TemplatesService.java
+++ b/python/openapi/src/com/jetbrains/python/templateLanguages/TemplatesService.java
@@ -18,8 +18,10 @@ package com.jetbrains.python.templateLanguages;
import com.intellij.lang.Language;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleServiceManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
+import com.jetbrains.python.packaging.PyPackageManager;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -42,6 +44,9 @@ public abstract class TemplatesService {
WEB2PY,
CHAMELEON);
+ public static List<String> ALL_TEMPLATE_BINDINGS = ContainerUtil.immutableList("django-mako", "django-jinja", "django-chameleon",
+ "flask-mako", "pyramid_jinja2");
+
public abstract Language getSelectedTemplateLanguage();
public static TemplatesService getInstance(Module module) {
@@ -65,5 +70,9 @@ public abstract class TemplatesService {
public abstract List<String> getTemplateFileTypes();
public abstract void setTemplateFileTypes(List<String> fileTypes);
+
+ public abstract void generateTemplates(@NotNull final TemplateSettingsHolder settings, VirtualFile baseDir);
+ public abstract void installTemplateEngine(@NotNull final TemplateSettingsHolder settings, @NotNull final PyPackageManager packageManager,
+ @NotNull final Project project, @NotNull final String prefix);
}
diff --git a/python/pluginResources/META-INF/plugin.xml b/python/pluginResources/META-INF/plugin.xml
index 6ec30aa5fdff..31f714c875a8 100644
--- a/python/pluginResources/META-INF/plugin.xml
+++ b/python/pluginResources/META-INF/plugin.xml
@@ -4,13 +4,22 @@
<id>PythonCore</id>
<name>Python Community Edition</name>
- <idea-version since-build="135.406" until-build="138.*"/>
- <description>Smart editing for Python scripts</description>
- <version>3.4.Beta.135.@@BUILD_NUMBER@@</version>
+ <idea-version since-build="138.0" until-build="138.*"/>
+
+ <description><![CDATA[
+The Python plug-in provides smart editing for Python scripts. The feature set of the plugin
+ corresponds to PyCharm IDE Community Edition.
+<br>
+<a href="http://blog.jetbrains.com/pycharm">PyCharm blog</a><br>
+<a href="http://forum.jetbrains.com/forum/PyCharm">Discussion forum</a><br>
+<a href="http://youtrack.jetbrains.com/issues/PY">Issue tracker</a><br>
+]]></description>
+
+ <version>4.0.@@BUILD_NUMBER@@</version>
<depends>com.intellij.modules.java</depends>
- <vendor url="http://www.jetbrains.com/pycharm/" logo="/com/jetbrains/python/python.png">JetBrains, Keith Lea</vendor>
+ <vendor url="http://www.jetbrains.com/pycharm/" logo="/com/jetbrains/python/python.png">JetBrains</vendor>
<xi:include href="/META-INF/python-core.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="/META-INF/python-plugin-core.xml" xpointer="xpointer(/idea-plugin/*)"/>
</idea-plugin>
diff --git a/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java b/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java
index 4a663c38b65e..4a9df08f6eb7 100644
--- a/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java
+++ b/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java
@@ -48,7 +48,7 @@ public class PyManagePackagesDialog extends DialogWrapper {
List<Sdk> sdks = PythonSdkType.getAllSdks();
Collections.sort(sdks, new PreferredSdkComparator());
final JComboBox sdkComboBox = new JComboBox(new CollectionComboBoxModel(sdks, sdk));
- sdkComboBox.setRenderer(new PySdkListCellRenderer());
+ sdkComboBox.setRenderer(new PySdkListCellRenderer(false));
PackagesNotificationPanel notificationPanel = new PackagesNotificationPanel(project);
final PyInstalledPackagesPanel packagesPanel = new PyInstalledPackagesPanel(project, notificationPanel);
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
index a667bb69f849..e9014b3759c2 100644
--- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java
@@ -18,8 +18,8 @@ package com.jetbrains.python.psi.impl;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.psi.AccessDirection;
+import com.jetbrains.python.psi.PyCallSiteExpression;
import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
@@ -113,7 +113,7 @@ public class PyJavaClassType implements PyClassLikeType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return getReturnType(context);
}
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
index 6f0fd48e8742..cb5d94e516bb 100644
--- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java
@@ -21,8 +21,8 @@ import com.intellij.psi.PsiMethod;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.psi.AccessDirection;
+import com.jetbrains.python.psi.PyCallSiteExpression;
import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.types.PyCallableParameter;
@@ -58,7 +58,7 @@ public class PyJavaMethodType implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return getReturnType(context);
}
diff --git a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form
index edec809c4952..0332fda9195b 100644
--- a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form
+++ b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form
@@ -75,7 +75,7 @@
<text value="Use SDK of module:"/>
</properties>
</component>
- <component id="5f300" class="javax.swing.JComboBox" binding="myModuleComboBox">
+ <component id="5f300" class="com.intellij.application.options.ModulesComboBox" binding="myModuleComboBox">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java
index 4a1957e9e631..cf0e440353a4 100644
--- a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java
+++ b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java
@@ -15,7 +15,6 @@
*/
package com.jetbrains.python.run;
-import com.intellij.application.options.ModuleListCellRenderer;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.util.PathMappingsComponent;
import com.intellij.ide.util.PropertiesComponent;
@@ -27,6 +26,7 @@ import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.application.options.ModulesComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.ui.CollectionComboBoxModel;
@@ -58,7 +58,7 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm {
private RawCommandLineEditor myInterpreterOptionsTextField;
private JComboBox myInterpreterComboBox;
private JRadioButton myUseModuleSdkRadioButton;
- private JComboBox myModuleComboBox;
+ private ModulesComboBox myModuleComboBox;
private JPanel myMainPanel;
private JRadioButton myUseSpecifiedSdkRadioButton;
private JBLabel myPythonInterpreterJBLabel;
@@ -77,8 +77,8 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm {
final List<Module> validModules = data.getValidModules();
Collections.sort(validModules, new ModulesAlphaComparator());
Module selection = validModules.size() > 0 ? validModules.get(0) : null;
- myModuleComboBox.setModel(new CollectionComboBoxModel(validModules, selection));
- myModuleComboBox.setRenderer(new ModuleListCellRenderer());
+ myModuleComboBox.setModules(validModules);
+ myModuleComboBox.setSelectedModule(selection);
myInterpreterComboBox.setRenderer(new SdkListCellRenderer("<Project Default>"));
myWorkingDirectoryTextField.addBrowseFolderListener("Select Working Directory", "", data.getProject(),
@@ -181,11 +181,11 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm {
}
public Module getModule() {
- return (Module)myModuleComboBox.getSelectedItem();
+ return myModuleComboBox.getSelectedModule();
}
public void setModule(Module module) {
- myModuleComboBox.setSelectedItem(module);
+ myModuleComboBox.setSelectedModule(module);
}
public boolean isUseModuleSdk() {
diff --git a/python/psi-api/src/com/jetbrains/python/psi/Callable.java b/python/psi-api/src/com/jetbrains/python/psi/Callable.java
index a31197ec60c1..59e190ee4f4e 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/Callable.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/Callable.java
@@ -45,7 +45,7 @@ public interface Callable extends PyTypedElement, PyQualifiedNameOwner {
* Returns the type of the call to the callable.
*/
@Nullable
- PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite);
+ PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite);
/**
* Returns the type of the call to the callable where the call site is specified by the optional receiver and the arguments to parameters
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyBinaryExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyBinaryExpression.java
index 0461318736fc..9ca5a30b3d2f 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyBinaryExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyBinaryExpression.java
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
-public interface PyBinaryExpression extends PyQualifiedExpression, PyReferenceOwner {
+public interface PyBinaryExpression extends PyQualifiedExpression, PyCallSiteExpression, PyReferenceOwner {
PyExpression getLeftExpression();
@Nullable PyExpression getRightExpression();
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
index 581c4257c430..ae429f0d51af 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents an entire call expression, like <tt>foo()</tt> or <tt>foo.bar[1]('x')</tt>.
*/
-public interface PyCallExpression extends PyExpression {
+public interface PyCallExpression extends PyCallSiteExpression {
/**
* @return the expression representing the object being called (reference to a function).
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCallSiteExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyCallSiteExpression.java
new file mode 100644
index 000000000000..a2c49cb52500
--- /dev/null
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyCallSiteExpression.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.psi;
+
+/**
+ * Marker interface for Python expressions that are call sites for explicit or implicit function calls.
+ *
+ * @author vlan
+ */
+public interface PyCallSiteExpression extends PyExpression {
+}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyFile.java b/python/psi-api/src/com/jetbrains/python/psi/PyFile.java
index 1786b934159b..48d1b50b5800 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyFile.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyFile.java
@@ -27,6 +27,7 @@ public interface PyFile extends PyElement, PsiFile, PyDocStringOwner, ScopeOwner
List<PyClass> getTopLevelClasses();
+ @NotNull
List<PyFunction> getTopLevelFunctions();
List<PyTargetExpression> getTopLevelAttributes();
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyReferenceOwner.java b/python/psi-api/src/com/jetbrains/python/psi/PyReferenceOwner.java
index d9fab3f3a6c7..d03434794ff1 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyReferenceOwner.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyReferenceOwner.java
@@ -17,12 +17,12 @@ package com.jetbrains.python.psi;
import com.intellij.psi.PsiPolyVariantReference;
import com.jetbrains.python.psi.resolve.PyResolveContext;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public interface PyReferenceOwner extends PyElement {
- @Nullable
+ @NotNull
PsiPolyVariantReference getReference(PyResolveContext context);
}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PySubscriptionExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PySubscriptionExpression.java
index dc3f28d8ea38..cc1bba0616d2 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PySubscriptionExpression.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PySubscriptionExpression.java
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
-public interface PySubscriptionExpression extends PyQualifiedExpression, PyReferenceOwner {
+public interface PySubscriptionExpression extends PyQualifiedExpression, PyCallSiteExpression, PyReferenceOwner {
/**
* @return For <code>spam[x][y][n]</code> will return <code>spam</code> regardless number of its dimensions
diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
index b3a1134a2e03..f4f3a74f5a9f 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
@@ -236,6 +236,7 @@ public class PyPsiUtils {
}
}
+ @NotNull
static <T, U extends PsiElement> List<T> collectStubChildren(U e,
final StubElement<U> stub, final IElementType elementType,
final Class<T> itemClass) {
diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
index 5707005026cb..be76db2af007 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
@@ -42,7 +42,7 @@ public interface PyTypeProvider {
PyType getReturnType(@NotNull Callable callable, @NotNull TypeEvalContext context);
@Nullable
- PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context);
+ PyType getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context);
@Nullable
PyType getContextManagerVariableType(PyClass contextManager, PyExpression withExpression, TypeEvalContext context);
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java
index 66fb827babe4..d2c36ba37343 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java
@@ -15,7 +15,7 @@
*/
package com.jetbrains.python.psi.types;
-import com.jetbrains.python.psi.PyQualifiedExpression;
+import com.jetbrains.python.psi.PyCallSiteExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,7 +46,7 @@ public interface PyCallableType extends PyType {
* Returns the type which is the result of calling an instance of this type.
*/
@Nullable
- PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite);
+ PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite);
/**
* Returns the list of parameter types.
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
index c27dc4bc04ed..0c60e6555b59 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
@@ -35,7 +35,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
protected interface ReturnTypeCallback {
@Nullable
- PyType getType(@Nullable PyQualifiedExpression callSite, @Nullable PyType qualifierType, TypeEvalContext context);
+ PyType getType(@Nullable PyCallSiteExpression callSite, @Nullable PyType qualifierType, TypeEvalContext context);
}
private static class ReturnTypeDescriptor {
@@ -46,12 +46,13 @@ public class PyTypeProviderBase implements PyTypeProvider {
}
@Nullable
- public PyType get(PyFunction function, @Nullable PyQualifiedExpression callSite, TypeEvalContext context) {
+ public PyType get(PyFunction function, @Nullable PyCallSiteExpression callSite, TypeEvalContext context) {
PyClass containingClass = function.getContainingClass();
if (containingClass != null) {
final ReturnTypeCallback typeCallback = myStringToReturnTypeMap.get(containingClass.getQualifiedName());
if (typeCallback != null) {
- final PyExpression qualifier = callSite != null ? callSite.getQualifier() : null;
+ final PyExpression callee = callSite instanceof PyCallExpression ? ((PyCallExpression)callSite).getCallee() : null;
+ final PyExpression qualifier = callee instanceof PyQualifiedExpression ? ((PyQualifiedExpression)callee).getQualifier() : null;
PyType qualifierType = qualifier != null ? context.getType(qualifier) : null;
return typeCallback.getType(callSite, qualifierType, context);
}
@@ -62,7 +63,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
private final ReturnTypeCallback mySelfTypeCallback = new ReturnTypeCallback() {
@Override
- public PyType getType(@Nullable PyQualifiedExpression callSite, @Nullable PyType qualifierType, TypeEvalContext context) {
+ public PyType getType(@Nullable PyCallSiteExpression callSite, @Nullable PyType qualifierType, TypeEvalContext context) {
if (qualifierType instanceof PyClassType) {
PyClass aClass = ((PyClassType)qualifierType).getPyClass();
return PyPsiFacade.getInstance(aClass.getProject()).createClassType(aClass, false);
@@ -101,7 +102,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
}
@Override
- public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
ReturnTypeDescriptor descriptor;
synchronized (myMethodToReturnTypeMap) {
descriptor = myMethodToReturnTypeMap.get(function.getName());
diff --git a/python/python-community.iml b/python/python-community.iml
index 831f4bd1cf61..e0aca64302e3 100644
--- a/python/python-community.iml
+++ b/python/python-community.iml
@@ -14,7 +14,7 @@
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="python-pydev" />
- <orderEntry type="library" name="XmlRPC" level="project" />
+ <orderEntry type="library" exported="" name="XmlRPC" level="project" />
<orderEntry type="module" module-name="xdebugger-api" />
<orderEntry type="library" name="http-client-3.1" level="project" />
<orderEntry type="module" module-name="RegExpSupport" exported="" />
diff --git a/python/python-rest/src/com/jetbrains/rest/RestFileProviderFactory.java b/python/python-rest/src/com/jetbrains/rest/RestFileProviderFactory.java
index 5c61251d9ba6..ae15df01e0a5 100644
--- a/python/python-rest/src/com/jetbrains/rest/RestFileProviderFactory.java
+++ b/python/python-rest/src/com/jetbrains/rest/RestFileProviderFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull;
*/
public class RestFileProviderFactory implements FileViewProviderFactory {
+ @NotNull
public FileViewProvider createFileViewProvider(@NotNull VirtualFile virtualFile, Language language, @NotNull PsiManager psiManager, boolean eventSystemEnabled) {
return new RestFileViewProvider(psiManager, virtualFile, eventSystemEnabled);
}
diff --git a/python/python-rest/src/com/jetbrains/rest/RestPythonUtil.java b/python/python-rest/src/com/jetbrains/rest/RestPythonUtil.java
index 52b8de6b4e63..f32fce8e40b7 100644
--- a/python/python-rest/src/com/jetbrains/rest/RestPythonUtil.java
+++ b/python/python-rest/src/com/jetbrains/rest/RestPythonUtil.java
@@ -50,7 +50,7 @@ public class RestPythonUtil {
if (sdk != null) {
PyPackageManagerImpl manager = (PyPackageManagerImpl)PyPackageManager.getInstance(sdk);
try {
- final PyPackage sphinx = manager.findPackage("Sphinx");
+ final PyPackage sphinx = manager.findInstalledPackage("Sphinx");
presentation.setEnabled(sphinx != null);
}
catch (PyExternalProcessException ignored) {
diff --git a/python/python-rest/src/com/jetbrains/rest/inspections/RestInspection.java b/python/python-rest/src/com/jetbrains/rest/inspections/RestInspection.java
index 0369198c3f3c..a22819d0cebd 100644
--- a/python/python-rest/src/com/jetbrains/rest/inspections/RestInspection.java
+++ b/python/python-rest/src/com/jetbrains/rest/inspections/RestInspection.java
@@ -15,9 +15,7 @@
*/
package com.jetbrains.rest.inspections;
-import com.intellij.codeInspection.CustomSuppressableInspectionTool;
-import com.intellij.codeInspection.LocalInspectionTool;
-import com.intellij.codeInspection.SuppressIntentionAction;
+import com.intellij.codeInspection.*;
import com.intellij.psi.PsiElement;
import com.jetbrains.rest.RestBundle;
import org.jetbrains.annotations.Nls;
@@ -27,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
/**
* User : catherine
*/
-public abstract class RestInspection extends LocalInspectionTool implements CustomSuppressableInspectionTool {
+public abstract class RestInspection extends LocalInspectionTool {
@Nls
@NotNull
@Override
@@ -46,9 +44,10 @@ public abstract class RestInspection extends LocalInspectionTool implements Cust
return true;
}
+ @NotNull
@Override
- public SuppressIntentionAction[] getSuppressActions(@Nullable PsiElement element) {
- return null;
+ public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
+ return SuppressQuickFix.EMPTY_ARRAY;
}
@Override
diff --git a/python/resources/icons/com/jetbrains/python/python-logo.png b/python/resources/icons/com/jetbrains/python/python-logo.png
new file mode 100644
index 000000000000..87fff4d6dbfb
--- /dev/null
+++ b/python/resources/icons/com/jetbrains/python/python-logo.png
Binary files differ
diff --git a/python/src/META-INF/pycharm-core.xml b/python/src/META-INF/pycharm-core.xml
index fdec83addc28..775d912b284a 100644
--- a/python/src/META-INF/pycharm-core.xml
+++ b/python/src/META-INF/pycharm-core.xml
@@ -79,7 +79,7 @@
<actions>
<group id="PlatformOpenProjectGroup">
- <action id="NewDirectoryProject" class="com.jetbrains.python.newProject.PythonNewDirectoryProjectAction"/>
+ <action id="NewDirectoryProject" class="com.jetbrains.python.newProject.PyCharmNewProjectAction"/>
<add-to-group group-id="FileOpenGroup" anchor="first"/>
</group>
@@ -95,7 +95,7 @@
icon="AllIcons.RunConfigurations.RerunFailedTests"/>
<group id="WelcomeScreen.Platform.NewProject">
- <action id="WelcomeScreen.CreateDirectoryProject" class="com.jetbrains.python.newProject.PythonNewDirectoryProjectAction" icon="AllIcons.General.CreateNewProject"/>
+ <action id="WelcomeScreen.CreateDirectoryProject" class="com.jetbrains.python.newProject.actions.PyCharmNewProjectStep" icon="AllIcons.General.CreateNewProject"/>
<action id="WelcomeScreen.OpenDirectoryProject" class="com.intellij.ide.actions.OpenFileAction" icon="AllIcons.General.OpenProject"/>
<add-to-group group-id="WelcomeScreen.QuickStart" anchor="first"/>
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index 411fa6cede4d..54491eb737d6 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -69,6 +69,8 @@
implementationClass="com.jetbrains.python.codeInsight.completion.PyParameterCompletionContributor"/>
<completion.contributor language="Python"
implementationClass="com.jetbrains.python.codeInsight.completion.PyDocstringCompletionContributor"/>
+ <completion.contributor language="Python"
+ implementationClass="com.jetbrains.python.codeInsight.completion.PyMetaClassCompletionContributor"/>
<lang.tokenSeparatorGenerator language="Python" implementationClass="com.jetbrains.python.PyTokenSeparatorGenerator"/>
<lang.elementManipulator forClass="com.jetbrains.python.psi.PyReferenceExpression"
implementationClass="com.jetbrains.python.psi.impl.PyReferenceExpressionManipulator"/>
@@ -91,6 +93,7 @@
<stubIndex implementation="com.jetbrains.python.psi.stubs.PySuperClassIndex"/>
<stubIndex implementation="com.jetbrains.python.psi.stubs.PyVariableNameIndex"/>
<stubIndex implementation="com.jetbrains.python.psi.stubs.PyInstanceAttributeIndex"/>
+ <stubIndex implementation="com.jetbrains.python.psi.stubs.PyDecoratorStubIndex"/>
<fileBasedIndex implementation="com.jetbrains.python.psi.stubs.PyModuleNameIndex"/>
<declarationRangeHandler key="com.jetbrains.python.psi.PyClass"
diff --git a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
index 27207ab31136..18786ed32ee5 100644
--- a/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
+++ b/python/src/com/jetbrains/numpy/codeInsight/NumpyDocStringTypeProvider.java
@@ -20,10 +20,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.jetbrains.numpy.documentation.NumPyDocString;
import com.jetbrains.numpy.documentation.NumPyDocStringParameter;
-import com.jetbrains.python.psi.PyFunction;
-import com.jetbrains.python.psi.PyNamedParameter;
-import com.jetbrains.python.psi.PyPsiFacade;
-import com.jetbrains.python.psi.PyQualifiedExpression;
+import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.PyTypeProviderBase;
import com.jetbrains.python.psi.types.TypeEvalContext;
@@ -67,9 +64,10 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
@Nullable
@Override
- public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
if (isInsideNumPy(function)) {
- final NumPyDocString docString = NumPyDocString.forFunction(function, callSite);
+ final PyExpression callee = callSite instanceof PyCallExpression ? ((PyCallExpression)callSite).getCallee() : null;
+ final NumPyDocString docString = NumPyDocString.forFunction(function, callee);
if (docString != null) {
final List<NumPyDocStringParameter> returns = docString.getReturns();
final PyPsiFacade facade = getPsiFacade(function);
diff --git a/python/src/com/jetbrains/python/PyBundle.java b/python/src/com/jetbrains/python/PyBundle.java
index 28b853e31e5c..c6f17d15ff91 100644
--- a/python/src/com/jetbrains/python/PyBundle.java
+++ b/python/src/com/jetbrains/python/PyBundle.java
@@ -27,6 +27,7 @@ import java.util.ResourceBundle;
// A copy of Ruby's.
/**
+ * TODO: Copy/paste with Django and PyBDD bundles
* Resource bundle access.
* Date: Nov 25, 2008 2:36:10 AM
*/
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index f87f2c23f007..5d29d3f79d50 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -774,8 +774,7 @@ runcfg.testing.no.test.framework=No {0} runner found in selected interpreter
# Consoles messages
python.console=Python Console
-django.console=Django Console
-django.console.and.manage.py=Django Console and manage.py options
+
# UI messages
MSG.title.bad.sdk=Invalid Python SDK
@@ -790,6 +789,7 @@ runcfg.unittest.dlg.test_function_title=Function
runcfg.unittest.dlg.keywords=Keywords:
run.configuration.remote.debug.name=Python Remote Debug
run.configuration.type.description=Starts server for remote debug
+run.configuration.show.command.line.action.name=Show Python Prompt
unable.to.stop=Currently running process can't be stopped. Kill it manually first.
diff --git a/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java b/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java
index 15b29c1c584a..dd9d3ef9dc00 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyMethodNameTypedHandler.java
@@ -82,7 +82,7 @@ public class PyMethodNameTypedHandler extends TypedHandlerDelegate {
if (caretOffset == chars.length() || chars.charAt(caretOffset) != ':') {
textToType += ':';
}
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, textToType, true, 1 + pname.length()); // right after param name
+ EditorModificationUtil.insertStringAtCaret(editor, textToType, true, 1 + pname.length()); // right after param name
return Result.STOP;
}
}
diff --git a/python/src/com/jetbrains/python/codeInsight/PyStdReferenceContributor.java b/python/src/com/jetbrains/python/codeInsight/PyStdReferenceContributor.java
index 3be84bfdc170..5b0221d0c6ff 100644
--- a/python/src/com/jetbrains/python/codeInsight/PyStdReferenceContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyStdReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
*/
public class PyStdReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registerClassAttributeReference(registrar, PyNames.ALL, new PsiReferenceProvider() {
@NotNull
@Override
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java
index 24318f85ad04..3b2e8283cee5 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java
@@ -41,6 +41,7 @@ import com.jetbrains.python.psi.stubs.PyClassNameIndex;
import com.jetbrains.python.psi.stubs.PyFunctionNameIndex;
import com.jetbrains.python.psi.stubs.PyVariableNameIndex;
import com.jetbrains.python.psi.types.PyModuleType;
+import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -50,7 +51,7 @@ import java.util.Collection;
public class PyClassNameCompletionContributor extends CompletionContributor {
@Override
- public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.isExtendedCompletion()) {
final PsiElement element = parameters.getPosition();
final PsiElement parent = element.getParent();
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java
new file mode 100644
index 000000000000..bac27082b23f
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyMetaClassCompletionContributor.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight.completion;
+
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.patterns.PlatformPatterns;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.filters.ElementFilter;
+import com.intellij.psi.filters.position.FilterPattern;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.Processor;
+import com.jetbrains.python.PythonLanguage;
+import com.jetbrains.python.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author vlan
+ */
+public class PyMetaClassCompletionContributor extends CompletionContributor {
+ public PyMetaClassCompletionContributor() {
+ extend(CompletionType.BASIC,
+ PlatformPatterns
+ .psiElement()
+ .withLanguage(PythonLanguage.getInstance())
+ .withParents(PyReferenceExpression.class, PyExpressionStatement.class, PyStatementList.class, PyClass.class)
+ .and(hasLanguageLevel(new Processor<LanguageLevel>() {
+ @Override
+ public boolean process(LanguageLevel level) {
+ return level.isOlderThan(LanguageLevel.PYTHON30);
+ }
+ })),
+ new CompletionProvider<CompletionParameters>() {
+ @Override
+ protected void addCompletions(@NotNull CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull CompletionResultSet result) {
+ result.addElement(LookupElementBuilder.create("__metaclass__ = "));
+ }
+ });
+ extend(CompletionType.BASIC,
+ PlatformPatterns
+ .psiElement()
+ .withLanguage(PythonLanguage.getInstance())
+ .withParents(PyReferenceExpression.class, PyArgumentList.class, PyClass.class)
+ .and(hasLanguageLevel(new Processor<LanguageLevel>() {
+ @Override
+ public boolean process(LanguageLevel level) {
+ return level.isAtLeast(LanguageLevel.PYTHON30);
+ }
+ })),
+ new CompletionProvider<CompletionParameters>() {
+ @Override
+ protected void addCompletions(@NotNull CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull CompletionResultSet result) {
+ result.addElement(LookupElementBuilder.create("metaclass="));
+ }
+ });
+ }
+
+ public static FilterPattern hasLanguageLevel(@NotNull final Processor<LanguageLevel> processor) {
+ return new FilterPattern(new ElementFilter() {
+ @Override
+ public boolean isAcceptable(Object element, @Nullable PsiElement context) {
+ if (element instanceof PsiElement) {
+ return processor.process(LanguageLevel.forElement((PsiElement)element));
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isClassAcceptable(Class hintClass) {
+ return true;
+ }
+ });
+ }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java
index db0e4537db38..bc3de2d28cfe 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java
@@ -40,7 +40,7 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
*/
public class PySpecialMethodNamesCompletionContributor extends CompletionContributor {
@Override
- public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
+ public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
// auto-insert the obvious only case; else show other cases.
final LookupElement[] items = context.getItems();
if (items.length == 1) {
diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java
index 168a3fe8121f..1cdba261017f 100644
--- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java
+++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java
@@ -84,7 +84,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
@Override
public PyType getType(TypeEvalContext context, PsiElement anchor) {
final List<PyType> types = new ArrayList<PyType>();
- types.add(PyTypeParser.getTypeByName(target, PyNames.CALLABLE));
+ types.add(PyTypeParser.getTypeByName(target, "collections." + PyNames.CALLABLE));
return createAssertionType(context.getType(target), types, positive, context);
}
});
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
index ad1d6a24bdc1..bcad2c1a105c 100644
--- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
+++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyNamedTupleType.java
@@ -95,7 +95,7 @@ public class PyNamedTupleType extends PyClassTypeImpl implements PyCallableType
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
if (myDefinitionLevel > 0) {
return new PyNamedTupleType(myClass, myDeclaration, myName, myFields, myDefinitionLevel-1);
}
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java
index 1a097263c24a..8a0b9ebe7050 100644
--- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibCanonicalPathProvider.java
@@ -73,6 +73,10 @@ public class PyStdlibCanonicalPathProvider implements PyCanonicalPathProvider {
components.set(0, "sqlite3");
return QualifiedName.fromComponents(components);
}
+ else if (head.equals("_pickle")) {
+ components.set(0, "pickle");
+ return QualifiedName.fromComponents(components);
+ }
}
return null;
}
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
index d7678c2cd871..346d40f3273e 100644
--- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
@@ -120,7 +120,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
@Nullable
@Override
- public PyType getCallType(@NotNull PyFunction function, @Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
+ public PyType getCallType(@NotNull PyFunction function, @Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
final String qname = getQualifiedName(function, callSite);
if (qname != null) {
if (OPEN_FUNCTIONS.contains(qname) && callSite != null) {
diff --git a/python/src/com/jetbrains/python/console/PyOpenDebugConsoleAction.java b/python/src/com/jetbrains/python/console/PyOpenDebugConsoleAction.java
index 45906d513f21..6b6edde16ae7 100644
--- a/python/src/com/jetbrains/python/console/PyOpenDebugConsoleAction.java
+++ b/python/src/com/jetbrains/python/console/PyOpenDebugConsoleAction.java
@@ -59,7 +59,7 @@ public class PyOpenDebugConsoleAction extends AnAction implements DumbAware {
selectRunningProcess(e.getDataContext(), project, new Consumer<PythonDebugLanguageConsoleView>() {
@Override
public void consume(PythonDebugLanguageConsoleView view) {
- view.showDebugConsole(true);
+ view.enableConsole(false);
IdeFocusManager.getInstance(project).requestFocus(view.getPydevConsoleView().getComponent(), true);
}
});
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
index 221337572811..ba2f137751a4 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -131,6 +131,7 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
public static Key<Sdk> CONSOLE_SDK = new Key<Sdk>("PYDEV_CONSOLE_SDK_KEY");
private static final long APPROPRIATE_TO_WAIT = 60000;
+ private PyRemoteSdkCredentials myRemoteCredentials;
protected PydevConsoleRunner(@NotNull final Project project,
@NotNull Sdk sdk, @NotNull final PyConsoleType consoleType,
@@ -352,16 +353,16 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
myCommandLine = commandLine.getCommandLineString();
try {
- PyRemoteSdkCredentials remoteCredentials = data.getRemoteSdkCredentials();
+ myRemoteCredentials = data.getRemoteSdkCredentials(true);
PathMappingSettings mappings = manager.setupMappings(getProject(), data, null);
RemoteSshProcess remoteProcess =
- manager.createRemoteProcess(getProject(), remoteCredentials, mappings, commandLine, true);
+ manager.createRemoteProcess(getProject(), myRemoteCredentials, mappings, commandLine, true);
Pair<Integer, Integer> remotePorts = getRemotePortsFromProcess(remoteProcess);
- remoteProcess.addLocalTunnel(myPorts[0], remoteCredentials.getHost(), remotePorts.first);
+ remoteProcess.addLocalTunnel(myPorts[0], myRemoteCredentials.getHost(), remotePorts.first);
remoteProcess.addRemoteTunnel(remotePorts.second, "localhost", myPorts[1]);
@@ -425,15 +426,10 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory<PythonC
if (manager != null) {
PyRemoteSdkAdditionalDataBase data = (PyRemoteSdkAdditionalDataBase)mySdk.getSdkAdditionalData();
assert data != null;
- try {
- myProcessHandler =
- manager.createConsoleProcessHandler(process, data.getRemoteSdkCredentials(), getConsoleView(), myPydevConsoleCommunication,
- myCommandLine, CharsetToolkit.UTF8_CHARSET,
- manager.setupMappings(getProject(), data, null));
- }
- catch (InterruptedException e) {
- LOG.error("Error getting remote credentials");
- }
+ myProcessHandler =
+ manager.createConsoleProcessHandler(process, myRemoteCredentials, getConsoleView(), myPydevConsoleCommunication,
+ myCommandLine, CharsetToolkit.UTF8_CHARSET,
+ manager.setupMappings(getProject(), data, null));
}
else {
LOG.error("Can't create remote console process handler");
diff --git a/python/src/com/jetbrains/python/console/PythonDebugLanguageConsoleView.java b/python/src/com/jetbrains/python/console/PythonDebugLanguageConsoleView.java
index 495c26df74c8..961f703e678d 100644
--- a/python/src/com/jetbrains/python/console/PythonDebugLanguageConsoleView.java
+++ b/python/src/com/jetbrains/python/console/PythonDebugLanguageConsoleView.java
@@ -15,64 +15,32 @@
*/
package com.jetbrains.python.console;
-import com.google.common.collect.Lists;
-import com.intellij.execution.ExecutionBundle;
-import com.intellij.execution.filters.Filter;
-import com.intellij.execution.filters.HyperlinkInfo;
+import com.intellij.execution.console.DuplexConsoleView;
+import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.impl.ConsoleViewImpl;
-import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ConsoleView;
-import com.intellij.execution.ui.ConsoleViewContentType;
-import com.intellij.execution.ui.ObservableConsoleView;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.actionSystem.ToggleAction;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ScrollType;
-import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.jetbrains.python.PyBundle;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import java.awt.*;
-import java.util.List;
-
/**
* @author traff
*/
-public class PythonDebugLanguageConsoleView extends JPanel implements ConsoleView, ObservableConsoleView, PyCodeExecutor {
-
- private final static String TEXT_CONSOLE_PANEL = "TEXT_CONSOLE_PANEL";
- private final static String PYDEV_CONSOLE_PANEL = "PYDEV_CONSOLE_PANEL";
-
- private final PythonConsoleView myPydevConsoleView;
-
- private final ConsoleView myTextConsole;
-
- public boolean myIsDebugConsole = false;
-
- private ProcessHandler myProcessHandler;
+public class PythonDebugLanguageConsoleView extends DuplexConsoleView<ConsoleView, PythonConsoleView> implements PyCodeExecutor {
public PythonDebugLanguageConsoleView(final Project project, Sdk sdk, ConsoleView consoleView) {
- super(new CardLayout());
- myPydevConsoleView = new PythonConsoleView(project, "Python Console", sdk);
- myTextConsole = consoleView;
+ super(consoleView, new PythonConsoleView(project, "Python Console", sdk));
- add(myTextConsole.getComponent(), TEXT_CONSOLE_PANEL);
- add(myPydevConsoleView.getComponent(), PYDEV_CONSOLE_PANEL);
+ enableConsole(!PyConsoleOptions.getInstance(project).isShowDebugConsoleByDefault());
- showDebugConsole(PyConsoleOptions.getInstance(project).isShowDebugConsoleByDefault());
-
- Disposer.register(this, myPydevConsoleView);
- Disposer.register(this, myTextConsole);
+ getSwitchConsoleActionPresentation().setIcon(PythonIcons.Python.Debug.CommandLine);
+ getSwitchConsoleActionPresentation().setText(PyBundle.message("run.configuration.show.command.line.action.name"));
}
public PythonDebugLanguageConsoleView(final Project project, Sdk sdk) {
@@ -81,192 +49,33 @@ public class PythonDebugLanguageConsoleView extends JPanel implements ConsoleVie
@Override
public void executeCode(@NotNull String code, @Nullable Editor e) {
- showDebugConsole(true);
+ enableConsole(false);
getPydevConsoleView().executeCode(code, e);
}
- private void doShowConsole(String type) {
- CardLayout cl = (CardLayout)(getLayout());
- cl.show(this, type);
- }
-
-
- public boolean isDebugConsole() {
- return myIsDebugConsole;
- }
-
- public void showDebugConsole(boolean flag) {
- if (flag) {
- doShowConsole(PYDEV_CONSOLE_PANEL);
- myPydevConsoleView.requestFocus();
- }
- else {
- doShowConsole(TEXT_CONSOLE_PANEL);
- }
- myIsDebugConsole = flag;
- }
-
public PythonConsoleView getPydevConsoleView() {
- return myPydevConsoleView;
+ return getSecondaryConsoleView();
}
public ConsoleViewImpl getTextConsole() {
- if (myTextConsole instanceof ConsoleViewImpl) {
- return (ConsoleViewImpl)myTextConsole;
+ ConsoleView consoleView = getPrimaryConsoleView();
+ if (consoleView instanceof ConsoleViewImpl) {
+ return (ConsoleViewImpl)consoleView;
}
return null;
}
@Override
- public void allowHeavyFilters() {
- myTextConsole.allowHeavyFilters();
- }
-
- @Override
- public JComponent getComponent() {
- return this;
- }
-
- @Override
- public JComponent getPreferredFocusableComponent() {
- return this;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public void print(@NotNull String s, @NotNull ConsoleViewContentType contentType) {
- myPydevConsoleView.print(s, contentType);
- myTextConsole.print(s, contentType);
- }
-
- @Override
- public void clear() {
- myPydevConsoleView.clear();
- myTextConsole.clear();
- }
-
- @Override
- public void scrollTo(int offset) {
- myPydevConsoleView.getLanguageConsole().getHistoryViewer().getCaretModel().moveToOffset(offset);
- myPydevConsoleView.getLanguageConsole().getHistoryViewer().getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
- myTextConsole.scrollTo(offset);
- }
-
- @Override
- public void attachToProcess(ProcessHandler processHandler) {
- myProcessHandler = processHandler;
- myPydevConsoleView.attachToProcess(processHandler);
- myTextConsole.attachToProcess(processHandler);
- }
-
- @Override
- public void setOutputPaused(boolean value) {
- myPydevConsoleView.setOutputPaused(value);
- myTextConsole.setOutputPaused(value);
- }
+ public void enableConsole(boolean primary) {
+ super.enableConsole(primary);
- @Override
- public boolean isOutputPaused() {
- return false;
- }
-
- @Override
- public boolean hasDeferredOutput() {
- return myPydevConsoleView.hasDeferredOutput() && myTextConsole.hasDeferredOutput();
- }
-
- @Override
- public void performWhenNoDeferredOutput(Runnable runnable) {
-
- }
-
- @Override
- public void setHelpId(String helpId) {
- myPydevConsoleView.setHelpId(helpId);
- myTextConsole.setHelpId(helpId);
- }
-
- @Override
- public void addMessageFilter(Filter filter) {
- myPydevConsoleView.addMessageFilter(filter);
- myTextConsole.addMessageFilter(filter);
- }
-
- @Override
- public void printHyperlink(String hyperlinkText, HyperlinkInfo info) {
- myPydevConsoleView.printHyperlink(hyperlinkText, info);
- myTextConsole.printHyperlink(hyperlinkText, info);
- }
-
- @Override
- public int getContentSize() {
- return myTextConsole.getContentSize();
- }
-
- @Override
- public boolean canPause() {
- return false;
- }
-
- @NotNull
- @Override
- public AnAction[] createConsoleActions() {
- List<AnAction> actions = Lists.newArrayList(myTextConsole.createConsoleActions());
- actions.add(new ShowDebugConsoleAction(this));
-
- return actions.toArray(new AnAction[actions.size()]);
- }
-
- @Override
- public void addChangeListener(@NotNull ChangeListener listener, @NotNull Disposable parent) {
- myPydevConsoleView.addChangeListener(listener, parent);
- if (myTextConsole instanceof ObservableConsoleView) {
- ((ObservableConsoleView)myTextConsole).addChangeListener(listener, parent);
- }
- }
-
- private static class ShowDebugConsoleAction extends ToggleAction implements DumbAware {
- private final PythonDebugLanguageConsoleView myConsole;
-
-
- public ShowDebugConsoleAction(final PythonDebugLanguageConsoleView console) {
- super(ExecutionBundle.message("run.configuration.show.command.line.action.name"), null,
- PythonIcons.Python.Debug.CommandLine);
- myConsole = console;
- }
-
- @Override
- public boolean isSelected(final AnActionEvent event) {
- return myConsole.isDebugConsole();
- }
-
- @Override
- public void setSelected(final AnActionEvent event, final boolean flag) {
- myConsole.showDebugConsole(flag);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- update(event);
- }
- });
- }
+ if (!primary && !isPrimaryConsoleEnabled()) {
+ PythonConsoleView pydevConsoleView = getPydevConsoleView();
+ LanguageConsoleImpl languageConsole = pydevConsoleView.getConsole();
- @Override
- public void update(final AnActionEvent event) {
- super.update(event);
- final Presentation presentation = event.getPresentation();
- final boolean isRunning = myConsole.myProcessHandler != null && !myConsole.myProcessHandler.isProcessTerminated();
- if (isRunning) {
- presentation.setEnabled(true);
- }
- else {
- myConsole.showDebugConsole(false);
- presentation.putClientProperty(SELECTED_PROPERTY, false);
- presentation.setEnabled(false);
- }
+ IdeFocusManager.findInstance().requestFocus(languageConsole.getConsoleEditor().getContentComponent(), true);
+ pydevConsoleView.updateUI();
+ languageConsole.getHistoryViewer().getComponent().updateUI();
}
}
}
diff --git a/python/src/com/jetbrains/python/documentation/DocStringReferenceContributor.java b/python/src/com/jetbrains/python/documentation/DocStringReferenceContributor.java
index 0867c293328f..192a70b8e8e8 100644
--- a/python/src/com/jetbrains/python/documentation/DocStringReferenceContributor.java
+++ b/python/src/com/jetbrains/python/documentation/DocStringReferenceContributor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,13 +17,14 @@ package com.jetbrains.python.documentation;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
public class DocStringReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(DocStringTagCompletionContributor.DOCSTRING_PATTERN,
new DocStringReferenceProvider());
}
diff --git a/python/src/com/jetbrains/python/documentation/doctest/PyDocReferenceExpression.java b/python/src/com/jetbrains/python/documentation/doctest/PyDocReferenceExpression.java
index 62356d2c08fb..46e4709de0ab 100644
--- a/python/src/com/jetbrains/python/documentation/doctest/PyDocReferenceExpression.java
+++ b/python/src/com/jetbrains/python/documentation/doctest/PyDocReferenceExpression.java
@@ -38,6 +38,7 @@ public class PyDocReferenceExpression extends PyReferenceExpressionImpl {
}
@NotNull
+ @Override
public PsiPolyVariantReference getReference(PyResolveContext context) {
if (isQualified()) {
return new PyQualifiedReference(this, context);
diff --git a/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java b/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
index 1185c2707bff..10ddcea15fbe 100644
--- a/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
+++ b/python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -52,7 +52,7 @@ public class PyClassFindUsagesHandler extends FindUsagesHandler {
}
@Override
- protected Collection<String> getStringsToSearch(PsiElement element) {
+ protected Collection<String> getStringsToSearch(@NotNull PsiElement element) {
if (element instanceof PyFunction && PyNames.INIT.equals(((PyFunction) element).getName())) {
return Collections.emptyList();
}
diff --git a/python/src/com/jetbrains/python/findUsages/PyModuleFindUsagesHandler.java b/python/src/com/jetbrains/python/findUsages/PyModuleFindUsagesHandler.java
index 6588d2d389a6..fd0eef003d6f 100644
--- a/python/src/com/jetbrains/python/findUsages/PyModuleFindUsagesHandler.java
+++ b/python/src/com/jetbrains/python/findUsages/PyModuleFindUsagesHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -72,6 +72,7 @@ public class PyModuleFindUsagesHandler extends FindUsagesHandler {
};
}
+ @NotNull
@Override
public Collection<PsiReference> findReferencesToHighlight(@NotNull PsiElement target, @NotNull SearchScope searchScope) {
if (target instanceof PyImportedModule) {
diff --git a/python/src/com/jetbrains/python/formatter/PyLanguageCodeStyleSettingsProvider.java b/python/src/com/jetbrains/python/formatter/PyLanguageCodeStyleSettingsProvider.java
index 9e7f97db5f8e..32ad8a31b003 100644
--- a/python/src/com/jetbrains/python/formatter/PyLanguageCodeStyleSettingsProvider.java
+++ b/python/src/com/jetbrains/python/formatter/PyLanguageCodeStyleSettingsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -123,6 +123,11 @@ public class PyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettin
return PlatformUtils.isPyCharm() ? DisplayPriority.KEY_LANGUAGE_SETTINGS : DisplayPriority.LANGUAGE_SETTINGS;
}
+ @Override
+ public boolean isIndentBasedLanguageSemantics() {
+ return true;
+ }
+
@SuppressWarnings("FieldCanBeLocal")
private static String SPACING_SETTINGS_PREVIEW = "def settings_preview(argument, key=value):\n" +
" dict = {1:'a', 2:'b', 3:'c'}\n" +
diff --git a/python/src/com/jetbrains/python/formatter/PyPreFormatProcessor.java b/python/src/com/jetbrains/python/formatter/PyPreFormatProcessor.java
index af07fe82bd3a..ee2c4abb7939 100644
--- a/python/src/com/jetbrains/python/formatter/PyPreFormatProcessor.java
+++ b/python/src/com/jetbrains/python/formatter/PyPreFormatProcessor.java
@@ -84,9 +84,13 @@ public class PyPreFormatProcessor implements PreFormatProcessor {
String text = element.getText();
int commentStart = text.indexOf('#');
if (commentStart != -1 && (commentStart + 1) < text.length()) {
- if (text.charAt(commentStart+1) == '!') {
+ char charAfterDash = text.charAt(commentStart + 1);
+ if (charAfterDash == '!' && element.getTextRange().getStartOffset() == 0) {
return; //shebang
}
+ if (charAfterDash == '#' || charAfterDash == ':') {
+ return;
+ }
String commentText = StringUtil.trimLeading(text.substring(commentStart + 1));
String newText = "# " + commentText;
diff --git a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
index 04477b1be313..e793de32c173 100644
--- a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
@@ -78,15 +78,17 @@ public class PyCallingNonCallableInspection extends PyInspection {
}
if (!callable) {
final PyType calleeType = callee != null ? myTypeEvalContext.getType(callee) : type;
+ String message = "Expression is not callable";
if (calleeType instanceof PyClassType) {
- registerProblem(node, String.format("'%s' object is not callable", calleeType.getName()), new PyRemoveCallQuickFix());
+ message = String.format("'%s' object is not callable", calleeType.getName());
}
else if (callee != null) {
- registerProblem(node, String.format("'%s' is not callable", callee.getName()), new PyRemoveCallQuickFix());
- }
- else {
- registerProblem(node, "Expression is not callable", new PyRemoveCallQuickFix());
+ final String name = callee.getName();
+ if (name != null) {
+ message = String.format("'%s' is not callable", name);
+ }
}
+ registerProblem(node, message, new PyRemoveCallQuickFix());
}
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java
index 5a7ac6ff9a30..ae47dbb6136e 100644
--- a/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyDocstringInspection.java
@@ -21,7 +21,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.codeInspection.SuppressIntentionAction;
+import com.intellij.codeInspection.SuppressQuickFix;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.TextRange;
@@ -230,9 +230,10 @@ public class PyDocstringInspection extends PyInspection {
}
}
+ @NotNull
@Override
- public SuppressIntentionAction[] getSuppressActions(@Nullable PsiElement element) {
- List<SuppressIntentionAction> result = new ArrayList<SuppressIntentionAction>();
+ public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
+ List<SuppressQuickFix> result = new ArrayList<SuppressQuickFix>();
if (element != null) {
if (PsiTreeUtil.getParentOfType(element, PyFunction.class) != null) {
result.add(new PySuppressInspectionFix(getShortName().replace("Inspection", ""), "Suppress for function", PyFunction.class));
@@ -241,6 +242,6 @@ public class PyDocstringInspection extends PyInspection {
result.add(new PySuppressInspectionFix(getShortName().replace("Inspection", ""), "Suppress for class", PyClass.class));
}
}
- return result.toArray(new SuppressIntentionAction[result.size()]);
+ return result.toArray(new SuppressQuickFix[result.size()]);
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyInspection.java b/python/src/com/jetbrains/python/inspections/PyInspection.java
index 9227f1c7d1d1..a35e2c774b05 100644
--- a/python/src/com/jetbrains/python/inspections/PyInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyInspection.java
@@ -15,10 +15,7 @@
*/
package com.jetbrains.python.inspections;
-import com.intellij.codeInspection.CustomSuppressableInspectionTool;
-import com.intellij.codeInspection.LocalInspectionTool;
-import com.intellij.codeInspection.SuppressIntentionAction;
-import com.intellij.codeInspection.SuppressionUtil;
+import com.intellij.codeInspection.*;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -41,7 +38,7 @@ import java.util.regex.Pattern;
/**
* @author yole
*/
-public abstract class PyInspection extends LocalInspectionTool implements CustomSuppressableInspectionTool {
+public abstract class PyInspection extends LocalInspectionTool {
@Nls
@NotNull
@Override
@@ -60,12 +57,13 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
return true;
}
+ @NotNull
@Override
- public SuppressIntentionAction[] getSuppressActions(@Nullable final PsiElement element) {
- List<SuppressIntentionAction> result = new ArrayList<SuppressIntentionAction>();
+ public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
+ List<SuppressQuickFix> result = new ArrayList<SuppressQuickFix>();
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for statement", PyStatement.class) {
@Override
- protected PsiElement getContainer(PsiElement context) {
+ public PsiElement getContainer(PsiElement context) {
if (PsiTreeUtil.getParentOfType(context, PyStatementList.class, false, ScopeOwner.class) != null ||
PsiTreeUtil.getParentOfType(context, PyFunction.class, PyClass.class) == null) {
return super.getContainer(context);
@@ -75,7 +73,7 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
});
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for function", PyFunction.class));
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for class", PyClass.class));
- return result.toArray(new SuppressIntentionAction[result.size()]);
+ return result.toArray(new SuppressQuickFix[result.size()]);
}
@Override
@@ -131,7 +129,7 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
return m.matches() && SuppressionUtil.isInspectionToolIdMentioned(m.group(1), getSuppressId());
}
- private String getSuppressId() {
+ protected String getSuppressId() {
return getShortName().replace("Inspection", "");
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
index 149ff2cca041..f4b9b7796e93 100644
--- a/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
@@ -303,9 +303,7 @@ public class PyPropertyDefinitionInspection extends PyInspection {
hasReturns = returnStatements.length > 0;
}
else {
- PyReferenceExpression callSite = being_checked instanceof PyReferenceExpression ? (PyReferenceExpression) being_checked : null;
- final PyType type = callSite != null ? callable.getCallType(myTypeEvalContext, callSite)
- : myTypeEvalContext.getReturnType(callable);
+ final PyType type = myTypeEvalContext.getReturnType(callable);
hasReturns = !(type instanceof PyNoneType);
}
if (allowed ^ hasReturns) {
diff --git a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
index d31d19ef4da9..bb0c83ed1979 100644
--- a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java
@@ -56,10 +56,7 @@ public class PyTypeCheckerInspection extends PyInspection {
// TODO: Visit decorators with arguments
@Override
public void visitPyCallExpression(PyCallExpression node) {
- final PyExpression callee = node.getCallee();
- if (callee instanceof PyQualifiedExpression) {
- checkCallSite((PyQualifiedExpression)callee);
- }
+ checkCallSite(node);
}
@Override
@@ -85,7 +82,7 @@ public class PyTypeCheckerInspection extends PyInspection {
}
}
- private void checkCallSite(@Nullable PyQualifiedExpression callSite) {
+ private void checkCallSite(@Nullable PyCallSiteExpression callSite) {
final Map<PyGenericType, PyType> substitutions = new LinkedHashMap<PyGenericType, PyType>();
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, myTypeEvalContext);
if (results != null) {
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java
index a138555d3693..9924292ad906 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java
@@ -138,7 +138,7 @@ public class AddMethodQuickFix implements LocalQuickFix {
method = (PyFunction)PyUtil.addElementToStatementList(method, clsStmtList, PyNames.INIT.equals(method.getName()));
if (myReplaceUsage) {
- showTemplateBuilder(method, problemElement.getContainingFile());
+ showTemplateBuilder(method);
}
}
catch (IncorrectOperationException ignored) {
@@ -158,9 +158,10 @@ public class AddMethodQuickFix implements LocalQuickFix {
return pyClass != null ? new PyClassTypeImpl(pyClass, false) : null;
}
- private static void showTemplateBuilder(PyFunction method, PsiFile file) {
+ private static void showTemplateBuilder(@NotNull PyFunction method) {
method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
-
+ final PsiFile file = method.getContainingFile();
+ if (file == null) return;
final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(method);
ParamHelper.walkDownParamArray(
method.getParameterList().getParameters(),
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PySuppressInspectionFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PySuppressInspectionFix.java
index 9addabf06a98..0e6a7d98b356 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/PySuppressInspectionFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/PySuppressInspectionFix.java
@@ -15,6 +15,7 @@
*/
package com.jetbrains.python.inspections.quickfix;
+import com.intellij.codeInsight.daemon.impl.actions.AbstractBatchSuppressByNoInspectionCommentFix;
import com.intellij.codeInsight.daemon.impl.actions.AbstractSuppressByNoInspectionCommentFix;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -23,7 +24,7 @@ import com.jetbrains.python.psi.PyElement;
/**
* @author yole
*/
-public class PySuppressInspectionFix extends AbstractSuppressByNoInspectionCommentFix {
+public class PySuppressInspectionFix extends AbstractBatchSuppressByNoInspectionCommentFix {
private final Class<? extends PyElement> myContainerClass;
public PySuppressInspectionFix(final String ID, final String text, final Class<? extends PyElement> containerClass) {
@@ -33,7 +34,7 @@ public class PySuppressInspectionFix extends AbstractSuppressByNoInspectionComme
}
@Override
- protected PsiElement getContainer(PsiElement context) {
+ public PsiElement getContainer(PsiElement context) {
return PsiTreeUtil.getParentOfType(context, myContainerClass);
}
}
diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
index fbe26803b39f..fac391abdff7 100644
--- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
+++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
@@ -997,7 +997,12 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
if (element == null) {
if (importElement.getImportedQName() != null) {
//Mark import as unused even if it can't be resolved
- result.add(importElement.getParent());
+ if (areAllImportsUnused(importStatement, unusedImports)) {
+ result.add(importStatement);
+ }
+ else {
+ result.add(importElement);
+ }
}
continue;
}
diff --git a/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralFindUsagesHandlerFactory.java b/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralFindUsagesHandlerFactory.java
index 006f4f3753e7..52091ed899b9 100644
--- a/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralFindUsagesHandlerFactory.java
+++ b/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralFindUsagesHandlerFactory.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.jetbrains.python.magicLiteral;
import com.intellij.find.findUsages.FindUsagesHandler;
@@ -34,7 +49,7 @@ public class PyMagicLiteralFindUsagesHandlerFactory extends FindUsagesHandlerFac
@Nullable
@Override
- protected Collection<String> getStringsToSearch(final PsiElement element) {
+ protected Collection<String> getStringsToSearch(@NotNull final PsiElement element) {
return Collections.singleton(((StringLiteralExpression)element).getStringValue());
}
}
diff --git a/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java b/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java
index 0a801b10494b..b7fdf465f7ea 100644
--- a/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java
+++ b/python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class PyMagicLiteralRenameHandler implements RenameHandler {
@Override
- public boolean isAvailableOnDataContext(DataContext dataContext) {
+ public boolean isAvailableOnDataContext(final DataContext dataContext) {
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) {
return false;
@@ -47,11 +47,7 @@ public class PyMagicLiteralRenameHandler implements RenameHandler {
final PsiElement element = getElement(file, editor);
- if (element == null || !PyMagicLiteralTools.isMagicLiteral(element)) {
- return false;
- }
-
- return true;
+ return !((element == null) || !PyMagicLiteralTools.isMagicLiteral(element));
}
@Nullable
diff --git a/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java b/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java
index c1847940b05e..fbbdfa215e9c 100644
--- a/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java
+++ b/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java
@@ -239,6 +239,8 @@ public class PyPIPackageUtil {
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection)connection).setSSLSocketFactory(sslContext.getSocketFactory());
}
+ connection.setConnectTimeout(5000);
+ connection.setReadTimeout(5000);
InputStream is = connection.getInputStream();
Reader reader = new InputStreamReader(is);
try{
@@ -257,8 +259,8 @@ public class PyPIPackageUtil {
return packages;
}
- public Collection<String> getPackageNames() throws IOException {
- Map<String, String> pyPIPackages = loadAndGetPackages();
+ public Collection<String> getPackageNames() {
+ Map<String, String> pyPIPackages = getPyPIPackages();
ArrayList<String> list = Lists.newArrayList(pyPIPackages.keySet());
Collections.sort(list);
return list;
diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
index 4a4f016b5579..359e497f21c8 100644
--- a/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
+++ b/python/src/com/jetbrains/python/packaging/PyPackageManagerImpl.java
@@ -425,6 +425,21 @@ public class PyPackageManagerImpl extends PyPackageManager {
@Override
public void install(String requirementString) throws PyExternalProcessException {
+ boolean hasSetuptools = false;
+ boolean hasPip = false;
+ try {
+ hasSetuptools = findInstalledPackage(SETUPTOOLS) != null;
+ }
+ catch (PyExternalProcessException ignored) {
+ }
+ try {
+ hasPip = findInstalledPackage(PIP) != null;
+ }
+ catch (PyExternalProcessException ignored) {
+ }
+
+ if (!hasSetuptools) installManagement(SETUPTOOLS);
+ if (!hasPip) installManagement(PIP);
install(Collections.singletonList(PyRequirement.fromString(requirementString)), Collections.<String>emptyList());
}
@@ -591,17 +606,31 @@ public class PyPackageManagerImpl extends PyPackageManager {
}
}
+ @Override
@Nullable
- public PyPackage findPackage(String name) throws PyExternalProcessException {
+ public PyPackage findInstalledPackage(String name) throws PyExternalProcessException {
return findPackageByName(name, getPackages());
}
+ @Override
+ public boolean findPackage(@NotNull final String name) {
+ try {
+ final String output = runPythonHelper(PACKAGING_TOOL, list("search", name));
+ return StringUtil.containsIgnoreCase(output, name + " ");
+ }
+ catch (PyExternalProcessException e) {
+ LOG.error(e.getMessage());
+ return false;
+ }
+ }
+
@Nullable
public PyPackage findPackageFast(String name) throws PyExternalProcessException {
final List<PyPackage> packages = getPackagesFast();
return packages != null ? findPackageByName(name, packages) : null;
}
+ @Nullable
private static PyPackage findPackageByName(String name, List<PyPackage> packages) {
for (PyPackage pkg : packages) {
if (name.equalsIgnoreCase(pkg.getName())) {
diff --git a/python/src/com/jetbrains/python/packaging/PyPackageManagersImpl.java b/python/src/com/jetbrains/python/packaging/PyPackageManagersImpl.java
index 714bf8212b58..054e9e01d23f 100644
--- a/python/src/com/jetbrains/python/packaging/PyPackageManagersImpl.java
+++ b/python/src/com/jetbrains/python/packaging/PyPackageManagersImpl.java
@@ -17,6 +17,7 @@ package com.jetbrains.python.packaging;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
@@ -29,6 +30,7 @@ import java.util.Map;
public class PyPackageManagersImpl extends PyPackageManagers {
private final Map<String, PyPackageManagerImpl> myInstances = new HashMap<String, PyPackageManagerImpl>();
+ @NotNull
@Override
public synchronized PyPackageManager forSdk(Sdk sdk) {
final String name = sdk.getName();
diff --git a/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java b/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
index e0c0e3074e0c..348d2817ec75 100644
--- a/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
+++ b/python/src/com/jetbrains/python/packaging/ui/PyInstalledPackagesPanel.java
@@ -88,11 +88,11 @@ public class PyInstalledPackagesPanel extends InstalledPackagesPanel {
PyExternalProcessException exc = null;
try {
PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(selectedSdk);
- myHasSetuptools = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_SETUPTOOLS) != null;
+ myHasSetuptools = packageManager.findInstalledPackage(PyPackageManagerImpl.PACKAGE_SETUPTOOLS) != null;
if (!myHasSetuptools) {
- myHasSetuptools = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_DISTRIBUTE) != null;
+ myHasSetuptools = packageManager.findInstalledPackage(PyPackageManagerImpl.PACKAGE_DISTRIBUTE) != null;
}
- myHasPip = packageManager.findPackage(PyPackageManagerImpl.PACKAGE_PIP) != null;
+ myHasPip = packageManager.findInstalledPackage(PyPackageManagerImpl.PACKAGE_PIP) != null;
}
catch (PyExternalProcessException e) {
exc = e;
diff --git a/python/src/com/jetbrains/python/projectView/PyRemoteLibrariesNode.java b/python/src/com/jetbrains/python/projectView/PyRemoteLibrariesNode.java
index 2fd5694eacf1..62de7ea14daf 100644
--- a/python/src/com/jetbrains/python/projectView/PyRemoteLibrariesNode.java
+++ b/python/src/com/jetbrains/python/projectView/PyRemoteLibrariesNode.java
@@ -15,25 +15,41 @@
*/
package com.jetbrains.python.projectView;
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
+import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.util.PlatformIcons;
+import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
import com.jetbrains.python.sdk.PySdkUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
+
/**
* @author traff
*/
public class PyRemoteLibrariesNode extends PsiDirectoryNode {
- private PyRemoteLibrariesNode(Project project, PsiDirectory value, ViewSettings viewSettings) {
+ private final Sdk mySdk;
+ private final PyRemoteSdkAdditionalDataBase myRemoteSdkData;
+
+ private PyRemoteLibrariesNode(Sdk sdk, Project project, PsiDirectory value, ViewSettings viewSettings) {
super(project, value, viewSettings);
+ mySdk = sdk;
+ assert mySdk.getSdkAdditionalData() instanceof PyRemoteSdkAdditionalDataBase;
+
+ myRemoteSdkData = (PyRemoteSdkAdditionalDataBase)mySdk.getSdkAdditionalData();
}
@Override
@@ -44,11 +60,47 @@ public class PyRemoteLibrariesNode extends PsiDirectoryNode {
@Nullable
public static PyRemoteLibrariesNode create(@NotNull Project project, @NotNull Sdk sdk, ViewSettings settings) {
- final VirtualFile remoteLibraries = PySdkUtil.findRemoteLibrariesDir(sdk);
- if (remoteLibraries != null) {
+ final VirtualFile remoteLibrary = PySdkUtil.findAnyRemoteLibrary(sdk);
+ if (remoteLibrary != null) {
+ final VirtualFile remoteLibraries = remoteLibrary.getParent();
final PsiDirectory remoteLibrariesDirectory = PsiManager.getInstance(project).findDirectory(remoteLibraries);
- return new PyRemoteLibrariesNode(project, remoteLibrariesDirectory, settings);
+ return new PyRemoteLibrariesNode(sdk, project, remoteLibrariesDirectory, settings);
}
return null;
}
+
+ @Override
+ public Collection<AbstractTreeNode> getChildrenImpl() {
+
+ return FluentIterable.from(Lists.newArrayList(getValue().getChildren())).transform(new Function<PsiElement, AbstractTreeNode>() {
+ @Override
+ public AbstractTreeNode apply(PsiElement input) {
+ if (input instanceof PsiDirectory) {
+ PsiDirectory directory = (PsiDirectory)input;
+ if (myRemoteSdkData.getPathMappings().canReplaceLocal((directory.getVirtualFile().getPath()))) {
+ return new PyRemoteRootNode(myRemoteSdkData.getPathMappings().convertToRemote(directory.getVirtualFile().getPath()),
+ getProject(), directory, getSettings());
+ }
+ }
+
+ return null;
+ }
+ }).filter(Predicates.notNull()).toList();
+ }
+
+ public static class PyRemoteRootNode extends PsiDirectoryNode {
+
+ private String myRemotePath;
+
+ public PyRemoteRootNode(String remotePath, Project project, PsiDirectory value, ViewSettings viewSettings) {
+ super(project, value, viewSettings);
+ myRemotePath = remotePath;
+ }
+
+ @Override
+ protected void updateImpl(PresentationData data) {
+ data.setPresentableText(myRemotePath);
+ data.setIcon(PlatformIcons.FOLDER_ICON);
+ }
+ }
}
diff --git a/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java b/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java
index dedc82e38246..6153bc64146d 100644
--- a/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java
+++ b/python/src/com/jetbrains/python/projectView/PyTreeStructureProvider.java
@@ -36,7 +36,6 @@ import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil;
import com.jetbrains.python.psi.PyDocStringOwner;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
-import com.jetbrains.python.remote.PyRemoteSdkCredentials;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -116,6 +115,17 @@ public class PyTreeStructureProvider implements SelectableTreeStructureProvider,
if (dirParent != null && dirParent.getName().equals(PythonSdkType.SKELETON_DIR_NAME)) {
continue;
}
+
+ if (dirParent != null && dirParent.getName().equals(PythonSdkType.REMOTE_SOURCES_DIR_NAME)) {
+ continue;
+ }
+ if (dirParent != null) {
+ PsiDirectory grandParent = dirParent.getParent();
+
+ if (grandParent != null && grandParent.getName().equals(PythonSdkType.REMOTE_SOURCES_DIR_NAME)) {
+ continue;
+ }
+ }
}
newChildren.add(child);
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java b/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java
deleted file mode 100644
index 36e67a166765..000000000000
--- a/python/src/com/jetbrains/python/psi/impl/PyBlockEvaluator.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.psi.impl;
-
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.util.QualifiedName;
-import com.jetbrains.python.PyNames;
-import com.jetbrains.python.psi.*;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- *
- * @author yole
- */
-public class PyBlockEvaluator {
- private final Map<String, Object> myNamespace = new HashMap<String, Object>();
- private final Map<String, List<PyExpression>> myDeclarations = new HashMap<String, List<PyExpression>>();
- private final Set<PyFile> myVisitedFiles;
- private final Set<String> myDeclarationsToTrack = new HashSet<String>();
- private String myCurrentFilePath;
- private Object myReturnValue;
- private boolean myEvaluateCollectionItems = true;
-
- public PyBlockEvaluator() {
- myVisitedFiles = new HashSet<PyFile>();
- }
-
- public PyBlockEvaluator(Set<PyFile> visitedFiles) {
- myVisitedFiles = visitedFiles;
- }
-
- public void trackDeclarations(String attrName) {
- myDeclarationsToTrack.add(attrName);
- }
-
- public void evaluate(PyElement element) {
- VirtualFile vFile = element.getContainingFile().getVirtualFile();
- myCurrentFilePath = vFile != null ? vFile.getPath() : null;
- if (myVisitedFiles.contains(element)) {
- return;
- }
- myVisitedFiles.add((PyFile)element.getContainingFile());
- PyElement statementContainer = element instanceof PyFunction ? ((PyFunction) element).getStatementList() : element;
- if (statementContainer == null) {
- return;
- }
- statementContainer.acceptChildren(new PyElementVisitor() {
- @Override
- public void visitPyAssignmentStatement(PyAssignmentStatement node) {
- PyExpression expression = node.getLeftHandSideExpression();
- if (expression instanceof PyTargetExpression) {
- String name = expression.getName();
- PyExpression value = ((PyTargetExpression)expression).findAssignedValue();
- myNamespace.put(name, prepareEvaluator().evaluate(value));
- if (myDeclarationsToTrack.contains(name)) {
- List<PyExpression> declarations = new ArrayList<PyExpression>();
- PyPsiUtils.sequenceToList(declarations, value);
- myDeclarations.put(name, declarations);
- }
- }
- else if (expression instanceof PySubscriptionExpression) {
- PyExpression operand = ((PySubscriptionExpression)expression).getOperand();
- PyExpression indexExpression = ((PySubscriptionExpression)expression).getIndexExpression();
- if (operand instanceof PyReferenceExpression && ((PyReferenceExpression)operand).getQualifier() == null) {
- Object currentValue = myNamespace.get(((PyReferenceExpression)operand).getReferencedName());
- if (currentValue instanceof Map) {
- Object mapKey = prepareEvaluator().evaluate(indexExpression);
- if (mapKey != null) {
- Object value = myEvaluateCollectionItems ? prepareEvaluator().evaluate(node.getAssignedValue()) : node.getAssignedValue();
- ((Map)currentValue).put(mapKey, value);
- }
- }
- }
- }
- }
-
- @Override
- public void visitPyAugAssignmentStatement(PyAugAssignmentStatement node) {
- PyExpression target = node.getTarget();
- String name = target.getName();
- if (target instanceof PyReferenceExpression && !((PyReferenceExpression)target).isQualified() && name != null) {
- Object currentValue = myNamespace.get(name);
- if (currentValue != null) {
- Object rhs = prepareEvaluator().evaluate(node.getValue());
- myNamespace.put(name, prepareEvaluator().concatenate(currentValue, rhs));
- }
- if (myDeclarationsToTrack.contains(name)) {
- List<PyExpression> declarations = myDeclarations.get(name);
- if (declarations != null) {
- PyPsiUtils.sequenceToList(declarations, node.getValue());
- }
- }
- }
- }
-
- @Override
- public void visitPyExpressionStatement(PyExpressionStatement node) {
- node.getExpression().accept(this);
- }
-
- @Override
- public void visitPyCallExpression(PyCallExpression node) {
- PyExpression callee = node.getCallee();
- if (callee instanceof PyReferenceExpression) {
- PyReferenceExpression calleeRef = (PyReferenceExpression)callee;
- PyExpression qualifier = calleeRef.getQualifier();
- if (qualifier instanceof PyReferenceExpression) {
- PyReferenceExpression qualifierRef = (PyReferenceExpression)qualifier;
- if (!qualifierRef.isQualified()) {
- if (PyNames.EXTEND.equals(calleeRef.getReferencedName()) && node.getArguments().length == 1) {
- processExtendCall(node, qualifierRef.getReferencedName());
- }
- else if (PyNames.UPDATE.equals(calleeRef.getReferencedName()) && node.getArguments().length == 1) {
- processUpdateCall(node, qualifierRef.getReferencedName());
- }
- }
- }
- }
- }
-
- @Override
- public void visitPyFromImportStatement(PyFromImportStatement node) {
- if (node.isFromFuture()) return;
- PsiElement source = PyUtil.turnDirIntoInit(node.resolveImportSource());
- if (source instanceof PyFile) {
- PyBlockEvaluator importEvaluator = new PyBlockEvaluator(myVisitedFiles);
- importEvaluator.myDeclarationsToTrack.addAll(myDeclarationsToTrack);
- importEvaluator.evaluate((PyFile)source);
- if (node.isStarImport()) {
- // TODO honor __all__ here
- myNamespace.putAll(importEvaluator.myNamespace);
- myDeclarations.putAll(importEvaluator.myDeclarations);
- }
- else {
- for (final PyImportElement element : node.getImportElements()) {
- final String nameOfVarInOurModule = element.getVisibleName();
- final QualifiedName nameOfVarInExternalModule = element.getImportedQName();
- if ((nameOfVarInOurModule == null) || (nameOfVarInExternalModule == null)) {
- continue;
- }
-
- final Object value = importEvaluator.myNamespace.get(nameOfVarInExternalModule.toString());
- myNamespace.put(nameOfVarInOurModule, value);
- final List<PyExpression> declarations = importEvaluator.getDeclarations(nameOfVarInOurModule);
- if (myDeclarations.containsKey(nameOfVarInOurModule)) {
- myDeclarations.get(nameOfVarInOurModule).addAll(declarations);
- }
- else {
- myDeclarations.put(nameOfVarInOurModule, declarations);
- }
- }
- }
- }
- }
-
- @Override
- public void visitPyIfStatement(PyIfStatement node) {
- PyStatementList list = node.getIfPart().getStatementList();
- if (list != null) {
- list.acceptChildren(this);
- }
- }
-
- @Override
- public void visitPyReturnStatement(PyReturnStatement node) {
- myReturnValue = prepareEvaluator().evaluate(node.getExpression());
- }
- });
- }
-
- private void processExtendCall(PyCallExpression node, String nameBeingExtended) {
- PyExpression arg = node.getArguments()[0];
-
- Object value = myNamespace.get(nameBeingExtended);
- if (value instanceof List) {
- Object argValue = prepareEvaluator().evaluate(arg);
- myNamespace.put(nameBeingExtended, prepareEvaluator().concatenate(value, argValue));
- }
-
- if (myDeclarationsToTrack.contains(nameBeingExtended)) {
- List<PyExpression> declarations = myDeclarations.get(nameBeingExtended);
- if (declarations != null) {
- PyPsiUtils.sequenceToList(declarations, arg);
- }
- }
- }
-
- private void processUpdateCall(PyCallExpression node, String name) {
- Object value = myNamespace.get(name);
- if (value instanceof Map) {
- Object argValue = prepareEvaluator().evaluate(node.getArguments()[0]);
- if (argValue instanceof Map) {
- ((Map)value).putAll((Map)argValue);
- }
- }
- }
-
- private PyEvaluator prepareEvaluator() {
- PyEvaluator evaluator = createEvaluator();
- evaluator.setNamespace(myNamespace);
- evaluator.setEvaluateCollectionItems(myEvaluateCollectionItems);
- return evaluator;
- }
-
- protected PyEvaluator createEvaluator() {
- return new PyPathEvaluator(myCurrentFilePath);
- }
-
- public Object getValue(String name) {
- return myNamespace.get(name);
- }
-
- @Nullable
- public String getValueAsString(String name) {
- Object value = myNamespace.get(name);
- return value instanceof String ? (String) value : null;
- }
-
- @Nullable
- public List getValueAsList(String name) {
- Object value = myNamespace.get(name);
- return value instanceof List ? (List) value : null;
- }
-
- @NotNull
- public List<String> getValueAsStringList(String name) {
- Object value = myNamespace.get(name);
- if (value instanceof List) {
- List valueList = (List) value;
- for (Object o : valueList) {
- if (o != null && !(o instanceof String)) {
- return Collections.emptyList();
- }
- }
- return (List<String>) value;
- }
- if (value instanceof String) {
- return Collections.singletonList((String) value);
- }
- return Collections.emptyList();
- }
-
- public Set<PyFile> getVisitedFiles() {
- return myVisitedFiles;
- }
-
- @NotNull
- public List<PyExpression> getDeclarations(String name) {
- List<PyExpression> expressions = myDeclarations.get(name);
- return expressions != null ? expressions : Collections.<PyExpression>emptyList();
- }
-
- public Object getReturnValue() {
- return myReturnValue;
- }
-
- public void setEvaluateCollectionItems(boolean evaluateCollectionItems) {
- myEvaluateCollectionItems = evaluateCollectionItems;
- }
-}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
index 0f4b0813cf7c..1f03945574b3 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
@@ -15,6 +15,7 @@
*/
package com.jetbrains.python.psi.impl;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
@@ -24,6 +25,7 @@ import com.intellij.openapi.roots.JdkOrderEntry;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.impl.ModuleLibraryOrderEntryImpl;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -126,7 +128,7 @@ public class PyBuiltinCache {
}
@Nullable
- public static PyFile getSkeletonFile(@NotNull Project project, @NotNull Sdk sdk, @NotNull String name) {
+ public static PyFile getSkeletonFile(final @NotNull Project project, @NotNull Sdk sdk, @NotNull String name) {
SdkTypeId sdkType = sdk.getSdkType();
if (sdkType instanceof PythonSdkType) {
// dig out the builtins file, create an instance based on it
@@ -136,12 +138,20 @@ public class PyBuiltinCache {
final String builtins_url = url + "/" + name;
File builtins = new File(VfsUtilCore.urlToPath(builtins_url));
if (builtins.isFile() && builtins.canRead()) {
- VirtualFile builtins_vfile = LocalFileSystem.getInstance().findFileByIoFile(builtins);
+ final VirtualFile builtins_vfile = LocalFileSystem.getInstance().findFileByIoFile(builtins);
if (builtins_vfile != null) {
- PsiFile file = PsiManager.getInstance(project).findFile(builtins_vfile);
- if (file instanceof PyFile) {
- return (PyFile)file;
- }
+ final Ref<PyFile> result = Ref.create();
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ PsiFile file = PsiManager.getInstance(project).findFile(builtins_vfile);
+ if (file instanceof PyFile) {
+ result.set((PyFile)file);
+ }
+ }
+ });
+ return result.get();
+
}
}
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
index b9fe8c342054..d44c848049ba 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
@@ -365,14 +365,14 @@ public class PyCallExpressionHelper {
/**
* Returns argument if it exists and has appropriate type
- * @param parameter argument
- * @param argClass expected class
+ * @param parameter argument
+ * @param argClass expected class
* @param expression call expression
- * @param <T> expected class
+ * @param <T> expected class
* @return argument expression or null if has wrong type of does not exist
*/
@Nullable
- public static <T extends PsiElement> T getArgument(
+ public static <T extends PsiElement> T getArgument(
@NotNull final FunctionParameter parameter,
@NotNull final Class<T> argClass,
@NotNull final PyCallExpression expression) {
@@ -449,7 +449,7 @@ public class PyCallExpressionHelper {
}
}
if (init != null) {
- final PyType t = init.getCallType(context, (PyReferenceExpression)callee);
+ final PyType t = init.getCallType(context, call);
if (cls != null) {
if (init.getContainingClass() != cls) {
if (t instanceof PyCollectionType) {
@@ -474,11 +474,11 @@ public class PyCallExpressionHelper {
}
final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context, call);
if (providedType instanceof PyCallableType) {
- return ((PyCallableType)providedType).getCallType(context, (PyReferenceExpression)callee);
+ return ((PyCallableType)providedType).getCallType(context, call);
}
if (target instanceof Callable) {
final Callable callable = (Callable)target;
- return callable.getCallType(context, (PyReferenceExpression)callee);
+ return callable.getCallType(context, call);
}
}
}
@@ -489,13 +489,7 @@ public class PyCallExpressionHelper {
final PyType type = context.getType(callee);
if (type instanceof PyCallableType) {
final PyCallableType callableType = (PyCallableType)type;
- final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null;
- if (callSite != null) {
- return callableType.getCallType(context, callSite);
- }
- else {
- return callableType.getReturnType(context);
- }
+ return callableType.getCallType(context, call);
}
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
index c723aedb6b0d..030fcfe3d7e5 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java
@@ -419,6 +419,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
return PyPsiUtils.collectStubChildren(this, this.getStub(), PyElementTypes.CLASS_DECLARATION, PyClass.class);
}
+ @NotNull
@Override
public List<PyFunction> getTopLevelFunctions() {
return PyPsiUtils.collectStubChildren(this, this.getStub(), PyElementTypes.FUNCTION_DECLARATION, PyFunction.class);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java
index 53dea09e4f5c..e0cdf87b2aab 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionBuilder.java
@@ -24,13 +24,9 @@ import com.intellij.util.ArrayUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.psi.*;
-
import org.jetbrains.annotations.NotNull;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.regex.Pattern;
/**
@@ -45,10 +41,13 @@ public class PyFunctionBuilder {
private final List<String> myDecorators = new ArrayList<String>();
private String myAnnotation = null;
private String[] myDocStringLines = null;
+ @NotNull
+ private final Map<String, String> myDecoratorValues = new HashMap<String, String>();
/**
* Creates builder copying signature and doc from another one.
- * @param source what to copy
+ *
+ * @param source what to copy
* @param decoratorsToCopyIfExist list of decorator names to be copied to new function.
* @return builder configured by this function
*/
@@ -82,6 +81,7 @@ public class PyFunctionBuilder {
/**
* Adds docstring to function. Provide doc with out of comment blocks.
+ *
* @param docString doc
*/
public void docString(@NotNull final String docString) {
@@ -127,15 +127,21 @@ public class PyFunctionBuilder {
}
public PyFunction buildFunction(Project project, final LanguageLevel languageLevel) {
- String text = buildText(project);
PyElementGenerator generator = PyElementGenerator.getInstance(project);
+ String text = buildText(project, generator, languageLevel);
return generator.createFromText(languageLevel, PyFunction.class, text);
}
- private String buildText(Project project) {
+ private String buildText(Project project, PyElementGenerator generator, LanguageLevel languageLevel) {
StringBuilder builder = new StringBuilder();
for (String decorator : myDecorators) {
- builder.append(decorator).append("\n");
+ final StringBuilder decoratorAppender = builder.append('@' + decorator);
+ if (myDecoratorValues.containsKey(decorator)) {
+ final PyCallExpression fakeCall = generator.createCallExpression(languageLevel, "fakeFunction");
+ fakeCall.getArgumentList().addArgument(generator.createStringLiteralFromString(myDecoratorValues.get(decorator)));
+ decoratorAppender.append(fakeCall.getArgumentList().getText());
+ }
+ decoratorAppender.append("\n");
}
builder.append("def ");
builder.append(myName).append("(");
@@ -165,8 +171,18 @@ public class PyFunctionBuilder {
return builder.toString();
}
+ /**
+ * Adds decorator with argument
+ * @param decoratorName decorator name
+ * @param value its argument
+ */
+ public void decorate(@NotNull final String decoratorName, @NotNull final String value) {
+ decorate(decoratorName);
+ myDecoratorValues.put(decoratorName, value);
+ }
+
public void decorate(String decoratorName) {
- myDecorators.add("@" + decoratorName);
+ myDecorators.add(decoratorName);
}
@NotNull
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
index acc225b67f22..2531b37bf8b2 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
@@ -209,7 +209,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
PyType type = null;
for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
type = typeProvider.getCallType(this, callSite, context);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
index 0dd75915de12..3dd9f78083d6 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java
@@ -70,7 +70,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return context.getReturnType(this);
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
index 79535f21f3f4..6aeb16e96113 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyPrefixExpressionImpl.java
@@ -70,13 +70,10 @@ public class PyPrefixExpressionImpl extends PyElementImpl implements PyPrefixExp
return getReference(PyResolveContext.noImplicits());
}
+ @NotNull
@Override
public PsiPolyVariantReference getReference(PyResolveContext context) {
- final PyElementType t = getOperator();
- if (t.getSpecialMethodName() != null) {
- return new PyOperatorReference(this, context);
- }
- return null;
+ return new PyOperatorReference(this, context);
}
@Override
@@ -85,11 +82,10 @@ public class PyPrefixExpressionImpl extends PyElementImpl implements PyPrefixExp
return PyBuiltinCache.getInstance(this).getBoolType();
}
final PsiReference ref = getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
- if (ref != null) {
- final PsiElement resolved = ref.resolve();
- if (resolved instanceof Callable) {
- return ((Callable)resolved).getCallType(context, this);
- }
+ final PsiElement resolved = ref.resolve();
+ if (resolved instanceof Callable) {
+ // TODO: Make PyPrefixExpression a PyCallSiteExpression, use getCallType() here and analyze it in PyTypeChecker.analyzeCallSite()
+ return ((Callable)resolved).getReturnType(context, key);
}
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
index 47ae58965b8a..126ed26acf32 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
@@ -57,13 +57,14 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
super(astNode);
}
- @Override
@NotNull
+ @Override
public PsiPolyVariantReference getReference() {
return getReference(PyResolveContext.defaultContext());
}
@NotNull
+ @Override
public PsiPolyVariantReference getReference(PyResolveContext context) {
final PsiFile file = getContainingFile();
final PyExpression qualifier = getQualifier();
diff --git a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
index 2b21e17ee0f8..9cceec4fd5d5 100644
--- a/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
@@ -68,11 +68,9 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub
public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
PyType res = null;
final PsiReference ref = getReference(PyResolveContext.noImplicits().withTypeEvalContext(context));
- if (ref != null) {
- final PsiElement resolved = ref.resolve();
- if (resolved instanceof Callable) {
- res = ((Callable)resolved).getCallType(context, this);
- }
+ final PsiElement resolved = ref.resolve();
+ if (resolved instanceof Callable) {
+ res = ((Callable)resolved).getCallType(context, this);
}
if (PyTypeChecker.isUnknown(res) || res instanceof PyNoneType) {
final PyExpression indexExpression = getIndexExpression();
@@ -98,6 +96,7 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub
return getReference(PyResolveContext.noImplicits());
}
+ @NotNull
@Override
public PsiPolyVariantReference getReference(PyResolveContext context) {
return new PyOperatorReference(this, context);
diff --git a/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java b/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java
index c3fd23bc289c..136a7073bb8b 100644
--- a/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java
+++ b/python/src/com/jetbrains/python/psi/impl/PythonLanguageLevelPusher.java
@@ -15,11 +15,14 @@
*/
package com.jetbrains.python.psi.impl;
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetManager;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
@@ -37,6 +40,8 @@ import com.intellij.util.containers.WeakHashMap;
import com.intellij.util.io.DataInputOutputUtil;
import com.intellij.util.messages.MessageBus;
import com.jetbrains.python.PythonFileType;
+import com.jetbrains.python.PythonModuleTypeBase;
+import com.jetbrains.python.facet.PythonFacetSettings;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
@@ -61,11 +66,13 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<LanguageLev
final Module[] modules = ModuleManager.getInstance(project).getModules();
Set<Sdk> usedSdks = new HashSet<Sdk>();
for (Module module : modules) {
- final Sdk sdk = PythonSdkType.findPythonSdk(module);
- myModuleSdks.put(module, sdk);
- if (sdk != null && !usedSdks.contains(sdk)) {
- usedSdks.add(sdk);
- updateSdkLanguageLevel(project, sdk);
+ if (isPythonModule(module)) {
+ final Sdk sdk = PythonSdkType.findPythonSdk(module);
+ myModuleSdks.put(module, sdk);
+ if (sdk != null && !usedSdks.contains(sdk)) {
+ usedSdks.add(sdk);
+ updateSdkLanguageLevel(project, sdk);
+ }
}
}
}
@@ -167,17 +174,19 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<LanguageLev
final Module[] modules = ModuleManager.getInstance(project).getModules();
boolean needReparseOpenFiles = false;
for (Module module : modules) {
- Sdk newSdk = PythonSdkType.findPythonSdk(module);
- if (myModuleSdks.containsKey(module)) {
- Sdk oldSdk = myModuleSdks.get(module);
- if ((newSdk != null || oldSdk != null) && newSdk != oldSdk) {
- needReparseOpenFiles = true;
+ if (isPythonModule(module)) {
+ Sdk newSdk = PythonSdkType.findPythonSdk(module);
+ if (myModuleSdks.containsKey(module)) {
+ Sdk oldSdk = myModuleSdks.get(module);
+ if ((newSdk != null || oldSdk != null) && newSdk != oldSdk) {
+ needReparseOpenFiles = true;
+ }
+ }
+ myModuleSdks.put(module, newSdk);
+ if (newSdk != null && !updatedSdks.contains(newSdk)) {
+ updatedSdks.add(newSdk);
+ updateSdkLanguageLevel(project, newSdk);
}
- }
- myModuleSdks.put(module, newSdk);
- if (newSdk != null && !updatedSdks.contains(newSdk)) {
- updatedSdks.add(newSdk);
- updateSdkLanguageLevel(project, newSdk);
}
}
if (needReparseOpenFiles) {
@@ -185,6 +194,18 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<LanguageLev
}
}
+ private static boolean isPythonModule(@NotNull final Module module) {
+ final ModuleType moduleType = ModuleType.get(module);
+ if (moduleType instanceof PythonModuleTypeBase) return true;
+ final Facet[] allFacets = FacetManager.getInstance(module).getAllFacets();
+ for (Facet facet : allFacets) {
+ if (facet.getConfiguration() instanceof PythonFacetSettings) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void updateSdkLanguageLevel(final Project project, final Sdk sdk) {
final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(sdk);
final VirtualFile[] files = sdk.getRootProvider().getFiles(OrderRootType.CLASSES);
@@ -240,4 +261,8 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<LanguageLev
LanguageLevel.FORCE_LANGUAGE_LEVEL = languageLevel;
pushLanguageLevel(project);
}
+
+ public void flushLanguageLevelCache() {
+ myModuleSdks.clear();
+ }
}
diff --git a/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyBlockEvaluator.java b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyBlockEvaluator.java
new file mode 100644
index 000000000000..b1fca2893970
--- /dev/null
+++ b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyBlockEvaluator.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.psi.impl.blockEvaluator;
+
+import com.google.common.collect.Sets;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.QualifiedName;
+import com.jetbrains.python.PyNames;
+import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyEvaluator;
+import com.jetbrains.python.psi.impl.PyPathEvaluator;
+import com.jetbrains.python.psi.impl.PyPsiUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author yole
+ */
+public class PyBlockEvaluator {
+ @NotNull
+ private final PyEvaluationResult myEvaluationResult = new PyEvaluationResult();
+ @NotNull
+ private final PyEvaluationContext myContext;
+ private final Set<PyFile> myVisitedFiles;
+ private final Set<String> myDeclarationsToTrack = new HashSet<String>();
+ private String myCurrentFilePath;
+ private Object myReturnValue;
+ private boolean myEvaluateCollectionItems = true;
+
+ /**
+ * @param evaluationContext context, obtained via {@link #getContext()}. Pass it here to enable cache. See {@link com.jetbrains.python.psi.impl.blockEvaluator.PyEvaluationContext}
+ * for more info
+ * @see com.jetbrains.python.psi.impl.blockEvaluator.PyEvaluationContext
+ */
+ public PyBlockEvaluator(@NotNull final PyEvaluationContext evaluationContext) {
+ this(Sets.<PyFile>newHashSet(), evaluationContext);
+ }
+
+ /**
+ * Create evaluator with out of cache context
+ */
+ public PyBlockEvaluator() {
+ this(new PyEvaluationContext());
+ }
+
+ private PyBlockEvaluator(@NotNull final Set<PyFile> visitedFiles, @NotNull final PyEvaluationContext evaluationContext) {
+ myVisitedFiles = visitedFiles;
+ myContext = evaluationContext;
+ }
+
+ public void trackDeclarations(String attrName) {
+ myDeclarationsToTrack.add(attrName);
+ }
+
+ public void evaluate(PyElement element) {
+ VirtualFile vFile = element.getContainingFile().getVirtualFile();
+ myCurrentFilePath = vFile != null ? vFile.getPath() : null;
+ if (myVisitedFiles.contains(element)) {
+ return;
+ }
+ myVisitedFiles.add((PyFile)element.getContainingFile());
+ PyElement statementContainer = element instanceof PyFunction ? ((PyFunction)element).getStatementList() : element;
+ if (statementContainer == null) {
+ return;
+ }
+ statementContainer.acceptChildren(new MyPyElementVisitor());
+ }
+
+ private void processExtendCall(PyCallExpression node, String nameBeingExtended) {
+ PyExpression arg = node.getArguments()[0];
+
+ Object value = myEvaluationResult.myNamespace.get(nameBeingExtended);
+ if (value instanceof List) {
+ Object argValue = prepareEvaluator().evaluate(arg);
+ myEvaluationResult.myNamespace.put(nameBeingExtended, prepareEvaluator().concatenate(value, argValue));
+ }
+
+ if (myDeclarationsToTrack.contains(nameBeingExtended)) {
+ List<PyExpression> declarations = myEvaluationResult.myDeclarations.get(nameBeingExtended);
+ if (declarations != null) {
+ PyPsiUtils.sequenceToList(declarations, arg);
+ }
+ }
+ }
+
+ private void processUpdateCall(PyCallExpression node, String name) {
+ Object value = myEvaluationResult.myNamespace.get(name);
+ if (value instanceof Map) {
+ Object argValue = prepareEvaluator().evaluate(node.getArguments()[0]);
+ if (argValue instanceof Map) {
+ ((Map)value).putAll((Map)argValue);
+ }
+ }
+ }
+
+ private PyEvaluator prepareEvaluator() {
+ PyEvaluator evaluator = createEvaluator();
+ evaluator.setNamespace(myEvaluationResult.myNamespace);
+ evaluator.setEvaluateCollectionItems(myEvaluateCollectionItems);
+ return evaluator;
+ }
+
+ protected PyEvaluator createEvaluator() {
+ return new PyPathEvaluator(myCurrentFilePath);
+ }
+
+ public Object getValue(String name) {
+ return myEvaluationResult.myNamespace.get(name);
+ }
+
+ @Nullable
+ public String getValueAsString(String name) {
+ Object value = myEvaluationResult.myNamespace.get(name);
+ return value instanceof String ? (String)value : null;
+ }
+
+ @Nullable
+ public List getValueAsList(String name) {
+ Object value = myEvaluationResult.myNamespace.get(name);
+ return value instanceof List ? (List)value : null;
+ }
+
+ @NotNull
+ public List<String> getValueAsStringList(String name) {
+ Object value = myEvaluationResult.myNamespace.get(name);
+ if (value instanceof List) {
+ List valueList = (List)value;
+ for (Object o : valueList) {
+ if (o != null && !(o instanceof String)) {
+ return Collections.emptyList();
+ }
+ }
+ return (List<String>)value;
+ }
+ if (value instanceof String) {
+ return Collections.singletonList((String)value);
+ }
+ return Collections.emptyList();
+ }
+
+ public Set<PyFile> getVisitedFiles() {
+ return myVisitedFiles;
+ }
+
+
+ public Object getReturnValue() {
+ return myReturnValue;
+ }
+
+ public void setEvaluateCollectionItems(boolean evaluateCollectionItems) {
+ myEvaluateCollectionItems = evaluateCollectionItems;
+ }
+
+ @NotNull
+ public List<PyExpression> getDeclarations(@NotNull final String name) {
+ return myEvaluationResult.getDeclarations(name);
+ }
+
+ /**
+ * @return so-called context. You may pass it to any instance of {@link com.jetbrains.python.psi.impl.blockEvaluator.PyBlockEvaluator}
+ * to make instances share their cache
+ */
+ @NotNull
+ public PyEvaluationContext getContext() {
+ return myContext;
+ }
+
+ private class MyPyElementVisitor extends PyElementVisitor {
+ @Override
+ public void visitPyAssignmentStatement(PyAssignmentStatement node) {
+ PyExpression expression = node.getLeftHandSideExpression();
+ if (expression instanceof PyTargetExpression) {
+ String name = expression.getName();
+ PyExpression value = ((PyTargetExpression)expression).findAssignedValue();
+ myEvaluationResult.myNamespace.put(name, prepareEvaluator().evaluate(value));
+ if (myDeclarationsToTrack.contains(name)) {
+ List<PyExpression> declarations = new ArrayList<PyExpression>();
+ PyPsiUtils.sequenceToList(declarations, value);
+ myEvaluationResult.myDeclarations.put(name, declarations);
+ }
+ }
+ else if (expression instanceof PySubscriptionExpression) {
+ PyExpression operand = ((PySubscriptionExpression)expression).getOperand();
+ PyExpression indexExpression = ((PySubscriptionExpression)expression).getIndexExpression();
+ if (operand instanceof PyReferenceExpression && ((PyReferenceExpression)operand).getQualifier() == null) {
+ Object currentValue = myEvaluationResult.myNamespace.get(((PyReferenceExpression)operand).getReferencedName());
+ if (currentValue instanceof Map) {
+ Object mapKey = prepareEvaluator().evaluate(indexExpression);
+ if (mapKey != null) {
+ Object value = myEvaluateCollectionItems ? prepareEvaluator().evaluate(node.getAssignedValue()) : node.getAssignedValue();
+ ((Map)currentValue).put(mapKey, value);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitPyAugAssignmentStatement(PyAugAssignmentStatement node) {
+ PyExpression target = node.getTarget();
+ String name = target.getName();
+ if (target instanceof PyReferenceExpression && !((PyReferenceExpression)target).isQualified() && name != null) {
+ Object currentValue = myEvaluationResult.myNamespace.get(name);
+ if (currentValue != null) {
+ Object rhs = prepareEvaluator().evaluate(node.getValue());
+ myEvaluationResult.myNamespace.put(name, prepareEvaluator().concatenate(currentValue, rhs));
+ }
+ if (myDeclarationsToTrack.contains(name)) {
+ List<PyExpression> declarations = myEvaluationResult.myDeclarations.get(name);
+ if (declarations != null) {
+ PyPsiUtils.sequenceToList(declarations, node.getValue());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitPyExpressionStatement(PyExpressionStatement node) {
+ node.getExpression().accept(this);
+ }
+
+ @Override
+ public void visitPyCallExpression(PyCallExpression node) {
+ PyExpression callee = node.getCallee();
+ if (callee instanceof PyReferenceExpression) {
+ PyReferenceExpression calleeRef = (PyReferenceExpression)callee;
+ PyExpression qualifier = calleeRef.getQualifier();
+ if (qualifier instanceof PyReferenceExpression) {
+ PyReferenceExpression qualifierRef = (PyReferenceExpression)qualifier;
+ if (!qualifierRef.isQualified()) {
+ if (PyNames.EXTEND.equals(calleeRef.getReferencedName()) && node.getArguments().length == 1) {
+ processExtendCall(node, qualifierRef.getReferencedName());
+ }
+ else if (PyNames.UPDATE.equals(calleeRef.getReferencedName()) && node.getArguments().length == 1) {
+ processUpdateCall(node, qualifierRef.getReferencedName());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitPyFromImportStatement(final PyFromImportStatement node) {
+ if (node.isFromFuture()) return;
+ final PsiElement source = PyUtil.turnDirIntoInit(node.resolveImportSource());
+ if (source instanceof PyFile) {
+ final PyFile pyFile = (PyFile)source;
+ PyEvaluationResult newlyEvaluatedResult = myContext.getCachedResult(pyFile);
+
+ if (newlyEvaluatedResult == null) {
+ final PyBlockEvaluator importEvaluator = new PyBlockEvaluator(myVisitedFiles, myContext);
+ importEvaluator.myDeclarationsToTrack.addAll(myDeclarationsToTrack);
+ importEvaluator.evaluate(pyFile);
+ newlyEvaluatedResult = importEvaluator.myEvaluationResult;
+ myContext.cache(pyFile, newlyEvaluatedResult);
+ }
+
+ if (node.isStarImport()) {
+ // TODO honor __all__ here
+ myEvaluationResult.myNamespace.putAll(newlyEvaluatedResult.myNamespace);
+ myEvaluationResult.myDeclarations.putAll(newlyEvaluatedResult.myDeclarations);
+ }
+ else {
+ for (final PyImportElement element : node.getImportElements()) {
+ final String nameOfVarInOurModule = element.getVisibleName();
+ final QualifiedName nameOfVarInExternalModule = element.getImportedQName();
+ if ((nameOfVarInOurModule == null) || (nameOfVarInExternalModule == null)) {
+ continue;
+ }
+
+ final Object value = newlyEvaluatedResult.myNamespace.get(nameOfVarInExternalModule.toString());
+ myEvaluationResult.myNamespace.put(nameOfVarInOurModule, value);
+ final List<PyExpression> declarations = newlyEvaluatedResult.getDeclarations(nameOfVarInOurModule);
+ if (myEvaluationResult.myDeclarations.containsKey(nameOfVarInOurModule)) {
+ myEvaluationResult.myDeclarations.get(nameOfVarInOurModule).addAll(declarations);
+ }
+ else {
+ myEvaluationResult.myDeclarations.put(nameOfVarInOurModule, declarations);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitPyIfStatement(PyIfStatement node) {
+ PyStatementList list = node.getIfPart().getStatementList();
+ if (list != null) {
+ list.acceptChildren(this);
+ }
+ }
+
+ @Override
+ public void visitPyReturnStatement(PyReturnStatement node) {
+ myReturnValue = prepareEvaluator().evaluate(node.getExpression());
+ }
+ }
+}
diff --git a/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationContext.java b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationContext.java
new file mode 100644
index 000000000000..ababfd56751d
--- /dev/null
+++ b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationContext.java
@@ -0,0 +1,42 @@
+package com.jetbrains.python.psi.impl.blockEvaluator;
+
+import com.jetbrains.python.psi.PyFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Cache for {@link com.jetbrains.python.psi.impl.blockEvaluator.PyBlockEvaluator}.
+ * You may obtain one via {@link PyBlockEvaluator#getContext()} and pass to ctor:
+ * {@link com.jetbrains.python.psi.impl.blockEvaluator.PyBlockEvaluator#PyBlockEvaluator(PyEvaluationContext)} to enable cache
+ *
+ * @author Ilya.Kazakevich
+ */
+public class PyEvaluationContext {
+ @NotNull
+ private final Map<PyFile, PyEvaluationResult> myResultMap = new HashMap<PyFile, PyEvaluationResult>();
+
+ PyEvaluationContext() {
+ }
+
+ /**
+ * Get evaluation result by file
+ * @param file file
+ * @return eval result
+ */
+ @Nullable
+ PyEvaluationResult getCachedResult(@NotNull final PyFile file) {
+ return myResultMap.get(file);
+ }
+
+ /**
+ * Store evaluation result by file
+ * @param file file
+ * @param result evaluation result
+ */
+ void cache(@NotNull final PyFile file, @NotNull final PyEvaluationResult result) {
+ myResultMap.put(file, result);
+ }
+}
diff --git a/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationResult.java b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationResult.java
new file mode 100644
index 000000000000..c28baf569f8b
--- /dev/null
+++ b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/PyEvaluationResult.java
@@ -0,0 +1,26 @@
+package com.jetbrains.python.psi.impl.blockEvaluator;
+
+import com.jetbrains.python.psi.PyExpression;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Ilya.Kazakevich
+ */
+@SuppressWarnings("PackageVisibleField") // Package-only class
+class PyEvaluationResult {
+ @NotNull
+ final Map<String, Object> myNamespace = new HashMap<String, Object>();
+ @NotNull
+ final Map<String, List<PyExpression>> myDeclarations = new HashMap<String, List<PyExpression>>();
+
+ @NotNull
+ List<PyExpression> getDeclarations(@NotNull final String name) {
+ final List<PyExpression> expressions = myDeclarations.get(name);
+ return (expressions != null) ? expressions : Collections.<PyExpression>emptyList();
+ }
+}
diff --git a/python/src/com/jetbrains/python/psi/impl/blockEvaluator/package-info.java b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/package-info.java
new file mode 100644
index 000000000000..c44fd5dfa346
--- /dev/null
+++ b/python/src/com/jetbrains/python/psi/impl/blockEvaluator/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Engine to evaluate block of python text.
+ * Use {@link com.jetbrains.python.psi.impl.blockEvaluator.PyBlockEvaluator} as entry point.
+ *
+ * @author Ilya.Kazakevich
+ */
+package com.jetbrains.python.psi.impl.blockEvaluator; \ No newline at end of file
diff --git a/python/src/com/jetbrains/python/psi/impl/stubs/PyDecoratorCallElementType.java b/python/src/com/jetbrains/python/psi/impl/stubs/PyDecoratorCallElementType.java
index 388d7977fb5a..9ad2fe32eab3 100644
--- a/python/src/com/jetbrains/python/psi/impl/stubs/PyDecoratorCallElementType.java
+++ b/python/src/com/jetbrains/python/psi/impl/stubs/PyDecoratorCallElementType.java
@@ -17,14 +17,16 @@ package com.jetbrains.python.psi.impl.stubs;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
-import com.jetbrains.python.psi.PyStubElementType;
+import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.PyDecorator;
+import com.jetbrains.python.psi.PyStubElementType;
import com.jetbrains.python.psi.impl.PyDecoratorImpl;
-import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.stubs.PyDecoratorStub;
+import com.jetbrains.python.psi.stubs.PyDecoratorStubIndex;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -34,7 +36,7 @@ import java.io.IOException;
* User: dcheryasov
* Date: Dec 18, 2008 9:09:57 PM
*/
-public class PyDecoratorCallElementType extends PyStubElementType<PyDecoratorStub, PyDecorator> {
+public class PyDecoratorCallElementType extends PyStubElementType<PyDecoratorStub, PyDecorator> {
public PyDecoratorCallElementType() {
super("DECORATOR_CALL");
}
@@ -55,10 +57,18 @@ public class PyDecoratorCallElementType extends PyStubElementType<PyDecoratorStu
QualifiedName.serialize(stub.getQualifiedName(), dataStream);
}
+ @Override
+ public void indexStub(@NotNull final PyDecoratorStub stub, @NotNull final IndexSink sink) {
+ // Index decorators stub by name (todo: index by FQDN as well!)
+ final QualifiedName qualifiedName = stub.getQualifiedName();
+ if (qualifiedName != null) {
+ sink.occurrence(PyDecoratorStubIndex.KEY, qualifiedName.toString());
+ }
+ }
+
@NotNull
public PyDecoratorStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
QualifiedName q_name = QualifiedName.deserialize(dataStream);
return new PyDecoratorStubImpl(q_name, parentStub);
}
-
}
diff --git a/python/src/com/jetbrains/python/psi/stubs/PyDecoratorStubIndex.java b/python/src/com/jetbrains/python/psi/stubs/PyDecoratorStubIndex.java
new file mode 100644
index 000000000000..0e7ea414cff0
--- /dev/null
+++ b/python/src/com/jetbrains/python/psi/stubs/PyDecoratorStubIndex.java
@@ -0,0 +1,24 @@
+package com.jetbrains.python.psi.stubs;
+
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import com.jetbrains.python.psi.PyDecorator;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Python Decorator stub index.
+ * Decorators are indexed by name
+ * @author Ilya.Kazakevich
+ */
+public class PyDecoratorStubIndex extends StringStubIndexExtension<PyDecorator> {
+ /**
+ * Key to search for python decorators
+ */
+ public static final StubIndexKey<String, PyDecorator> KEY = StubIndexKey.createIndexKey("Python.Decorator");
+
+ @NotNull
+ @Override
+ public StubIndexKey<String, PyDecorator> getKey() {
+ return KEY;
+ }
+}
diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
index dc63784e19aa..520c9b558881 100644
--- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java
@@ -21,8 +21,8 @@ import com.intellij.util.Function;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.AccessDirection;
+import com.jetbrains.python.psi.PyCallSiteExpression;
import com.jetbrains.python.psi.PyExpression;
-import com.jetbrains.python.psi.PyQualifiedExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import org.jetbrains.annotations.NotNull;
@@ -55,7 +55,7 @@ public class PyCallableTypeImpl implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return myReturnType;
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
index 778b8387f85e..34a92e16bf01 100644
--- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
@@ -316,7 +316,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return getReturnType(context);
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
index 229fe2677d12..bb58b68300e8 100644
--- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
+++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java
@@ -52,7 +52,7 @@ public class PyFunctionType implements PyCallableType {
@Nullable
@Override
- public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
+ public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return myCallable.getCallType(context, callSite);
}
diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
index f4a52368a047..9881d6cc106c 100644
--- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
+++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java
@@ -496,16 +496,9 @@ public class PyTypeChecker {
}
@Nullable
- public static AnalyzeCallResults analyzeCallSite(@Nullable PyQualifiedExpression callSite, @NotNull TypeEvalContext context) {
- if (callSite == null) {
- return null;
- }
- PsiElement parent = callSite.getParent();
- while (parent instanceof PyParenthesizedExpression) {
- parent = ((PyParenthesizedExpression)parent).getContainedExpression();
- }
- if (parent instanceof PyCallExpression) {
- return analyzeCall((PyCallExpression)parent, context);
+ public static AnalyzeCallResults analyzeCallSite(@Nullable PyCallSiteExpression callSite, @NotNull TypeEvalContext context) {
+ if (callSite instanceof PyCallExpression) {
+ return analyzeCall((PyCallExpression)callSite, context);
}
else if (callSite instanceof PyBinaryExpression) {
return analyzeCall((PyBinaryExpression)callSite, context);
diff --git a/python/src/com/jetbrains/python/remote/PySkeletonsPathAware.java b/python/src/com/jetbrains/python/remote/PySkeletonsPathAware.java
index 789d1ba17020..4cc21ed75c20 100644
--- a/python/src/com/jetbrains/python/remote/PySkeletonsPathAware.java
+++ b/python/src/com/jetbrains/python/remote/PySkeletonsPathAware.java
@@ -2,9 +2,22 @@ package com.jetbrains.python.remote;
/**
* @author traff
+ * @deprecated
*/
public interface PySkeletonsPathAware {
+ /**
+ * Use RemoteSdkProperties.getPathMappings() instead
+ * To be removed in IDEA 15
+ * @deprecated
+ */
+ @Deprecated
String getSkeletonsPath();
+ /**
+ * Use RemoteSdkProperties.getPathMappings() instead
+ * To be removed in IDEA 15
+ * @deprecated
+ */
+ @Deprecated
void setSkeletonsPath(String path);
}
diff --git a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
index b904b554570b..429be6c9197f 100644
--- a/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
+++ b/python/src/com/jetbrains/python/remote/PythonRemoteInterpreterManager.java
@@ -15,6 +15,7 @@
*/
package com.jetbrains.python.remote;
+import com.google.common.base.Function;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParamsGroup;
@@ -40,7 +41,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
-import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.List;
@@ -145,14 +145,16 @@ public abstract class PythonRemoteInterpreterManager {
public abstract SdkAdditionalData loadRemoteSdkData(Sdk sdk, Element additional);
- public abstract boolean testConnection(RemoteCredentials credentials);
-
public abstract PyConsoleProcessHandler createConsoleProcessHandler(Process process,
PyRemoteSdkCredentials data,
PythonConsoleView view,
PydevConsoleCommunication consoleCommunication,
String commandLine, Charset charset, PathMappingSettings settings);
+ @NotNull
+ public abstract RemoteSdkCredentialsProducer<PyRemoteSdkCredentials> getRemoteSdkCredentialsProducer(Function<RemoteCredentials, PyRemoteSdkCredentials> credentialsTransformer,
+ RemoteConnectionCredentialsWrapper connectionWrapper);
+
public static class PyRemoteInterpreterExecutionException extends ExecutionException {
public PyRemoteInterpreterExecutionException() {
@@ -167,15 +169,6 @@ public abstract class PythonRemoteInterpreterManager {
}
}
- @Nullable
- public abstract RemoteCredentials getVagrantRemoteCredentials(VagrantBasedCredentialsHolder data) throws IOException;
-
- public abstract boolean checkVagrantStatus(String vagrantFolder, boolean runIfDown);
-
public abstract void runVagrant(String vagrantFolder) throws ExecutionException;
-
- public abstract void checkVagrantStatus(VagrantBasedCredentialsHolder data);
-
- public abstract RemoteCredentials getCredentialsBySftpServerId(String id);
}
diff --git a/python/src/com/jetbrains/python/remote/RemoteProjectSettings.java b/python/src/com/jetbrains/python/remote/RemoteProjectSettings.java
index 424ea52bbff6..80d8697e6311 100644
--- a/python/src/com/jetbrains/python/remote/RemoteProjectSettings.java
+++ b/python/src/com/jetbrains/python/remote/RemoteProjectSettings.java
@@ -15,10 +15,12 @@
*/
package com.jetbrains.python.remote;
+import com.jetbrains.python.newProject.PyNewProjectSettings;
+
/**
* @author traff
*/
-public class RemoteProjectSettings {
+public class RemoteProjectSettings extends PyNewProjectSettings {
private String myDeploymentName;
private String myRemoteRoot;
diff --git a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
index d5ba031d6d67..168e8013d552 100644
--- a/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
+++ b/python/src/com/jetbrains/python/run/PyRemoteProcessStarter.java
@@ -74,7 +74,7 @@ public class PyRemoteProcessStarter {
try {
settings = manager.setupMappings(project, pyRemoteSdkAdditionalDataBase, settings);
- return manager.startRemoteProcess(project, pyRemoteSdkAdditionalDataBase.getRemoteSdkCredentials(), commandLine,
+ return manager.startRemoteProcess(project, pyRemoteSdkAdditionalDataBase.getRemoteSdkCredentials(true), commandLine,
settings);
}
catch (InterruptedException e) {
diff --git a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
index c3516dceaf4d..39fc2c909cf6 100644
--- a/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
+++ b/python/src/com/jetbrains/python/sdk/CreateVirtualEnvDialog.java
@@ -362,7 +362,7 @@ public class CreateVirtualEnvDialog extends IdeaDialog {
}
private void updateSdkList(final List<Sdk> allSdks, @Nullable Sdk initialSelection) {
- mySdkCombo.setRenderer(new PySdkListCellRenderer());
+ mySdkCombo.setRenderer(new PySdkListCellRenderer(false));
mySdkCombo.setModel(new CollectionComboBoxModel(allSdks, initialSelection));
checkValid();
}
diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
index 988622484b97..1a42621dde3d 100644
--- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
+++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java
@@ -23,17 +23,25 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.ListCellRendererWrapper;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.io.File;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class PySdkListCellRenderer extends ListCellRendererWrapper<Object> {
private final String myNullText;
private final Map<Sdk, SdkModificator> mySdkModifiers;
public static final String SEPARATOR = "separator";
- public PySdkListCellRenderer() {
+ final Pattern PYTHON_PATTERN = Pattern.compile("(\\d\\.?\\d\\.?\\d?)[ ]*\\(([^\\(\\)]*)\\)|(\\d\\.?\\d\\.?\\d?)[ ]*([^\\(\\)]*)");
+ private boolean isShortVersion;
+
+ public PySdkListCellRenderer(boolean shortVersion) {
+ isShortVersion = shortVersion;
myNullText = "";
mySdkModifiers = null;
}
@@ -50,13 +58,21 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper<Object> {
final PythonSdkFlavor flavor = PythonSdkFlavor.getPlatformIndependentFlavor(sdk.getHomePath());
final Icon icon = flavor != null ? flavor.getIcon() : ((SdkType)sdk.getSdkType()).getIcon();
- final String name;
+ String name;
if (mySdkModifiers != null && mySdkModifiers.containsKey(sdk)) {
name = mySdkModifiers.get(sdk).getName();
}
else {
name = sdk.getName();
}
+ if (name.startsWith("Remote")) name = name.substring(7);
+ final String flavorName = flavor == null ? "Python" : flavor.getName();
+ if (name.startsWith(flavorName)) name = name.substring(flavorName.length() + 1);
+
+ if (isShortVersion){
+ name = shortenName(name);
+ }
+
if (PythonSdkType.isInvalid(sdk)) {
setText("[invalid] " + name);
setIcon(wrapIconWithWarningDecorator(icon));
@@ -80,6 +96,28 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper<Object> {
setText(myNullText);
}
+ private String shortenName(@NotNull String name) {
+ final Matcher matcher = PYTHON_PATTERN.matcher(name);
+ if (matcher.matches()) {
+ String path = matcher.group(2);
+ if (path != null) {
+ name = matcher.group(1) + " at " + path;
+ }
+ else {
+ path = matcher.group(4);
+ final int index = path.lastIndexOf(File.separator);
+ if (index > 0) {
+ path = path.substring(index);
+ }
+ name = matcher.group(3) + " at ..." + path;
+ }
+ }
+ else if (new File(name).exists()) {
+ name = "..." + File.separator + new File(name).getParentFile().getParentFile().getName();
+ }
+ return name;
+ }
+
private static LayeredIcon wrapIconWithWarningDecorator(Icon icon) {
final LayeredIcon layered = new LayeredIcon(2);
layered.setIcon(icon, 0);
diff --git a/python/src/com/jetbrains/python/sdk/PySdkUtil.java b/python/src/com/jetbrains/python/sdk/PySdkUtil.java
index 60a4c5bb0323..8f2b62b1b414 100644
--- a/python/src/com/jetbrains/python/sdk/PySdkUtil.java
+++ b/python/src/com/jetbrains/python/sdk/PySdkUtil.java
@@ -57,8 +57,6 @@ public class PySdkUtil {
// Windows EOF marker, Ctrl+Z
public static final int SUBSTITUTE = 26;
- private static final String REMOTE_SOURCES_DIR_NAME = "remote_sources";
-
private PySdkUtil() {
// explicitly none
}
@@ -243,7 +241,7 @@ public class PySdkUtil {
String basePath = PathManager.getSystemPath();
return basePath +
File.separator +
- REMOTE_SOURCES_DIR_NAME +
+ PythonSdkType.REMOTE_SOURCES_DIR_NAME +
sep +
FileUtil.toSystemIndependentName(sdkHome).hashCode() +
sep;
@@ -255,8 +253,8 @@ public class PySdkUtil {
}
@Nullable
- public static VirtualFile findRemoteLibrariesDir(@NotNull final Sdk sdk) {
- return findLibraryDir(sdk, REMOTE_SOURCES_DIR_NAME, OrderRootType.CLASSES);
+ public static VirtualFile findAnyRemoteLibrary(@NotNull final Sdk sdk) {
+ return findLibraryDir(sdk, PythonSdkType.REMOTE_SOURCES_DIR_NAME, OrderRootType.CLASSES);
}
private static VirtualFile findLibraryDir(Sdk sdk, String dirName, OrderRootType rootType) {
diff --git a/python/src/com/jetbrains/python/sdk/PythonEnvUtil.java b/python/src/com/jetbrains/python/sdk/PythonEnvUtil.java
index ad860f7e30ee..0f448886290c 100644
--- a/python/src/com/jetbrains/python/sdk/PythonEnvUtil.java
+++ b/python/src/com/jetbrains/python/sdk/PythonEnvUtil.java
@@ -86,9 +86,4 @@ public class PythonEnvUtil {
public static void addToPythonPath(@NotNull Map<String, String> env, String value) {
addPathToEnv(env, PYTHONPATH, value);
}
-
- public static List<String> getPathListFromEnv(@NotNull Map<String, String> env, String envKey) {
- String pythonPath = env.get(envKey);
- return pythonPath != null ? Lists.newArrayList(pythonPath.split(File.pathSeparator)) : null;
- }
}
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
index a51d8e29c5a1..5e3506b9e4c5 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java
@@ -56,9 +56,7 @@ import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.reference.SoftReference;
-import com.intellij.remote.RemoteSdkCredentials;
-import com.intellij.remote.RemoteSdkCredentialsHolder;
-import com.intellij.remote.VagrantNotStartedException;
+import com.intellij.remote.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.NullableConsumer;
@@ -71,10 +69,10 @@ import com.jetbrains.python.facet.PythonFacetSettings;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.search.PyProjectScopeBuilder;
+import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import com.jetbrains.python.sdk.flavors.CPythonSdkFlavor;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
-import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher;
import icons.PythonIcons;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -96,6 +94,7 @@ import java.util.regex.Pattern;
* @author yole
*/
public class PythonSdkType extends SdkType {
+ public static final String REMOTE_SOURCES_DIR_NAME = "remote_sources";
private static final Logger LOG = Logger.getInstance("#" + PythonSdkType.class.getName());
private static final String[] WINDOWS_EXECUTABLE_SUFFIXES = new String[]{"cmd", "exe", "bat", "com"};
@@ -143,12 +142,9 @@ public class PythonSdkType extends SdkType {
*/
@NotNull
@NonNls
- public static String getBuiltinsFileName(Sdk sdk) {
- final String version = sdk.getVersionString();
- if (version != null && version.startsWith("Python 3")) {
- return PyBuiltinCache.BUILTIN_FILE_3K;
- }
- return PyBuiltinCache.BUILTIN_FILE;
+ public static String getBuiltinsFileName(@NotNull Sdk sdk) {
+ final LanguageLevel level = getLanguageLevelForSdk(sdk);
+ return level.isOlderThan(LanguageLevel.PYTHON30) ? PyBuiltinCache.BUILTIN_FILE : PyBuiltinCache.BUILTIN_FILE_3K;
}
@NonNls
@@ -241,6 +237,15 @@ public class PythonSdkType extends SdkType {
return PySdkUtil.isRemote(sdk);
}
+ public static boolean isVagrant(@Nullable Sdk sdk) {
+ if (sdk != null && sdk.getSdkAdditionalData() instanceof PyRemoteSdkAdditionalDataBase) {
+ PyRemoteSdkAdditionalDataBase data = (PyRemoteSdkAdditionalDataBase) sdk.getSdkAdditionalData();
+
+ return data.getRemoteConnectionType() == CredentialsType.VAGRANT;
+ }
+ return false;
+ }
+
public static boolean isRemote(@Nullable String sdkPath) {
return isRemote(findSdkByPath(sdkPath));
}
@@ -554,11 +559,11 @@ public class PythonSdkType extends SdkType {
public void run(@NotNull ProgressIndicator indicator) {
try {
final String skeletonsPath = getSkeletonsPath(PathManager.getSystemPath(), sdk.getHomePath());
- PySkeletonRefresher.refreshSkeletonsOfSdk(project, ownerComponent, skeletonsPath, null, sdk);
+ PythonSdkUpdater.updateSdk(project, ownerComponent, sdk, skeletonsPath);
}
catch (InvalidSdkException e) {
// If the SDK is invalid, the user should worry about the SDK itself, not about skeletons generation errors
- if (isRemote(sdk)) {
+ if (isVagrant(sdk)) {
notifyRemoteSdkSkeletonsFail(e, new Runnable() {
@Override
public void run() {
@@ -647,9 +652,6 @@ public class PythonSdkType extends SdkType {
}
}
}
- else {
- addRemoteLibrariesRoot(sdkModificator, sdkHome);
- }
PyUserSkeletonsUtil.addUserSkeletonsRoot(sdkModificator);
addSkeletonsRoot(sdkModificator, sdkHome);
@@ -699,14 +701,6 @@ public class PythonSdkType extends SdkType {
sdkModificator.addRoot(builtins_root, BUILTIN_ROOT_TYPE);
}
- private static void addRemoteLibrariesRoot(@NotNull SdkModificator sdkModificator, String sdkHome) {
- @NonNls final String librariesRoot = PySdkUtil.getRemoteSourcesLocalPath(sdkHome);
- new File(librariesRoot).mkdirs();
- final VirtualFile remoteLibraries = LocalFileSystem.getInstance().refreshAndFindFileByPath(librariesRoot);
- assert remoteLibraries != null : "Cannot find remote libraries path " + librariesRoot + " in VFS";
- sdkModificator.addRoot(remoteLibraries, OrderRootType.CLASSES);
- }
-
protected static void addHardcodedPaths(SdkModificator sdkModificator) {
// Add python-django installed as package in Linux
// NOTE: fragile and arbitrary
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
index f583ebb7a893..b4b968fdb108 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
@@ -15,6 +15,8 @@
*/
package com.jetbrains.python.sdk;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -30,16 +32,22 @@ import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.startup.StartupActivity;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil;
+import com.jetbrains.python.remote.PyRemoteSdkAdditionalDataBase;
import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import java.awt.*;
import java.io.File;
import java.util.*;
+import java.util.List;
/**
* A component that initiates a refresh of all project's Python SDKs.
@@ -91,56 +99,75 @@ public class PythonSdkUpdater implements StartupActivity {
// NOTE: everything is run later on the AWT thread
if (!sdksToUpdate.isEmpty()) {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- public void run() {
- if (delay > 0) {
- try {
- Thread.sleep(delay); // wait until all short-term disk-hitting activity ceases
- }
- catch (InterruptedException ignore) {
- }
+ updateSdks(project, delay, sdksToUpdate);
+ }
+ }
+
+ private void updateSdks(final Project project, final int delay, final Set<Sdk> sdksToUpdate) {
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ public void run() {
+ if (delay > 0) {
+ try {
+ Thread.sleep(delay); // wait until all short-term disk-hitting activity ceases
+ }
+ catch (InterruptedException ignore) {
}
- // update skeletons
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- ProgressManager.getInstance().run(new Task.Backgroundable(project, PyBundle.message("sdk.gen.updating.skels"), false) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- for (final Sdk sdk : sdksToUpdate) {
- try {
- LOG.info("Performing background update of skeletons for SDK " + sdk.getHomePath());
- updateSdk(project, sdk);
+ }
+ // update skeletons
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ ProgressManager.getInstance().run(new Task.Backgroundable(project, PyBundle.message("sdk.gen.updating.skels"), false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ for (final Sdk sdk : sdksToUpdate) {
+ try {
+ LOG.info("Performing background update of skeletons for SDK " + sdk.getHomePath());
+ updateSdk(project, null, sdk, PythonSdkType.findSkeletonsPath(sdk));
+ }
+ catch (InvalidSdkException e) {
+ if (PythonSdkType.isVagrant(sdk)) {
+ PythonSdkType.notifyRemoteSdkSkeletonsFail(e, new Runnable() {
+ @Override
+ public void run() {
+ updateSdks(project, delay, Sets.newHashSet(sdk));
+ }
+ });
}
- catch (InvalidSdkException e) {
- if (PythonSdkType.isRemote(sdk)) {
- PythonSdkType.notifyRemoteSdkSkeletonsFail(e, new Runnable() {
- @Override
- public void run() {
- updateActiveSdks(project, delay);
- }
- });
- }
- else if (!PythonSdkType.isInvalid(sdk)) {
- LOG.error(e);
- }
+ else if (!PythonSdkType.isInvalid(sdk)) {
+ LOG.error(e);
}
- myAlreadyUpdated.add(sdk.getHomePath());
}
+ myAlreadyUpdated.add(sdk.getHomePath());
}
- });
- }
- });
- }
- });
- }
+ }
+ });
+ }
+ });
+ }
+ });
}
- private static void updateSdk(@NotNull Project project, @NotNull final Sdk sdk) throws InvalidSdkException {
- PySkeletonRefresher.refreshSkeletonsOfSdk(project, sdk); // NOTE: whole thing would need a rename
+ public static void updateSdk(@Nullable Project project, @Nullable Component ownerComponent, @NotNull final Sdk sdk, String skeletonsPath) throws InvalidSdkException {
+ PySkeletonRefresher.refreshSkeletonsOfSdk(project, ownerComponent, skeletonsPath, new Ref<Boolean>(false), sdk); // NOTE: whole thing would need a rename
if (!PySdkUtil.isRemote(sdk)) {
updateSysPath(sdk);
}
+ else {
+ PyRemoteSdkAdditionalDataBase remoteSdkData = (PyRemoteSdkAdditionalDataBase)sdk.getSdkAdditionalData();
+ assert remoteSdkData != null;
+ final List<String> paths = Lists.newArrayList();
+ for (PathMappingSettings.PathMapping mapping : remoteSdkData.getPathMappings().getPathMappings()) {
+ paths.add(mapping.getLocalRoot());
+ }
+
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ updateSdkPath(sdk, paths);
+ }
+ });
+ }
}
private static void updateSysPath(@NotNull final Sdk sdk) throws InvalidSdkException {
diff --git a/python/src/com/jetbrains/python/sdk/flavors/IronPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/IronPythonSdkFlavor.java
index 450dff40c013..51b9ffd1cb2f 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/IronPythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/IronPythonSdkFlavor.java
@@ -17,17 +17,22 @@ package com.jetbrains.python.sdk.flavors;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PatternUtil;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
import java.util.*;
+import java.util.regex.Pattern;
/**
* @author yole
*/
public class IronPythonSdkFlavor extends PythonSdkFlavor {
+ public static final Pattern VERSION_RE = Pattern.compile("\\w+ ([0-9\\.]+).*");
+
private IronPythonSdkFlavor() {
}
@@ -64,13 +69,11 @@ public class IronPythonSdkFlavor extends PythonSdkFlavor {
return name.equals("ipy.exe") || name.equals("ipy64.exe");
}
- public String getVersionStringFromOutput(String version) {
- return getName() + " " + version;
- }
-
+ @Nullable
@Override
- public String getVersionRegexp() {
- return "\\w+ ([0-9\\.]+).*";
+ public String getVersionStringFromOutput(@NotNull String output) {
+ final String match = PatternUtil.getFirstMatch(Arrays.asList(StringUtil.splitByLines(output)), VERSION_RE);
+ return match != null ? getName() + " " + match : null;
}
@Override
diff --git a/python/src/com/jetbrains/python/sdk/flavors/JythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/JythonSdkFlavor.java
index 882d82b022bb..4b0fa93b329d 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/JythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/JythonSdkFlavor.java
@@ -19,19 +19,24 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PatternUtil;
import com.jetbrains.python.run.PythonCommandLineState;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
+import java.util.regex.Pattern;
/**
* @author yole
*/
public class JythonSdkFlavor extends PythonSdkFlavor {
+ private static final Pattern VERSION_RE = Pattern.compile("(Jython \\S+)( on .*)?");
private static final String JYTHONPATH = "JYTHONPATH";
private static final String PYTHON_PATH_PREFIX = "-Dpython.path=";
@@ -44,9 +49,10 @@ public class JythonSdkFlavor extends PythonSdkFlavor {
return FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("jython");
}
+ @Nullable
@Override
- public String getVersionRegexp() {
- return "(Jython \\S+)( on .*)?";
+ public String getVersionStringFromOutput(@NotNull String output) {
+ return PatternUtil.getFirstMatch(Arrays.asList(StringUtil.splitByLines(output)), VERSION_RE);
}
@Override
diff --git a/python/src/com/jetbrains/python/sdk/flavors/PyPySdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PyPySdkFlavor.java
index d857e45a9ee7..eb35d3fd6ce6 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/PyPySdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/PyPySdkFlavor.java
@@ -18,29 +18,53 @@ package com.jetbrains.python.sdk.flavors;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PatternUtil;
import com.jetbrains.python.psi.LanguageLevel;
import icons.PythonIcons;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
+import java.util.Arrays;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* @author traff
*/
public class PyPySdkFlavor extends PythonSdkFlavor {
+ public static PyPySdkFlavor INSTANCE = new PyPySdkFlavor();
+
+ private static final Pattern VERSION_RE = Pattern.compile("\\[(PyPy \\S+).*\\]");
+ private static final Pattern PYTHON_VERSION_RE = Pattern.compile("(Python \\S+).*");
+ private static final Pattern VERSION_STRING_RE = Pattern.compile("PyPy (\\S+)( \\[Python (\\S+)\\])?");
+
private PyPySdkFlavor() {
}
- public static PyPySdkFlavor INSTANCE = new PyPySdkFlavor();
-
public boolean isValidSdkPath(@NotNull File file) {
return FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("pypy");
}
- public String getVersionRegexp() {
- return "\\[(PyPy \\S+).*\\]";
+ @Nullable
+ @Override
+ public String getVersionStringFromOutput(@NotNull String output) {
+ final List<String> lines = Arrays.asList(StringUtil.splitByLines(output));
+ final String version = PatternUtil.getFirstMatch(lines, VERSION_RE);
+ final String pythonVersion = PatternUtil.getFirstMatch(lines, PYTHON_VERSION_RE);
+ if (version != null) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(version);
+ if (pythonVersion != null) {
+ builder.append(" [");
+ builder.append(pythonVersion);
+ builder.append("]");
+ }
+ return builder.toString();
+ }
+ return null;
}
public String getVersionOption() {
@@ -55,11 +79,19 @@ public class PyPySdkFlavor extends PythonSdkFlavor {
@Override
public LanguageLevel getLanguageLevel(Sdk sdk) {
- final String version = sdk.getVersionString();
- final String prefix = getName() + " ";
- if (version != null && version.startsWith(prefix)) {
- String pypyVersion = version.substring(prefix.length());
- return LanguageLevel.fromPythonVersion(getPythonVersion(pypyVersion));
+ final String versionString = sdk.getVersionString();
+ if (versionString != null) {
+ final Matcher matcher = VERSION_STRING_RE.matcher(versionString);
+ if (matcher.matches()) {
+ final String version = matcher.group(1);
+ final String pythonVersion = matcher.group(3);
+ if (pythonVersion != null) {
+ return LanguageLevel.fromPythonVersion(pythonVersion);
+ }
+ else if (version != null) {
+ return LanguageLevel.fromPythonVersion(getPythonVersion(version));
+ }
+ }
}
return LanguageLevel.getDefault();
}
diff --git a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java
index ec255b5c668f..4edac44956d3 100644
--- a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java
+++ b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java
@@ -45,6 +45,7 @@ import java.util.regex.Pattern;
* @author yole
*/
public abstract class PythonSdkFlavor {
+ private static final Pattern VERSION_RE = Pattern.compile("(Python \\S+).*");
private static final Logger LOG = Logger.getInstance(PythonSdkFlavor.class);
public static Collection<String> appendSystemPythonPath(@NotNull Collection<String> pythonPath) {
@@ -158,53 +159,40 @@ public abstract class PythonSdkFlavor {
return FileUtil.getNameWithoutExtension(file).toLowerCase().startsWith("python");
}
- public String getVersionString(String sdkHome) {
- return getVersionStringFromOutput(getVersionFromOutput(sdkHome, getVersionOption(), getVersionRegexp()));
- }
-
- public String getVersionStringFromOutput(String version) {
- return version;
- }
-
-
- public String getVersionRegexp() {
- return "(Python \\S+).*";
- }
-
- public String getVersionOption() {
- return "-V";
- }
-
- @Nullable
- public String getVersionFromOutput(ProcessOutput processOutput) {
- return getVersionFromOutput(getVersionRegexp(), processOutput);
- }
-
@Nullable
- protected static String getVersionFromOutput(String sdkHome, String versionOpt, String versionRegexp) {
- String runDirectory = new File(sdkHome).getParent();
- final ProcessOutput processOutput = PySdkUtil.getProcessOutput(runDirectory, new String[]{sdkHome, versionOpt}, 10000);
-
- return getVersionFromOutput(versionRegexp, processOutput);
+ public String getVersionString(@Nullable String sdkHome) {
+ if (sdkHome == null) {
+ return null;
+ }
+ final String runDirectory = new File(sdkHome).getParent();
+ final ProcessOutput processOutput = PySdkUtil.getProcessOutput(runDirectory, new String[]{sdkHome, getVersionOption()}, 10000);
+ return getVersionStringFromOutput(processOutput);
}
@Nullable
- private static String getVersionFromOutput(String version_regexp, ProcessOutput process_output) {
- if (process_output.getExitCode() != 0) {
- String err = process_output.getStderr();
- if (StringUtil.isEmpty(err)) {
- err = process_output.getStdout();
+ public String getVersionStringFromOutput(@NotNull ProcessOutput processOutput) {
+ if (processOutput.getExitCode() != 0) {
+ String errors = processOutput.getStderr();
+ if (StringUtil.isEmpty(errors)) {
+ errors = processOutput.getStdout();
}
- LOG.warn("Couldn't get interpreter version: process exited with code " + process_output.getExitCode() + "\n" + err
- );
+ LOG.warn("Couldn't get interpreter version: process exited with code " + processOutput.getExitCode() + "\n" + errors);
return null;
}
- Pattern pattern = Pattern.compile(version_regexp);
- final String result = PatternUtil.getFirstMatch(process_output.getStderrLines(), pattern);
+ final String result = getVersionStringFromOutput(processOutput.getStderr());
if (result != null) {
return result;
}
- return PatternUtil.getFirstMatch(process_output.getStdoutLines(), pattern);
+ return getVersionStringFromOutput(processOutput.getStdout());
+ }
+
+ @Nullable
+ public String getVersionStringFromOutput(@NotNull String output) {
+ return PatternUtil.getFirstMatch(Arrays.asList(StringUtil.splitByLines(output)), VERSION_RE);
+ }
+
+ public String getVersionOption() {
+ return "-V";
}
public Collection<String> getExtraDebugOptions() {
diff --git a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
index 13202d7a39c7..284a125e8736 100644
--- a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
+++ b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
@@ -237,7 +237,7 @@ public class PySkeletonRefresher {
final VirtualFile userSkeletonsDir = PyUserSkeletonsUtil.getUserSkeletonsDirectory();
final File userSkeletons = userSkeletonsDir != null ? new File(userSkeletonsDir.getPath()) : null;
- final VirtualFile remoteSourcesDir = PySdkUtil.findRemoteLibrariesDir(sdk);
+ final VirtualFile remoteSourcesDir = PySdkUtil.findAnyRemoteLibrary(sdk);
final File remoteSources = remoteSourcesDir != null ? new File(remoteSourcesDir.getPath()) : null;
final VirtualFile[] classDirs = sdk.getRootProvider().getFiles(OrderRootType.CLASSES);
diff --git a/python/src/com/jetbrains/python/spellchecker/python.dic b/python/src/com/jetbrains/python/spellchecker/python.dic
index edcc8d6156bf..d486a4f1ba34 100644
--- a/python/src/com/jetbrains/python/spellchecker/python.dic
+++ b/python/src/com/jetbrains/python/spellchecker/python.dic
@@ -1072,6 +1072,7 @@ itemcget
itemconfigure
itemgetter
itemre
+iter
iterable
iterdecode
iterdump
@@ -1264,6 +1265,7 @@ memp
memset
menubutton
menudefs
+metaclass
metas
metastrings
metavar
diff --git a/python/src/com/jetbrains/python/spellchecker/pythonExtras.dic b/python/src/com/jetbrains/python/spellchecker/pythonExtras.dic
index 18bb40e346d9..6db6fb3fd2e0 100644
--- a/python/src/com/jetbrains/python/spellchecker/pythonExtras.dic
+++ b/python/src/com/jetbrains/python/spellchecker/pythonExtras.dic
@@ -1,3 +1,4 @@
+cinit
rtype
tuple
tuples
diff --git a/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java b/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java
index f0702937f732..f8b4adde5b33 100644
--- a/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java
+++ b/python/src/com/jetbrains/python/statistics/PyPackageUsagesCollector.java
@@ -30,8 +30,10 @@ import com.jetbrains.python.packaging.PyRequirement;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
/**
* @author yole
@@ -51,13 +53,7 @@ public class PyPackageUsagesCollector extends AbstractApplicationUsagesCollector
public void run() {
List<PyRequirement> requirements = PyPackageManagerImpl.getRequirements(m);
if (requirements != null) {
- Collection<String> packages;
- try {
- packages = new HashSet<String>(PyPIPackageUtil.INSTANCE.getPackageNames());
- }
- catch (IOException e) {
- return;
- }
+ Collection<String> packages = new HashSet<String>(PyPIPackageUtil.INSTANCE.getPackageNames());
for (PyRequirement requirement : requirements) {
String name = requirement.getName();
if (packages.contains(name)) {
diff --git a/python/src/com/jetbrains/python/testing/PyRerunFailedTestsAction.java b/python/src/com/jetbrains/python/testing/PyRerunFailedTestsAction.java
index 2e92a0e52022..cc468c5e40ac 100644
--- a/python/src/com/jetbrains/python/testing/PyRerunFailedTestsAction.java
+++ b/python/src/com/jetbrains/python/testing/PyRerunFailedTestsAction.java
@@ -23,14 +23,11 @@ import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.AbstractTestProxy;
-import com.intellij.execution.testframework.Filter;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction;
-import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentContainer;
-import com.intellij.psi.search.GlobalSearchScope;
import com.jetbrains.python.run.AbstractPythonRunConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -131,15 +128,4 @@ public class PyRerunFailedTestsAction extends AbstractRerunFailedTestsAction {
passParentEnvs);
}
}
-
- @NotNull
- @Override
- protected Filter getFilter(Project project, GlobalSearchScope searchScope) {
- return new Filter() {
- public boolean shouldAccept(final AbstractTestProxy test) {
- boolean ignored = (test.getMagnitude() == TestStateInfo.Magnitude.IGNORED_INDEX.getValue());
- return !ignored && (test.isInterrupted() || test.isDefect());
- }
- };
- }
}
diff --git a/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java b/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
index 69d1ce01dd2a..9d763e2ce286 100644
--- a/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
+++ b/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
@@ -133,7 +133,7 @@ public class VFSTestFrameworkListener implements ApplicationComponent {
}
final PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(sdk);
try {
- return packageManager.findPackage(testPackageName) != null;
+ return packageManager.findInstalledPackage(testPackageName) != null;
}
catch (PyExternalProcessException e) {
LOG.info("Can't load package list " + e.getMessage());
diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java
index 51a28eefbbd0..f988dbd315e6 100644
--- a/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java
+++ b/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java
@@ -99,7 +99,7 @@ public class PyTestConfigurationProducer extends PythonTestConfigurationProducer
if (pyClass != null) {
final PyPackageManagerImpl packageManager = (PyPackageManagerImpl)PyPackageManager.getInstance(sdk);
try {
- final PyPackage pytestPackage = packageManager.findPackage("pytest");
+ final PyPackage pytestPackage = packageManager.findInstalledPackage("pytest");
if (pytestPackage != null && PackageVersionComparator.VERSION_COMPARATOR.compare(pytestPackage.getVersion(), "2.3.3") >= 0) {
keywords = pyClass.getName() + " and " + keywords;
}
diff --git a/python/testData/inspections/PyCallingNonCallableInspection/callDictSubscriptionExpression.py b/python/testData/inspections/PyCallingNonCallableInspection/callDictSubscriptionExpression.py
new file mode 100644
index 000000000000..4c6d7657d59d
--- /dev/null
+++ b/python/testData/inspections/PyCallingNonCallableInspection/callDictSubscriptionExpression.py
@@ -0,0 +1,4 @@
+ops = {'and': all, 'or': any}
+op = ops['or']
+ops['and']()
+op()
diff --git a/python/testData/inspections/PyCallingNonCallableInspection/localCallableClass.py b/python/testData/inspections/PyCallingNonCallableInspection/localCallableClass.py
new file mode 100644
index 000000000000..de03229331e0
--- /dev/null
+++ b/python/testData/inspections/PyCallingNonCallableInspection/localCallableClass.py
@@ -0,0 +1,7 @@
+class Callable(object):
+ pass
+
+
+def f(g):
+ if callable(g):
+ g()
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/a.py b/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/a.py
new file mode 100644
index 000000000000..baae7fc5fe65
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/a.py
@@ -0,0 +1,4 @@
+from library import foo,<error descr="Unresolved reference 'bar'">bar</error>
+
+
+print(foo) \ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/library.py b/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/library.py
new file mode 100644
index 000000000000..048ea67a76d9
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/OneUnsedOneMarked/library.py
@@ -0,0 +1 @@
+foo = 0 \ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/Py3CompletionTest.java b/python/testSrc/com/jetbrains/python/Py3CompletionTest.java
index 646f17c42d92..1409ff490005 100644
--- a/python/testSrc/com/jetbrains/python/Py3CompletionTest.java
+++ b/python/testSrc/com/jetbrains/python/Py3CompletionTest.java
@@ -52,6 +52,14 @@ public class Py3CompletionTest extends PyTestCase {
doTest();
}
+ // PY-13157
+ public void testMetaClass() {
+ doTestByText("class C(meta<caret>):\n" +
+ " pass\n");
+ myFixture.checkResult("class C(metaclass=):\n" +
+ " pass\n");
+ }
+
private void doTest() {
CamelHumpMatcher.forceStartMatching(getTestRootDisposable());
final String testName = "completion/" + getTestName(true);
@@ -59,4 +67,10 @@ public class Py3CompletionTest extends PyTestCase {
myFixture.completeBasic();
myFixture.checkResultByFile(testName + ".after.py");
}
+
+ private List<String> doTestByText(String text) {
+ myFixture.configureByText(PythonFileType.INSTANCE, text);
+ myFixture.completeBasic();
+ return myFixture.getLookupElementStrings();
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java b/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java
index 368c05556ef0..75665ac3dbe3 100644
--- a/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java
+++ b/python/testSrc/com/jetbrains/python/PyBlockEvaluatorTest.java
@@ -21,7 +21,7 @@ import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyStringLiteralExpression;
import com.jetbrains.python.psi.PyUtil;
-import com.jetbrains.python.psi.impl.PyBlockEvaluator;
+import com.jetbrains.python.psi.impl.blockEvaluator.PyBlockEvaluator;
import org.junit.Assert;
import java.util.ArrayList;
diff --git a/python/testSrc/com/jetbrains/python/PySdkFlavorTest.java b/python/testSrc/com/jetbrains/python/PySdkFlavorTest.java
new file mode 100644
index 000000000000..e934eb90e9d7
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/PySdkFlavorTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python;
+
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
+import com.jetbrains.python.fixtures.PyTestCase;
+import com.jetbrains.python.psi.LanguageLevel;
+import com.jetbrains.python.sdk.PythonSdkAdditionalData;
+import com.jetbrains.python.sdk.PythonSdkType;
+import com.jetbrains.python.sdk.flavors.JythonSdkFlavor;
+import com.jetbrains.python.sdk.flavors.PyPySdkFlavor;
+import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
+import com.jetbrains.python.sdk.flavors.UnixPythonSdkFlavor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author vlan
+ */
+public class PySdkFlavorTest extends PyTestCase {
+ public void testPython27VersionString() {
+ final PythonSdkFlavor flavor = UnixPythonSdkFlavor.INSTANCE;
+ final String versionOutput = "Python 2.7.6\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("Python 2.7.6", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON27, flavor.getLanguageLevel(mockSdk));
+ }
+
+ public void testPython34VersionString() {
+ final PythonSdkFlavor flavor = UnixPythonSdkFlavor.INSTANCE;
+ final String versionOutput = "Python 3.4.0\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("Python 3.4.0", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON34, flavor.getLanguageLevel(mockSdk));
+ }
+
+ public void testJython25VersionString() {
+ final PythonSdkFlavor flavor = JythonSdkFlavor.INSTANCE;
+ final String versionOutput = "Jython 2.5.3\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("Jython 2.5.3", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON25, flavor.getLanguageLevel(mockSdk));
+ }
+
+ public void testJython25WithWarningsVersionString() {
+ final PythonSdkFlavor flavor = JythonSdkFlavor.INSTANCE;
+ final String versionOutput = "\"my\" variable $jythonHome masks earlier declaration in same scope at /usr/bin/jython line 15.\n" +
+ "Jython 2.5.3\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("Jython 2.5.3", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON25, flavor.getLanguageLevel(mockSdk));
+ }
+
+ public void testPyPy23VersionString() {
+ final PythonSdkFlavor flavor = PyPySdkFlavor.INSTANCE;
+ final String versionOutput = "Python 2.7.6 (32f35069a16d819b58c1b6efb17c44e3e53397b2, Jun 10 2014, 00:42:27)\n" +
+ "[PyPy 2.3.1 with GCC 4.8.2]\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("PyPy 2.3.1 [Python 2.7.6]", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON27, flavor.getLanguageLevel(mockSdk));
+ assertEquals("__builtin__.py", PythonSdkType.getBuiltinsFileName(mockSdk));
+ }
+
+ public void testPyPy323VersionString() {
+ final PythonSdkFlavor flavor = PyPySdkFlavor.INSTANCE;
+ final String versionOutput = "Python 3.2.5 (986752d005bb6c65ce418113e4c3cd115f61a9b4, Jun 23 2014, 00:23:34)\n" +
+ "[PyPy 2.3.1 with GCC 4.8.2]\n";
+ final Sdk mockSdk = createMockSdk(flavor, versionOutput);
+ assertEquals("PyPy 2.3.1 [Python 3.2.5]", mockSdk.getVersionString());
+ assertEquals(LanguageLevel.PYTHON32, flavor.getLanguageLevel(mockSdk));
+ assertEquals("builtins.py", PythonSdkType.getBuiltinsFileName(mockSdk));
+ }
+
+ // TODO: Add tests for MayaPy and IronPython SDK flavors
+
+ @NotNull
+ private static Sdk createMockSdk(@NotNull PythonSdkFlavor flavor, @NotNull String versionOutput) {
+ final String versionString = flavor.getVersionStringFromOutput(versionOutput);
+ final ProjectJdkImpl sdk = new ProjectJdkImpl("Test", PythonSdkType.getInstance(), "/path/to/sdk", versionString);
+ sdk.setSdkAdditionalData(new PythonSdkAdditionalData(flavor));
+ return sdk;
+ }
+}
diff --git a/python/testSrc/com/jetbrains/python/PythonAutoPopupTest.java b/python/testSrc/com/jetbrains/python/PythonAutoPopupTest.java
index 6daf6dee059c..0df52f86f14d 100644
--- a/python/testSrc/com/jetbrains/python/PythonAutoPopupTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonAutoPopupTest.java
@@ -18,6 +18,7 @@ package com.jetbrains.python;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.testFramework.fixtures.CompletionAutoPopupTester;
import com.jetbrains.python.fixtures.PyTestCase;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
@@ -39,7 +40,7 @@ public class PythonAutoPopupTest extends PyTestCase {
}
@Override
- protected void invokeTestRunnable(Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
myTester.runWithAutoPopupEnabled(runnable);
}
diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
index da7888e80332..b57ae35baa17 100644
--- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
+++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java
@@ -606,4 +606,13 @@ public class PythonCompletionTest extends PyTestCase {
myFixture.checkResult("bar = {'a': '1'}\n" +
"print bar<caret>['a']");
}
+
+ // PY-1860
+ public void testDunderMetaClass() {
+ doTestByText("class C(object):\n" +
+ " __meta<caret>\n");
+ myFixture.checkResult("class C(object):\n" +
+ " __metaclass__ = \n");
+
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
index 3404194efd65..6850c3b049a8 100644
--- a/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
+++ b/python/testSrc/com/jetbrains/python/fixtures/PyTestCase.java
@@ -16,13 +16,14 @@
package com.jetbrains.python.fixtures;
import com.intellij.openapi.application.PathManager;
-import com.intellij.openapi.module.EmptyModuleType;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.impl.FilePropertyPusher;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -39,6 +40,7 @@ import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
import com.jetbrains.python.PythonHelpersLocator;
import com.jetbrains.python.PythonMockSdk;
+import com.jetbrains.python.PythonModuleTypeBase;
import com.jetbrains.python.PythonTestUtil;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyClass;
@@ -92,6 +94,8 @@ public abstract class PyTestCase extends UsefulTestCase {
setLanguageLevel(null);
myFixture.tearDown();
myFixture = null;
+ final PythonLanguageLevelPusher levelPusher = Extensions.findExtension(FilePropertyPusher.EP_NAME, PythonLanguageLevelPusher.class);
+ levelPusher.flushLanguageLevelCache();
super.tearDown();
}
@@ -149,7 +153,7 @@ public abstract class PyTestCase extends UsefulTestCase {
@Override
public ModuleType getModuleType() {
- return EmptyModuleType.getInstance();
+ return PythonModuleTypeBase.getInstance();
}
@Override
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCallingNonCallableInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCallingNonCallableInspectionTest.java
index 22743ac76b09..b4ae36c8e668 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyCallingNonCallableInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyCallingNonCallableInspectionTest.java
@@ -89,6 +89,16 @@ public class PyCallingNonCallableInspectionTest extends PyTestCase {
doTest();
}
+ // PY-13051
+ public void testCallDictSubscriptionExpression() {
+ doTest();
+ }
+
+ // PY-12004
+ public void testLocalCallableClass() {
+ doTest();
+ }
+
private void doTest() {
setLanguageLevel(LanguageLevel.PYTHON27);
try {
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
index 21417363faa6..e614edd8e627 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
@@ -361,6 +361,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doTest();
}
+ // PY-13418
+ public void testOneUnsedOneMarked() {
+ doMultiFileTest();
+ }
+
@NotNull
@Override
protected Class<? extends PyInspection> getInspectionClass() {
diff --git a/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/after.java.template b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/after.java.template
new file mode 100644
index 000000000000..f819c9e0e197
--- /dev/null
+++ b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/after.java.template
@@ -0,0 +1,7 @@
+if (otherCondition) {
+ doAnotherAction();
+} else if (someCondition) {
+ doSomeAction();
+} else {
+ defaultAction();
+} \ No newline at end of file
diff --git a/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/before.java.template b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/before.java.template
new file mode 100644
index 000000000000..ab7f1dad2b46
--- /dev/null
+++ b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/before.java.template
@@ -0,0 +1,7 @@
+if (someCondition) {
+ doSomeAction();
+} <spot>else</spot> if (otherCondition) {
+ doAnotherAction();
+} else {
+ defaultAction();
+} \ No newline at end of file
diff --git a/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/description.html b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/description.html
new file mode 100644
index 000000000000..49143dfc8ec4
--- /dev/null
+++ b/resources-en/src/intentionDescriptions/SwapIfStatementsIntentionAction/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+This intention swaps if-statements adjoined to else keyword
+</body>
+</html> \ No newline at end of file
diff --git a/resources-en/src/messages/QuickFixBundle.properties b/resources-en/src/messages/QuickFixBundle.properties
index 9e94379d7892..08cd32e9972b 100644
--- a/resources-en/src/messages/QuickFixBundle.properties
+++ b/resources-en/src/messages/QuickFixBundle.properties
@@ -281,4 +281,6 @@ wrap.array.to.arrays.as.list.single.parameter.text=Wrap using ''Arrays.asList''
annotations.fix=Annotations
add.missing.annotation.parameters.fix=Add missing annotation parameters - {0}
-add.missing.annotation.single.parameter.fix=Add missing annotation parameter ''{0}'' \ No newline at end of file
+add.missing.annotation.single.parameter.fix=Add missing annotation parameter ''{0}''
+
+add.method.qualifier.fix.text=Add Qualifier {0} to Method \ No newline at end of file
diff --git a/resources-en/src/search/searchableOptions.xml b/resources-en/src/search/searchableOptions.xml
index f0c1983a67c2..86e76b805242 100644
--- a/resources-en/src/search/searchableOptions.xml
+++ b/resources-en/src/search/searchableOptions.xml
@@ -22334,6 +22334,9 @@
<option name="end" hit="End (on blank line)" />
<option name="line" hit="End (on blank line)" />
<option name="on" hit="End (on blank line)" />
+ <option name="backspace" hit="Backspace smart indent" />
+ <option name="smart" hit="Backspace smart indent" />
+ <option name="indent" hit="Backspace smart indent" />
<option name="enter" hit="Enter" />
<option name="home" hit="Home" />
<option name="a" hit="Insert 'self' when defining a method" />
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 93cee99db49e..329fc3def69f 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -719,6 +719,10 @@
<className>com.intellij.codeInsight.intention.impl.CreateSwitchIntention</className>
<category>Control Flow</category>
</intentionAction>
+ <intentionAction>
+ <className>com.intellij.codeInsight.intention.impl.SwapIfStatementsIntentionAction</className>
+ <category>Control Flow</category>
+ </intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.CreateFieldFromParameterAction</className>
@@ -1467,6 +1471,7 @@
implementationClass="com.intellij.psi.impl.JavaRegExpHost"/>
<psi.referenceContributor language="JAVA" implementation="com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionReferenceContributor"/>
+ <psi.referenceContributor language="JAVA" implementation="com.intellij.psi.impl.source.resolve.reference.impl.JavaCharsetReferenceContributor"/>
<writingAccessProvider implementation="com.intellij.refactoring.util.ClsElementWritingAccessProvider"/>
@@ -1512,6 +1517,7 @@
<codeInsight.linkHandler prefix="#assignment/" handlerClass="com.intellij.codeInsight.intention.impl.config.AssignmentTooltipLinkHandler"/>
<nonProjectFileWritingAccessExtension
implementation="com.intellij.codeInsight.ExternalAnnotationsNonProjectFileWritingAccessExtension"/>
+ <lang.inspectionSuppressor language="JAVA" implementationClass="com.intellij.codeInspection.SuppressManagerImpl"/>
</extensions>
<actions>
diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml
index 81721a90017a..81a791f42208 100644
--- a/resources/src/idea/JavaActions.xml
+++ b/resources/src/idea/JavaActions.xml
@@ -117,7 +117,7 @@
<group id="ToggleBreakpointAction">
<action id="ToggleMethodBreakpoint" class="com.intellij.debugger.actions.ToggleMethodBreakpointAction"/>
<action id="ToggleFieldBreakpoint" class="com.intellij.debugger.actions.ToggleFieldBreakpointAction"/>
- <action id="ToggleBreakpointEnabled" class="com.intellij.debugger.actions.ToggleBreakpointEnabledAction"/>
+ <!--Moved to XDebugger <action id="ToggleBreakpointEnabled" class="com.intellij.debugger.actions.ToggleBreakpointEnabledAction"/>-->
<add-to-group group-id="DebugMainMenu" anchor="after" relative-to-action="ToggleLineBreakpoint"/>
</group>
@@ -184,7 +184,6 @@
<action id="Debugger.ResumeThread" class="com.intellij.debugger.actions.ResumeThreadAction"/>
<action id="Debugger.FreezeThread" class="com.intellij.debugger.actions.FreezeThreadAction"/>
<action id="Debugger.InterruptThread" class="com.intellij.debugger.actions.InterruptThreadAction"/>
- <action id="Debugger.FocusOnBreakpoint" class="com.intellij.debugger.ui.breakpoints.actions.FocusOnBreakpointAction"/>
<add-to-group group-id="DebuggerActions" anchor="first"/>
</group>
diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml
index ae9befc8fe2e..b27faab54d4a 100644
--- a/resources/src/idea/RichPlatformPlugin.xml
+++ b/resources/src/idea/RichPlatformPlugin.xml
@@ -113,7 +113,6 @@
<packaging.sourceItemProvider implementation="com.intellij.openapi.roots.ui.configuration.artifacts.sourceItems.ArtifactsSourceItemsProvider"/>
<packaging.artifactType implementation="com.intellij.packaging.impl.artifacts.JarArtifactType" order="first"/>
<packaging.artifactType implementation="com.intellij.packaging.impl.artifacts.PlainArtifactType" order="last"/>
- <compiler.additionalCompileScopeProvider implementation="com.intellij.packaging.impl.compiler.ArtifactAdditionalCompileScopeProvider"/>
<compiler.buildTargetScopeProvider implementation="com.intellij.packaging.impl.compiler.ArtifactBuildTargetScopeProvider"/>
<compiler implementation="com.intellij.packaging.impl.compiler.ArtifactsCompiler" id="artifactsCompiler"/>
<gotoRelatedProvider implementation="com.intellij.testIntegration.GotoTestRelatedProvider"/>
diff --git a/spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java b/spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java
index c27047c96308..1f2244995f68 100644
--- a/spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java
+++ b/spellchecker/src/com/intellij/spellchecker/inspections/SpellCheckingInspection.java
@@ -40,7 +40,7 @@ import java.awt.*;
import java.util.Set;
-public class SpellCheckingInspection extends LocalInspectionTool implements BatchSuppressableTool {
+public class SpellCheckingInspection extends LocalInspectionTool {
public static final String SPELL_CHECKING_INSPECTION_TOOL_NAME = "SpellCheckingInspection";
@Override
@@ -61,12 +61,13 @@ public class SpellCheckingInspection extends LocalInspectionTool implements Batc
@Override
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
if (element != null) {
- SpellcheckingStrategy strategy = getSpellcheckingStrategy(element, element.getLanguage());
+ final Language language = element.getLanguage();
+ SpellcheckingStrategy strategy = getSpellcheckingStrategy(element, language);
if(strategy instanceof SuppressibleSpellcheckingStrategy) {
return ((SuppressibleSpellcheckingStrategy)strategy).getSuppressActions(element, getShortName());
}
}
- return SuppressQuickFix.EMPTY_ARRAY;
+ return super.getBatchSuppressActions(element);
}
private static SpellcheckingStrategy getSpellcheckingStrategy(@NotNull PsiElement element, @NotNull Language language) {
@@ -80,9 +81,12 @@ public class SpellCheckingInspection extends LocalInspectionTool implements Batc
@Override
public boolean isSuppressedFor(@NotNull PsiElement element) {
- SpellcheckingStrategy strategy = getSpellcheckingStrategy(element, element.getLanguage());
- return strategy instanceof SuppressibleSpellcheckingStrategy &&
- ((SuppressibleSpellcheckingStrategy)strategy).isSuppressedFor(element, getShortName());
+ final Language language = element.getLanguage();
+ SpellcheckingStrategy strategy = getSpellcheckingStrategy(element, language);
+ if (strategy instanceof SuppressibleSpellcheckingStrategy) {
+ return ((SuppressibleSpellcheckingStrategy)strategy).isSuppressedFor(element, getShortName());
+ }
+ return super.isSuppressedFor(element);
}
@Override
diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
index c16bb7a2a010..71cb555d1838 100644
--- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
+++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
@@ -57,6 +57,7 @@ cdata
cglib
changelist
charset
+charsets
checkbox
checkboxes
checksum
@@ -219,6 +220,7 @@ jpeg
jpdl
jquery
jsessionid
+jshint
json
junit
keepduplicates
diff --git a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
index 19c4f06b1744..aec3931e6a45 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -24,12 +24,10 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.ModificationTracker;
import com.intellij.profile.Profile;
import com.intellij.profile.ProfileChangeAdapter;
import com.intellij.profile.codeInspection.InspectionProfileManager;
@@ -56,7 +54,6 @@ import java.util.List;
public class DomElementAnnotationsManagerImpl extends DomElementAnnotationsManager {
public static final Object LOCK = new Object();
- private static final Logger LOG = Logger.getInstance("#com.intellij.util.xml.highlighting.DomElementAnnotationsManagerImpl");
private static final Key<DomElementsProblemsHolderImpl> DOM_PROBLEM_HOLDER_KEY = Key.create("DomProblemHolder");
private static final Key<CachedValue<Boolean>> CACHED_VALUE_KEY = Key.create("DomProblemHolderCachedValue");
private final EventDispatcher<DomHighlightingListener> myDispatcher = EventDispatcher.create(DomHighlightingListener.class);
@@ -109,18 +106,10 @@ public class DomElementAnnotationsManagerImpl extends DomElementAnnotationsManag
}
};
- private final ModificationTracker myModificationTracker;
private final Project myProject;
- private long myModificationCount;
public DomElementAnnotationsManagerImpl(Project project) {
myProject = project;
- myModificationTracker = new ModificationTracker() {
- @Override
- public long getModificationCount() {
- return myModificationCount;
- }
- };
final ProfileChangeAdapter profileChangeAdapter = new ProfileChangeAdapter() {
@Override
public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
@@ -145,7 +134,7 @@ public class DomElementAnnotationsManagerImpl extends DomElementAnnotationsManag
@Override
public void dropAnnotationsCache() {
- myModificationCount++;
+ incModificationCount();
}
public final List<DomElementProblemDescriptor> appendProblems(@NotNull DomFileElement element, @NotNull DomElementAnnotationHolder annotationHolder, Class<? extends DomElementsInspection> inspectionClass) {
@@ -171,7 +160,7 @@ public class DomElementAnnotationsManagerImpl extends DomElementAnnotationsManag
final CachedValue<Boolean> cachedValue = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<Boolean>() {
@Override
public Result<Boolean> compute() {
- return new Result<Boolean>(Boolean.FALSE, element, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, myModificationTracker, ProjectRootManager.getInstance(myProject));
+ return new Result<Boolean>(Boolean.FALSE, element, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, DomElementAnnotationsManagerImpl.this, ProjectRootManager.getInstance(myProject));
}
}, false);
cachedValue.getValue();
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomCompletionContributor.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomCompletionContributor.java
index e0478c90a3d3..63b5d217018c 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomCompletionContributor.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomCompletionContributor.java
@@ -27,6 +27,7 @@ import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.HashSet;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.util.XmlUtil;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
@@ -35,7 +36,7 @@ public class DomCompletionContributor extends CompletionContributor{
private final GenericValueReferenceProvider myProvider = new GenericValueReferenceProvider();
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC) return;
if (domKnowsBetter(parameters, result)) {
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java
index 7614c25ff4ad..591795941d29 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomManagerImpl.java
@@ -83,10 +83,10 @@ public final class DomManagerImpl extends DomManager {
private final SemService mySemService;
private final DomApplicationComponent myApplicationComponent;
- private long myModificationCount;
private boolean myChanging;
public DomManagerImpl(Project project) {
+ super(project);
myProject = project;
mySemService = SemService.getSemService(project);
myApplicationComponent = DomApplicationComponent.getInstance();
@@ -221,7 +221,7 @@ public final class DomManagerImpl extends DomManager {
final void fireEvent(DomEvent event) {
if (mySemService.isInsideAtomicChange()) return;
- myModificationCount++;
+ incModificationCount();
myListeners.getMulticaster().eventOccured(event);
}
@@ -490,15 +490,10 @@ public final class DomManagerImpl extends DomManager {
return myApplicationComponent.getTypeChooserManager();
}
- @Override
- public long getModificationCount() {
- return myModificationCount + PsiManager.getInstance(myProject).getModificationTracker().getOutOfCodeBlockModificationCount();
- }
-
public void performAtomicChange(@NotNull Runnable change) {
mySemService.performAtomicChange(change);
if (!mySemService.isInsideAtomicChange()) {
- myModificationCount++;
+ incModificationCount();
}
}
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomReferenceContributor.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomReferenceContributor.java
index f44fe05c92d1..6fe7a0df71a4 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomReferenceContributor.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomReferenceContributor.java
@@ -18,13 +18,14 @@ package com.intellij.util.xml.impl;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
import com.intellij.patterns.XmlPatterns;
+import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class DomReferenceContributor extends PsiReferenceContributor{
@Override
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
GenericValueReferenceProvider provider = new GenericValueReferenceProvider();
registrar.registerReferenceProvider(XmlPatterns.xmlTag(), provider);
diff --git a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/DeleteDomElement.java b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/DeleteDomElement.java
index c293df56af66..9506608eef97 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/tree/actions/DeleteDomElement.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/tree/actions/DeleteDomElement.java
@@ -30,6 +30,7 @@ import com.intellij.util.xml.ElementPresentation;
import com.intellij.util.xml.tree.BaseDomElementNode;
import com.intellij.util.xml.tree.DomFileElementNode;
import com.intellij.util.xml.tree.DomModelTreeView;
+import org.jetbrains.annotations.NotNull;
/**
* User: Sergey.Vasiliev
@@ -56,12 +57,12 @@ public class DeleteDomElement extends BaseDomTreeAction {
final DomElement domElement = ((BaseDomElementNode)selectedNode).getDomElement();
- final int ret = Messages.showOkCancelDialog(getPresentationText(selectedNode) + "?", ApplicationBundle.message("action.remove"),
+ final int ret = Messages.showOkCancelDialog(getPresentationText(selectedNode, "Remove") + "?", "Remove",
Messages.getQuestionIcon());
if (ret == Messages.OK) {
new WriteCommandAction(domElement.getManager().getProject(), DomUtil.getFile(domElement)) {
@Override
- protected void run(final Result result) throws Throwable {
+ protected void run(@NotNull final Result result) throws Throwable {
domElement.undefine();
}
}.execute();
@@ -90,7 +91,7 @@ public class DeleteDomElement extends BaseDomTreeAction {
if (enabled) {
- e.getPresentation().setText(getPresentationText(selectedNode));
+ e.getPresentation().setText(getPresentationText(selectedNode, ApplicationBundle.message("action.remove")));
}
else {
e.getPresentation().setText(ApplicationBundle.message("action.remove"));
@@ -99,8 +100,7 @@ public class DeleteDomElement extends BaseDomTreeAction {
e.getPresentation().setIcon(AllIcons.General.Remove);
}
- private static String getPresentationText(final SimpleNode selectedNode) {
- String removeString = ApplicationBundle.message("action.remove");
+ private static String getPresentationText(final SimpleNode selectedNode, String removeString) {
final ElementPresentation presentation = ((BaseDomElementNode)selectedNode).getDomElement().getPresentation();
removeString += " " + presentation.getTypeName() +
(presentation.getElementName() == null || presentation.getElementName().trim().length() == 0? "" : ": " + presentation.getElementName());
diff --git a/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java b/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java
index 01bc1d819596..49b2f759fca0 100644
--- a/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java
+++ b/xml/dom-openapi/src/com/intellij/util/xml/DomManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,6 +20,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
+import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReferenceFactory;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
@@ -35,15 +36,19 @@ import java.lang.reflect.Type;
/**
* @author peter
*/
-public abstract class DomManager implements ModificationTracker {
+public abstract class DomManager extends CompositeModificationTracker implements ModificationTracker {
public static final Key<Module> MOCK_ELEMENT_MODULE = Key.create("MockElementModule");
- private final static NotNullLazyKey<DomManager, Project> INSTANCE_CACHE = ServiceManager.createLazyKey(DomManager.class);
+ private static final NotNullLazyKey<DomManager, Project> INSTANCE_CACHE = ServiceManager.createLazyKey(DomManager.class);
public static DomManager getDomManager(Project project) {
return INSTANCE_CACHE.getValue(project);
}
+ public DomManager(@NotNull Project project) {
+ super(PsiManager.getInstance(project).getModificationTracker().getOutOfCodeBlockModificationTracker());
+ }
+
public abstract Project getProject();
/**
diff --git a/xml/dom-openapi/src/com/intellij/util/xml/ParentScopeProvider.java b/xml/dom-openapi/src/com/intellij/util/xml/ParentScopeProvider.java
index a476377ad097..2ecee3f52589 100644
--- a/xml/dom-openapi/src/com/intellij/util/xml/ParentScopeProvider.java
+++ b/xml/dom-openapi/src/com/intellij/util/xml/ParentScopeProvider.java
@@ -15,12 +15,14 @@
*/
package com.intellij.util.xml;
+import org.jetbrains.annotations.NotNull;
+
/**
* @author peter
*/
public class ParentScopeProvider extends ScopeProvider{
@Override
- public DomElement getScope(DomElement element) {
+ public DomElement getScope(@NotNull DomElement element) {
return element.getParent();
}
}
diff --git a/xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManager.java b/xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManager.java
index 364aca490bc5..1aa27d4fd855 100644
--- a/xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManager.java
+++ b/xml/dom-openapi/src/com/intellij/util/xml/highlighting/DomElementAnnotationsManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import org.jetbrains.annotations.NotNull;
@@ -28,7 +29,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.EventListener;
import java.util.List;
-public abstract class DomElementAnnotationsManager {
+public abstract class DomElementAnnotationsManager extends SimpleModificationTracker {
public static DomElementAnnotationsManager getInstance(Project project) {
return ServiceManager.getService(project, DomElementAnnotationsManager.class);
diff --git a/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java b/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java
index 1935228d86eb..15c3de313d43 100644
--- a/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java
+++ b/xml/dom-openapi/src/com/intellij/util/xml/tree/DomModelTreeView.java
@@ -119,7 +119,7 @@ public class DomModelTreeView extends Wrapper implements DataProvider, Disposabl
final Project project = myDomManager.getProject();
DomElementAnnotationsManager.getInstance(project).addHighlightingListener(new DomElementAnnotationsManager.DomHighlightingListener() {
@Override
- public void highlightingFinished(DomFileElement element) {
+ public void highlightingFinished(@NotNull DomFileElement element) {
if (element.isValid()) {
queueUpdate(DomUtil.getFile(element).getVirtualFile());
}
diff --git a/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java b/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java
index 630ad79f03d0..bd69d041ed41 100644
--- a/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java
+++ b/xml/dom-tests/tests/com/intellij/util/xml/DomBasicsTest.java
@@ -30,6 +30,7 @@ import com.intellij.util.xml.reflect.DomAttributeChildDescription;
import com.intellij.util.xml.reflect.DomCollectionChildDescription;
import com.intellij.util.xml.reflect.DomFixedChildDescription;
import com.intellij.util.xml.reflect.DomGenericInfo;
+import org.jetbrains.annotations.NotNull;
import java.lang.reflect.ParameterizedType;
import java.util.*;
@@ -39,7 +40,7 @@ import java.util.*;
*/
public class DomBasicsTest extends DomTestCase {
@Override
- protected void invokeTestRunnable(final Runnable runnable) throws Exception {
+ protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception {
new WriteCommandAction.Simple(null) {
@Override
protected void run() throws Throwable {
diff --git a/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form b/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
index cd42e379619c..1a633fc60e83 100644
--- a/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
+++ b/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
@@ -14,17 +14,17 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
- <border type="etched" title="XML"/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
+ <border type="etched" title="XML"/>
<children>
<component id="5cbfc" class="javax.swing.JCheckBox" binding="myShowAutoImportPopups" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text resource-bundle="messages/ApplicationBundle" key="checkbox.show.import.popup"/>
+ <text value="Show import popup"/>
</properties>
</component>
</children>
diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java
index 1cf7a7730173..6781db72e93a 100644
--- a/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java
+++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,6 +15,8 @@
*/
package com.intellij.application.options.emmet;
+import com.intellij.codeInsight.template.emmet.filters.BemEmmetFilter;
+import com.intellij.codeInsight.template.emmet.filters.ZenCodingFilter;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
@@ -26,11 +28,8 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Map;
+import java.util.Set;
-/**
- * User: zolotov
- * Date: 2/20/13
- */
@State(
name = "EmmetOptions",
storages = {
@@ -39,24 +38,46 @@ import java.util.Map;
)}
)
public class EmmetOptions implements PersistentStateComponent<EmmetOptions>, ExportableComponent {
+ /**
+ * @deprecated delete after IDEA 14
+ */
private boolean myBemFilterEnabledByDefault = false;
private boolean myEmmetEnabled = true;
private int myEmmetExpandShortcut = TemplateSettings.TAB_CHAR;
private boolean myFuzzySearchEnabled = true;
private boolean myAutoInsertCssPrefixedEnabled = true;
private boolean myPreviewEnabled = false;
+ private Set<String> myFiltersEnabledByDefault = ContainerUtil.newHashSet();
@NotNull
private Map<String, Integer> prefixes = ContainerUtil.newHashMap();
-
+ /**
+ * @deprecated delete after IDEA 14
+ */
public boolean isBemFilterEnabledByDefault() {
return myBemFilterEnabledByDefault;
}
+ /**
+ * @deprecated delete after IDEA 14
+ */
public void setBemFilterEnabledByDefault(boolean enableBemFilterByDefault) {
myBemFilterEnabledByDefault = enableBemFilterByDefault;
}
+ @NotNull
+ public Set<String> getFiltersEnabledByDefault() {
+ return myFiltersEnabledByDefault;
+ }
+
+ public void setFiltersEnabledByDefault(@NotNull Set<String> filtersEnabledByDefault) {
+ myFiltersEnabledByDefault = filtersEnabledByDefault;
+ }
+
+ public boolean isFilterEnabledByDefault(@NotNull ZenCodingFilter filter) {
+ return myFiltersEnabledByDefault.contains(filter.getSuffix());
+ }
+
public void setEmmetExpandShortcut(int emmetExpandShortcut) {
myEmmetExpandShortcut = emmetExpandShortcut;
}
@@ -126,6 +147,11 @@ public class EmmetOptions implements PersistentStateComponent<EmmetOptions>, Exp
@Override
public void loadState(final EmmetOptions state) {
XmlSerializerUtil.copyBean(state, this);
+
+ // todo delete after IDEA 14
+ if (myFiltersEnabledByDefault.isEmpty() && myBemFilterEnabledByDefault) {
+ myFiltersEnabledByDefault.add(BemEmmetFilter.SUFFIX);
+ }
}
public static EmmetOptions getInstance() {
diff --git a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form
index 0c8dec3afcac..ec4cafb26fd0 100644
--- a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form
+++ b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.form
@@ -19,14 +19,6 @@
</clientProperties>
<border type="none" title="XML"/>
<children>
- <component id="9ed4c" class="com.intellij.ui.components.JBCheckBox" binding="myEnableBEMFilterJBCheckBox" default-binding="true">
- <constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text resource-bundle="messages/XmlBundle" key="emmet.enable.bem.filter"/>
- </properties>
- </component>
<component id="446a3" class="com.intellij.ui.components.JBCheckBox" binding="myEnableEmmetJBCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
@@ -37,12 +29,28 @@
</component>
<component id="c52c1" class="com.intellij.ui.components.JBCheckBox" binding="myEnablePreviewJBCheckBox">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/XmlBundle" key="emmet.enable.preview"/>
</properties>
</component>
+ <grid id="cdbb7" binding="myFiltersListPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="3282c" class="com.intellij.ui.CheckBoxList" binding="myFiltersCheckBoxList">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
+ </children>
+ </grid>
</children>
</grid>
<vspacer id="27c08">
diff --git a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java
index babbfc1d3046..764d74f94375 100644
--- a/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java
+++ b/xml/impl/src/com/intellij/application/options/emmet/XmlEmmetConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,34 +15,46 @@
*/
package com.intellij.application.options.emmet;
+import com.intellij.codeInsight.template.emmet.filters.ZenCodingFilter;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.ui.CheckBoxList;
+import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBCheckBox;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.xml.XmlBundle;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.Set;
-/**
- * User: zolotov
- * Date: 2/20/13
- */
public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Configurable.NoScroll {
- private JBCheckBox myEnableBEMFilterJBCheckBox;
private JPanel myPanel;
private JBCheckBox myEnableEmmetJBCheckBox;
private JBCheckBox myEnablePreviewJBCheckBox;
+ private CheckBoxList<ZenCodingFilter> myFiltersCheckBoxList;
+ private JPanel myFiltersListPanel;
public XmlEmmetConfigurable() {
myEnableEmmetJBCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean selected = myEnableEmmetJBCheckBox.isSelected();
- myEnableBEMFilterJBCheckBox.setEnabled(selected);
myEnablePreviewJBCheckBox.setEnabled(selected);
+ myFiltersCheckBoxList.setEnabled(selected);
+ }
+ });
+ myFiltersListPanel.setBorder(IdeBorderFactory.createTitledBorder(XmlBundle.message("emmet.filters.enabled.by.default"), false));
+ myFiltersCheckBoxList.setItems(ZenCodingFilter.getInstances(), new Function<ZenCodingFilter, String>() {
+ @Override
+ public String fun(ZenCodingFilter filter) {
+ return filter.getDisplayName();
}
});
}
@@ -62,29 +74,43 @@ public class XmlEmmetConfigurable implements UnnamedConfigurable, Disposable, Co
EmmetOptions emmetOptions = EmmetOptions.getInstance();
return emmetOptions.isEmmetEnabled() != myEnableEmmetJBCheckBox.isSelected() ||
emmetOptions.isPreviewEnabled() != myEnablePreviewJBCheckBox.isSelected() ||
- emmetOptions.isBemFilterEnabledByDefault() != myEnableBEMFilterJBCheckBox.isSelected();
+ !emmetOptions.getFiltersEnabledByDefault().equals(enabledFilters());
}
-
@Override
public void apply() throws ConfigurationException {
EmmetOptions emmetOptions = EmmetOptions.getInstance();
emmetOptions.setEmmetEnabled(myEnableEmmetJBCheckBox.isSelected());
- emmetOptions.setBemFilterEnabledByDefault(myEnableBEMFilterJBCheckBox.isSelected());
emmetOptions.setPreviewEnabled(myEnablePreviewJBCheckBox.isSelected());
+ emmetOptions.setFiltersEnabledByDefault(enabledFilters());
}
+
@Override
public void reset() {
EmmetOptions emmetOptions = EmmetOptions.getInstance();
myEnableEmmetJBCheckBox.setSelected(emmetOptions.isEmmetEnabled());
- myEnableBEMFilterJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
- myEnableBEMFilterJBCheckBox.setSelected(emmetOptions.isBemFilterEnabledByDefault());
myEnablePreviewJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
myEnablePreviewJBCheckBox.setSelected(emmetOptions.isPreviewEnabled());
+
+ Set<String> enabledByDefault = emmetOptions.getFiltersEnabledByDefault();
+ for (ZenCodingFilter filter : ZenCodingFilter.getInstances()) {
+ myFiltersCheckBoxList.setItemSelected(filter, enabledByDefault.contains(filter.getSuffix()));
+ }
}
@Override
public void disposeUIResources() {
}
+
+ @NotNull
+ private Set<String> enabledFilters() {
+ Set<String> result = ContainerUtil.newHashSet();
+ for (ZenCodingFilter filter : ZenCodingFilter.getInstances()) {
+ if (myFiltersCheckBoxList.isItemSelected(filter)) {
+ result.add(filter.getSuffix());
+ }
+ }
+ return result;
+ }
}
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java
index 86a2155124dd..cc066a921447 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlCompletionContributor.java
@@ -122,7 +122,7 @@ public class XmlCompletionContributor extends CompletionContributor {
}
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
super.fillCompletionVariants(parameters, result);
if (result.isStopped()) {
return;
diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlNoVariantsDelegator.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlNoVariantsDelegator.java
index 9166b67ab532..da991ac048f3 100644
--- a/xml/impl/src/com/intellij/codeInsight/completion/XmlNoVariantsDelegator.java
+++ b/xml/impl/src/com/intellij/codeInsight/completion/XmlNoVariantsDelegator.java
@@ -15,6 +15,8 @@
*/
package com.intellij.codeInsight.completion;
+import org.jetbrains.annotations.NotNull;
+
/**
* @author Dmitry Avdeev
* Date: 12/19/11
@@ -22,7 +24,7 @@ package com.intellij.codeInsight.completion;
public class XmlNoVariantsDelegator extends CompletionContributor {
@Override
- public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
+ public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
final boolean empty = result.runRemainingContributors(parameters, true).isEmpty();
if (!empty && parameters.getInvocationCount() == 0) {
diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java
index d6ab939090fe..3515297f31de 100644
--- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java
+++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java
@@ -17,58 +17,22 @@ package com.intellij.codeInsight.daemon.impl.analysis.encoding;
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
import com.intellij.codeInsight.daemon.XmlErrorMessages;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlAttributeValue;
-import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
/**
* @author cdr
*/
-public class XmlEncodingReference implements PsiReference, EmptyResolveMessageProvider, Comparable<XmlEncodingReference> {
- private final XmlAttributeValue myValue;
-
- private final String myCharsetName;
- private final TextRange myRangeInElement;
+public class XmlEncodingReference extends EncodingReference implements EmptyResolveMessageProvider, Comparable<XmlEncodingReference> {
private final int myPriority;
public XmlEncodingReference(XmlAttributeValue value, final String charsetName, final TextRange rangeInElement, int priority) {
- myValue = value;
- myCharsetName = charsetName;
- myRangeInElement = rangeInElement;
+ super(value, charsetName, rangeInElement);
myPriority = priority;
}
@Override
- public PsiElement getElement() {
- return myValue;
- }
-
- @Override
- public TextRange getRangeInElement() {
- return myRangeInElement;
- }
-
- @Override
- @Nullable
- public PsiElement resolve() {
- return CharsetToolkit.forName(myCharsetName) == null ? null : myValue;
- //if (ApplicationManager.getApplication().isUnitTestMode()) return myValue; // tests do not have full JDK
- //String fqn = charset.getClass().getName();
- //return myValue.getManager().findClass(fqn, GlobalSearchScope.allScope(myValue.getProject()));
- }
-
- @Override
@NotNull
public String getUnresolvedMessagePattern() {
//noinspection UnresolvedPropertyKey
@@ -76,43 +40,6 @@ public class XmlEncodingReference implements PsiReference, EmptyResolveMessagePr
}
@Override
- @NotNull
- public String getCanonicalText() {
- return myCharsetName;
- }
-
- @Override
- public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
- return null;
- }
-
- @Override
- public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
- return null;
- }
-
- @Override
- public boolean isReferenceTo(PsiElement element) {
- return false;
- }
-
- @Override
- @NotNull
- public Object[] getVariants() {
- Charset[] charsets = CharsetToolkit.getAvailableCharsets();
- List<LookupElement> suggestions = new ArrayList<LookupElement>(charsets.length);
- for (Charset charset : charsets) {
- suggestions.add(LookupElementBuilder.create(charset.name()).withCaseSensitivity(false));
- }
- return suggestions.toArray(new LookupElement[suggestions.size()]);
- }
-
- @Override
- public boolean isSoft() {
- return false;
- }
-
- @Override
public int compareTo(@NotNull XmlEncodingReference ref) {
return myPriority - ref.myPriority;
}
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java
index 43084679f455..656a061b9b4a 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java
@@ -18,20 +18,16 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.application.options.editor.WebEditorOptions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.lang.xml.XMLLanguage;
-import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlAttribute;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
-
public class XmlEqTypedHandler extends TypedHandlerDelegate {
- private final List<Caret> caretsForInsertingQuotes = ContainerUtil.newSmartList();
+ private boolean needToInsertQuotes = false;
@Override
public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) {
@@ -39,12 +35,10 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate {
if (WebEditorOptions.getInstance().isInsertQuotesForAttributeValue()) {
boolean inXml = file.getLanguage() instanceof XMLLanguage || file.getViewProvider().getBaseLanguage() instanceof XMLLanguage;
if (c == '=' && inXml) {
- for(Caret caret : editor.getCaretModel().getAllCarets()) {
- PsiElement at = file.findElementAt(caret.getOffset() - 1);
- PsiElement atParent = at != null ? at.getParent() : null;
- if(atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null) {
- caretsForInsertingQuotes.add(caret);
- }
+ PsiElement at = file.findElementAt(editor.getCaretModel().getOffset() - 1);
+ PsiElement atParent = at != null ? at.getParent() : null;
+ if(atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null) {
+ needToInsertQuotes = atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null;
}
}
}
@@ -54,15 +48,13 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate {
@Override
public Result charTyped(char c, Project project, @NotNull Editor editor, @NotNull PsiFile file) {
- for (Caret caret : caretsForInsertingQuotes) {
- int offset = caret.getOffset();
+ if (needToInsertQuotes) {
+ int offset = editor.getCaretModel().getOffset();
editor.getDocument().insertString(offset, "\"\"");
- caret.moveToOffset(offset + 1);
- }
- if (editor.getCaretModel().getAllCarets().size() == caretsForInsertingQuotes.size()) {
+ editor.getCaretModel().moveToOffset(offset + 1);
AutoPopupController.getInstance(project).scheduleAutoPopup(editor);
}
- caretsForInsertingQuotes.clear();
+ needToInsertQuotes = false;
return super.charTyped(c, project, editor, file);
}
}
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java
index 2c0143ebeda6..bde429676d2a 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlGtTypedHandler.java
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.highlighting.BraceMatchingUtil;
import com.intellij.lang.ASTNode;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.ScrollType;
@@ -94,7 +93,7 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
if (tokenType == XmlTokenType.XML_TAG_END ||
tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END && element.getTextOffset() == offset - 1) {
- EditorModificationUtil.moveAllCaretsRelatively(editor, 1);
+ EditorModificationUtil.moveCaretRelatively(editor, 1);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
return Result.STOP;
}
@@ -155,7 +154,7 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
element.getPrevSibling() !=null &&
element.getPrevSibling().getText().equals("<")) {
// tag is started and there is another text in the end
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "</" + element.getText() + ">", false, 0);
+ EditorModificationUtil.insertStringAtCaret(editor, "</" + element.getText() + ">", false, 0);
}
return Result.CONTINUE;
}
@@ -205,7 +204,7 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
Collection<TextRange> cdataReformatRanges = null;
final XmlElementDescriptor descriptor = tag.getDescriptor();
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, "</" + name + ">", false, 0);
+ EditorModificationUtil.insertStringAtCaret(editor, "</" + name + ">", false, 0);
if (descriptor instanceof XmlElementDescriptorWithCDataContent) {
final XmlElementDescriptorWithCDataContent cDataContainer = (XmlElementDescriptorWithCDataContent)descriptor;
@@ -214,12 +213,10 @@ public class XmlGtTypedHandler extends TypedHandlerDelegate {
if (cDataContainer.requiresCdataBracesInContext(tag)) {
@NonNls final String cDataStart = "><![CDATA[";
final String inserted = cDataStart + "\n]]>";
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, inserted, false, cDataStart.length());
- for (Caret caret : editor.getCaretModel().getAllCarets()) {
- int caretOffset = caret.getOffset();
- if (caretOffset >= cDataStart.length()) {
- cdataReformatRanges.add(TextRange.from(caretOffset - cDataStart.length(), inserted.length() + 1));
- }
+ EditorModificationUtil.insertStringAtCaret(editor, inserted, false, cDataStart.length());
+ int caretOffset = editor.getCaretModel().getOffset();
+ if (caretOffset >= cDataStart.length()) {
+ cdataReformatRanges.add(TextRange.from(caretOffset - cDataStart.length(), inserted.length() + 1));
}
}
}
diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java
index fbfc6df08044..c5e0ff307a94 100644
--- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java
+++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java
@@ -106,7 +106,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate {
}
}
}
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, tag.getName() + ">", false);
+ EditorModificationUtil.insertStringAtCaret(editor, tag.getName() + ">", false);
return Result.STOP;
}
}
@@ -133,7 +133,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate {
if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null) return Result.CONTINUE;
if (PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class) != null) return Result.CONTINUE;
- EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, ">", false);
+ EditorModificationUtil.insertStringAtCaret(editor, ">", false);
return Result.STOP;
}
return Result.CONTINUE;
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewAction.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewAction.java
index f7f5fe50d58d..2bfb6fad8a7a 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewAction.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewAction.java
@@ -55,10 +55,10 @@ public class EmmetPreviewAction extends BaseCodeInsightAction implements DumbAwa
@Override
protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
- int offset = editor.getCaretModel().getOffset();
return super.isValidForFile(project, editor, file) &&
file instanceof XmlFile &&
- ZenCodingTemplate.findApplicableDefaultGenerator(CustomTemplateCallback.getContext(file, offset), false) != null;
+ ZenCodingTemplate.findApplicableDefaultGenerator(CustomTemplateCallback.getContext(file, CustomTemplateCallback.getOffset(editor)),
+ false) != null;
}
@Override
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java
index 8d07047fc4d6..edde5a83a6d6 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java
@@ -65,7 +65,7 @@ public class EmmetPreviewHint extends LightweightHint implements Disposable {
@Override
public void editorReleased(@NotNull EditorFactoryEvent event) {
if (event.getEditor() == myParentEditor || event.getEditor() == myEditor || event.getEditor() == topLevelEditor) {
- hide();
+ Disposer.dispose(EmmetPreviewHint.this);
}
}
}, this);
@@ -176,6 +176,7 @@ public class EmmetPreviewHint extends LightweightHint implements Disposable {
maxHeight > contentSize.getHeight() ? (int)size.getHeight() : maxHeight);
}
+ @NotNull
@Override
public Insets getInsets() {
return new Insets(1, 2, 0, 0);
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewUtil.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewUtil.java
index 948739d57b96..af106929bcea 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewUtil.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewUtil.java
@@ -61,7 +61,7 @@ public class EmmetPreviewUtil {
if (generator != null && generator instanceof XmlZenCodingGenerator) {
final String templatePrefix = new ZenCodingTemplate().computeTemplateKeyWithoutContextChecking(callback);
if (templatePrefix != null) {
- ZenCodingTemplate.expand(templatePrefix, callback, null, generator, Collections.<ZenCodingFilter>emptyList(), expandPrimitiveAbbreviations, 0);
+ ZenCodingTemplate.expand(templatePrefix, callback, generator, Collections.<ZenCodingFilter>emptyList(), expandPrimitiveAbbreviations, 0);
TemplateImpl template = generatedTemplate.get();
String templateText = template != null ? template.getTemplateText() : null;
if (!StringUtil.isEmpty(templateText)) {
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
index 46d5a5640f53..b0d623683912 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
@@ -124,7 +124,7 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase {
public void expand(@NotNull String key, @NotNull CustomTemplateCallback callback) {
ZenCodingGenerator defaultGenerator = findApplicableDefaultGenerator(callback.getContext(), false);
assert defaultGenerator != null;
- expand(key, callback, null, defaultGenerator, Collections.<ZenCodingFilter>emptyList(), true, Registry.intValue("emmet.segments.limit"));
+ expand(key, callback, defaultGenerator, Collections.<ZenCodingFilter>emptyList(), true, Registry.intValue("emmet.segments.limit"));
}
@Nullable
@@ -179,15 +179,15 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase {
}
- public static void expand(@NotNull String key, @NotNull CustomTemplateCallback callback, @Nullable String surroundedText,
+ public static void expand(@NotNull String key, @NotNull CustomTemplateCallback callback,
@NotNull ZenCodingGenerator defaultGenerator,
@NotNull Collection<? extends ZenCodingFilter> extraFilters,
boolean expandPrimitiveAbbreviations, int segmentsLimit) {
- final ZenCodingNode node = parse(key, callback, defaultGenerator, surroundedText);
+ final ZenCodingNode node = parse(key, callback, defaultGenerator, null);
if (node == null) {
return;
}
- if (surroundedText == null && node instanceof TemplateNode) {
+ if (node instanceof TemplateNode) {
if (key.equals(((TemplateNode)node).getTemplateToken().getKey()) && callback.findApplicableTemplates(key).size() > 1) {
TemplateManagerImpl templateManager = (TemplateManagerImpl)callback.getTemplateManager();
Map<TemplateImpl, String> template2Argument = templateManager.findMatchingTemplates(callback.getFile(), callback.getEditor(), null, TemplateSettings.getInstance());
@@ -204,13 +204,8 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase {
List<ZenCodingFilter> filters = getFilters(node, context);
filters.addAll(extraFilters);
-
- if (surroundedText == null) {
- callback.deleteTemplateKey(key);
- // commit is required. otherwise injections placed after caret will be broken
- PsiDocumentManager.getInstance(callback.getProject()).commitDocument(callback.getEditor().getDocument());
- }
- expand(node, generator, filters, surroundedText, callback, expandPrimitiveAbbreviations, segmentsLimit);
+ callback.deleteTemplateKey(key);
+ expand(node, generator, filters, null, callback, expandPrimitiveAbbreviations, segmentsLimit);
}
private static void expand(ZenCodingNode node,
@@ -514,7 +509,7 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase {
if (!regularTemplateWithSamePrefixExists) {
// exclude perfect matches with existing templates because LiveTemplateCompletionContributor handles it
final Collection<SingleLineEmmetFilter> extraFilters = ContainerUtil.newLinkedList(new SingleLineEmmetFilter());
- expand(templatePrefix, callback, null, generator, extraFilters, false, 0);
+ expand(templatePrefix, callback, generator, extraFilters, false, 0);
if (!generatedTemplate.isNull()) {
final TemplateImpl template = generatedTemplate.get();
template.setKey(templatePrefix);
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
index 64d097d54777..e9de53d23d2e 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
@@ -20,7 +20,6 @@ import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
-import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.util.Couple;
@@ -51,6 +50,8 @@ import static com.google.common.collect.Lists.newLinkedList;
* And documentation here: http://docs.emmet.io/filters/bem/
*/
public class BemEmmetFilter extends ZenCodingFilter {
+ public static final String SUFFIX = "bem";
+
private static final Key<BemState> BEM_STATE = Key.create("BEM_STATE");
private static final String ELEMENT_SEPARATOR = "__";
@@ -95,13 +96,14 @@ public class BemEmmetFilter extends ZenCodingFilter {
@NotNull
@Override
- public String getSuffix() {
- return "bem";
+ public String getDisplayName() {
+ return "BEM";
}
+ @NotNull
@Override
- public boolean isAppliedByDefault(@NotNull PsiElement context) {
- return EmmetOptions.getInstance().isBemFilterEnabledByDefault();
+ public String getSuffix() {
+ return SUFFIX;
}
@Override
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/CommentZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/CommentZenCodingFilter.java
index 82b6235a53c9..d2a7662dcbcb 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/CommentZenCodingFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/CommentZenCodingFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -68,4 +68,10 @@ public class CommentZenCodingFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
+
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "Comment tags";
+ }
}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/EscapeZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/EscapeZenCodingFilter.java
index 3249b5a156e4..d07654699e34 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/EscapeZenCodingFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/EscapeZenCodingFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -43,4 +43,10 @@ public class EscapeZenCodingFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
+
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "Escape";
+ }
}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java
index acd047a26d1f..443db5edd88a 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/SingleLineEmmetFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -57,4 +57,10 @@ public class SingleLineEmmetFilter extends ZenCodingFilter {
public boolean isMyContext(@NotNull PsiElement context) {
return context.getLanguage() instanceof XMLLanguage;
}
+
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "Single line";
+ }
}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/TrimZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/TrimZenCodingFilter.java
index 1c6369244074..ceb0d1dd61b9 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/TrimZenCodingFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/TrimZenCodingFilter.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.codeInsight.template.emmet.filters;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
@@ -31,6 +46,12 @@ public class TrimZenCodingFilter extends ZenCodingFilter {
@NotNull
@Override
+ public String getDisplayName() {
+ return "Trim line markers";
+ }
+
+ @NotNull
+ @Override
public String filterText(@NotNull String text, @NotNull TemplateToken token) {
XmlDocument document = token.getFile().getDocument();
if (document != null) {
@@ -65,7 +86,6 @@ public class TrimZenCodingFilter extends ZenCodingFilter {
final String surroundedText = node.getSurroundedText();
if (surroundedText != null) {
node.setSurroundedText(PATTERN.matcher(surroundedText).replaceAll(""));
- } else if(node.getTemplateToken() == TemplateToken.EMPTY_TEMPLATE_TOKEN) {
}
for (GenerationNode child : node.getChildren()) {
doFilter(child);
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/XslZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/XslZenCodingFilter.java
index 685497f7bcd9..e97b72ed662b 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/XslZenCodingFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/XslZenCodingFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -90,6 +90,12 @@ public class XslZenCodingFilter extends ZenCodingFilter {
@Override
public boolean isAppliedByDefault(@NotNull PsiElement context) {
- return XslTextContextType.isXslOrXsltFile(context.getContainingFile());
+ return XslTextContextType.isXslOrXsltFile(context.getContainingFile()) || super.isAppliedByDefault(context);
+ }
+
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "XSL tuning";
}
}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/ZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/ZenCodingFilter.java
index f5057f3e6d9c..1e4ffa713009 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/ZenCodingFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/ZenCodingFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.template.emmet.filters;
+import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.openapi.extensions.ExtensionPointName;
@@ -29,10 +30,9 @@ import java.util.List;
* @author Eugene.Kudelevsky
*/
public abstract class ZenCodingFilter {
- public static final ExtensionPointName<ZenCodingFilter> EP_NAME =
- new ExtensionPointName<ZenCodingFilter>("com.intellij.xml.zenCodingFilter");
+ public static final ExtensionPointName<ZenCodingFilter> EP_NAME = new ExtensionPointName<ZenCodingFilter>("com.intellij.xml.zenCodingFilter");
- private static final ZenCodingFilter[] ourStandartFilters = new ZenCodingFilter[]{
+ private static final ZenCodingFilter[] OUR_STANDARD_FILTERS = new ZenCodingFilter[]{
new XslZenCodingFilter(),
new CommentZenCodingFilter(),
new EscapeZenCodingFilter(),
@@ -57,12 +57,15 @@ public abstract class ZenCodingFilter {
public abstract boolean isMyContext(@NotNull PsiElement context);
public boolean isAppliedByDefault(@NotNull PsiElement context) {
- return false;
+ return EmmetOptions.getInstance().isFilterEnabledByDefault(this);
}
+
+ @NotNull
+ public abstract String getDisplayName();
public static List<ZenCodingFilter> getInstances() {
List<ZenCodingFilter> generators = new ArrayList<ZenCodingFilter>();
- Collections.addAll(generators, ourStandartFilters);
+ Collections.addAll(generators, OUR_STANDARD_FILTERS);
Collections.addAll(generators, EP_NAME.getExtensions());
return generators;
}
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
index 62e752312126..ef57f5ed4e49 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
@@ -92,8 +93,7 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator {
public String computeTemplateKey(@NotNull CustomTemplateCallback callback) {
Editor editor = callback.getEditor();
int currentOffset = editor.getCaretModel().getOffset();
- int startOffset = editor.getDocument().getLineStartOffset(editor.getCaretModel().getLogicalPosition().line);
-
+ int startOffset = Math.min(editor.getDocument().getLineStartOffset(editor.getDocument().getLineNumber(currentOffset)), currentOffset);
CharSequence documentText = editor.getDocument().getCharsSequence();
PsiElement prevVisibleLeaf = callback.getContext();
while (prevVisibleLeaf != null) {
@@ -101,7 +101,8 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator {
if (textRange.getEndOffset() <= startOffset) {
break;
}
- if (prevVisibleLeaf.getNode().getElementType() == XmlTokenType.XML_TAG_END) {
+ IElementType prevType = prevVisibleLeaf.getNode().getElementType();
+ if (prevType == XmlTokenType.XML_TAG_END || prevType == XmlTokenType.XML_EMPTY_ELEMENT_END) {
startOffset = textRange.getEndOffset();
break;
}
diff --git a/xml/impl/src/com/intellij/ide/actions/CreateHtmlFileAction.java b/xml/impl/src/com/intellij/ide/actions/CreateHtmlFileAction.java
index cbf690cf4ceb..5ac605b5d450 100644
--- a/xml/impl/src/com/intellij/ide/actions/CreateHtmlFileAction.java
+++ b/xml/impl/src/com/intellij/ide/actions/CreateHtmlFileAction.java
@@ -43,8 +43,8 @@ public class CreateHtmlFileAction extends CreateFileFromTemplateAction implement
protected void buildDialog(Project project, PsiDirectory directory, CreateFileFromTemplateDialog.Builder builder) {
builder
.setTitle(XmlBundle.message("new.html.file.action"))
- .addKind("HTML file", StdFileTypes.HTML.getIcon(), FileTemplateManager.INTERNAL_HTML5_TEMPLATE_NAME)
- .addKind("HTML4 file", StdFileTypes.HTML.getIcon(), FileTemplateManager.INTERNAL_HTML_TEMPLATE_NAME)
+ .addKind("HTML 5 file", StdFileTypes.HTML.getIcon(), FileTemplateManager.INTERNAL_HTML5_TEMPLATE_NAME)
+ .addKind("HTML 4 file", StdFileTypes.HTML.getIcon(), FileTemplateManager.INTERNAL_HTML_TEMPLATE_NAME)
.addKind("XHTML file", StdFileTypes.XHTML.getIcon(), FileTemplateManager.INTERNAL_XHTML_TEMPLATE_NAME);
}
diff --git a/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java b/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
index 342a274c0b30..603746bb3c60 100644
--- a/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
+++ b/xml/impl/src/com/intellij/ide/browsers/StartBrowserPanel.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.ide.browsers;
import com.intellij.ide.DataManager;
@@ -141,6 +156,13 @@ public class StartBrowserPanel {
return browserSettings;
}
+ public void setFromSettings(StartBrowserSettings settings) {
+ setSelected(settings.isSelected());
+ setUrl(settings.getUrl());
+ myStartJavaScriptDebuggerCheckBox.setSelected(settings.isStartJavaScriptDebugger());
+ myBrowserSelector.setSelected(settings.getBrowser());
+ }
+
public static void setupUrlField(@NotNull TextFieldWithBrowseButton field, @NotNull final Project project) {
FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
diff --git a/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java b/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
index 7800d8821778..a2d78ccb898b 100644
--- a/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
+++ b/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -17,10 +17,7 @@ package com.intellij.ide.browsers;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Conditions;
-import com.intellij.openapi.util.JDOMUtil;
-import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
@@ -29,13 +26,10 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
+import java.util.*;
@State(name = "WebBrowsersConfiguration", storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/web-browsers.xml")})
-public class WebBrowserManager implements PersistentStateComponent<Element>, ModificationTracker {
+public class WebBrowserManager extends SimpleModificationTracker implements PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance(WebBrowserManager.class);
// default standard browser ID must be constant across all IDE versions on all machines for all users
@@ -48,8 +42,6 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
private List<ConfigurableWebBrowser> browsers;
- private long modificationCount;
-
DefaultBrowser defaultBrowser = DefaultBrowser.SYSTEM;
public WebBrowserManager() {
@@ -87,7 +79,7 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
public Element getState() {
Element state = new Element("state");
if (defaultBrowser != DefaultBrowser.SYSTEM) {
- state.setAttribute("default", defaultBrowser.name().toLowerCase());
+ state.setAttribute("default", defaultBrowser.name().toLowerCase(Locale.ENGLISH));
}
for (ConfigurableWebBrowser browser : browsers) {
@@ -185,7 +177,7 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
String defaultValue = element.getAttributeValue("default");
if (!StringUtil.isEmpty(defaultValue)) {
try {
- defaultBrowser = DefaultBrowser.valueOf(defaultValue.toUpperCase());
+ defaultBrowser = DefaultBrowser.valueOf(defaultValue.toUpperCase(Locale.ENGLISH));
}
catch (IllegalArgumentException e) {
LOG.warn(e);
@@ -245,7 +237,7 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
void setList(@NotNull List<ConfigurableWebBrowser> value) {
browsers = value;
- modificationCount++;
+ incModificationCount();
}
@NotNull
@@ -286,7 +278,7 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
final BrowserSpecificSettings specificSettings) {
final ConfigurableWebBrowser browser = new ConfigurableWebBrowser(id, family, name, path, active, specificSettings);
browsers.add(browser);
- modificationCount++;
+ incModificationCount();
return browser;
}
@@ -371,9 +363,4 @@ public class WebBrowserManager implements PersistentStateComponent<Element>, Mod
}
return null;
}
-
- @Override
- public long getModificationCount() {
- return modificationCount;
- }
} \ No newline at end of file
diff --git a/xml/impl/src/com/intellij/ide/browsers/actions/BaseOpenInBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/actions/BaseOpenInBrowserAction.java
index b01bcdfd9b52..8ec2a2e55b67 100644
--- a/xml/impl/src/com/intellij/ide/browsers/actions/BaseOpenInBrowserAction.java
+++ b/xml/impl/src/com/intellij/ide/browsers/actions/BaseOpenInBrowserAction.java
@@ -84,12 +84,11 @@ public abstract class BaseOpenInBrowserAction extends DumbAwareAction {
StringBuilder builder = new StringBuilder(description);
builder.append(" (");
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("WebOpenInAction");
- if (shortcuts.length > 0) {
- builder.append(KeymapUtil.getShortcutText(shortcuts[0]));
- }
+ boolean exists = shortcuts.length > 0;
+ if (exists) builder.append(KeymapUtil.getShortcutText(shortcuts[0]));
if (HtmlUtil.isHtmlFile(result.first.getFile())) {
- builder.append(", hold Shift to open URL of local file");
+ builder.append(exists ? ", " : "").append("hold Shift to open URL of local file");
}
builder.append(')');
description = builder.toString();
diff --git a/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
index 2d5409fd6974..5dd70c03ec77 100644
--- a/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
+++ b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
@@ -18,9 +18,7 @@ package com.intellij.ide.browsers.actions;
import com.intellij.icons.AllIcons;
import com.intellij.ide.browsers.WebBrowser;
import com.intellij.ide.browsers.WebBrowserManager;
-import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.ComputableActionGroup;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.psi.util.CachedValueProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,6 +30,10 @@ public abstract class OpenInBrowserBaseGroupAction extends ComputableActionGroup
protected OpenInBrowserBaseGroupAction(boolean popup) {
super(popup);
+ Presentation p = getTemplatePresentation();
+ p.setText("Open in _Browser");
+ p.setDescription("Open selected file in browser");
+ p.setIcon(AllIcons.Nodes.PpWeb);
}
@NotNull
@@ -75,4 +77,8 @@ public abstract class OpenInBrowserBaseGroupAction extends ComputableActionGroup
super(false);
}
}
+
+ public void update(@NotNull AnActionEvent e) {
+ e.getPresentation().setVisible(!ActionGroupUtil.isGroupEmpty(this, e));
+ }
} \ No newline at end of file
diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
index 5647e69af22c..5cd056f869d9 100644
--- a/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
+++ b/xml/impl/src/com/intellij/ide/browsers/impl/WebBrowserServiceImpl.java
@@ -62,7 +62,7 @@ public class WebBrowserServiceImpl extends WebBrowserService {
}
}
}
- return virtualFile instanceof LightVirtualFile ? Collections.<Url>emptySet() : Collections.singleton(Urls.newFromVirtualFile(virtualFile));
+ return virtualFile instanceof LightVirtualFile || !request.getFile().getViewProvider().isPhysical() ? Collections.<Url>emptySet() : Collections.singleton(Urls.newFromVirtualFile(virtualFile));
}
@Nullable
diff --git a/xml/impl/src/com/intellij/javaee/MapExternalResourceDialog.java b/xml/impl/src/com/intellij/javaee/MapExternalResourceDialog.java
index e09101ab5cbe..62196a18e0bf 100644
--- a/xml/impl/src/com/intellij/javaee/MapExternalResourceDialog.java
+++ b/xml/impl/src/com/intellij/javaee/MapExternalResourceDialog.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -105,7 +106,7 @@ public class MapExternalResourceDialog extends DialogWrapper {
ColoredTreeCellRenderer renderer = new ColoredTreeCellRenderer() {
@Override
- public void customizeCellRenderer(JTree tree,
+ public void customizeCellRenderer(@NotNull JTree tree,
Object value,
boolean selected,
boolean expanded,
@@ -142,6 +143,7 @@ public class MapExternalResourceDialog extends DialogWrapper {
});
myExplorer = new FileSystemTreeImpl(project, new FileChooserDescriptor(true, false, false, false, true, false));
+ Disposer.register(getDisposable(), myExplorer);
myExplorer.addListener(new FileSystemTree.Listener() {
@Override
diff --git a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
index 7e5977abf9dc..e2267f53b770 100644
--- a/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
+++ b/xml/impl/src/com/intellij/xml/util/XmlReferenceContributor.java
@@ -39,7 +39,7 @@ import static com.intellij.patterns.XmlPatterns.*;
*/
public class XmlReferenceContributor extends PsiReferenceContributor {
@Override
- public void registerReferenceProviders(final PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
final IdReferenceProvider idReferenceProvider = new IdReferenceProvider();
diff --git a/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java b/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java
index 11fb4a784c42..271fd5b6ff3d 100644
--- a/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java
+++ b/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java
@@ -15,8 +15,11 @@
*/
package com.intellij.xml.util.documentation;
+import com.intellij.lang.Language;
+import com.intellij.lang.LanguageDocumentation;
import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.lang.documentation.DocumentationUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiWhiteSpace;
@@ -36,22 +39,19 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* @author maxim
*/
public class HtmlDocumentationProvider implements DocumentationProvider {
- private static DocumentationProvider ourStyleProvider;
+ private DocumentationProvider myStyleProvider = null;
private static DocumentationProvider ourScriptProvider;
@NonNls public static final String ELEMENT_ELEMENT_NAME = "element";
@NonNls public static final String NBSP = ":&nbsp;";
@NonNls public static final String BR = "<br>";
- public static void registerStyleDocumentationProvider(DocumentationProvider documentationProvider) {
- ourStyleProvider = documentationProvider;
- }
-
@Override
@Nullable
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
@@ -63,10 +63,10 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
@Override
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
- String result = getUrlForHtml(element, PsiTreeUtil.getParentOfType(originalElement,XmlTag.class,false));
-
- if (result == null && ourStyleProvider !=null) {
- return ourStyleProvider.getUrlFor(element, originalElement);
+ String result = getUrlForHtml(element, PsiTreeUtil.getParentOfType(originalElement, XmlTag.class, false));
+ DocumentationProvider styleProvider = getStyleProvider();
+ if (result == null && styleProvider != null) {
+ return styleProvider.getUrlFor(element, originalElement);
}
return result != null ? Collections.singletonList(result) : null;
@@ -126,7 +126,7 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
key = nameElement.getText();
}
- key = (key != null)?key.toLowerCase():"";
+ key = StringUtil.notNullize(key).toLowerCase(Locale.US);
int dotIndex = key.indexOf('.');
if (dotIndex > 0) {
@@ -155,8 +155,9 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
final XmlTag tag = PsiTreeUtil.getParentOfType(originalElement, XmlTag.class, false);
String result = generateDocForHtml(element, false, tag, originalElement);
- if (result == null && ourStyleProvider !=null) {
- result = ourStyleProvider.generateDoc(element, originalElement);
+ DocumentationProvider styleProvider = getStyleProvider();
+ if (result == null && styleProvider !=null) {
+ result = styleProvider.generateDoc(element, originalElement);
}
if (result == null && ourScriptProvider !=null) {
@@ -170,15 +171,11 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
return result;
}
- public String generateDocForHtml(PsiElement element) {
- return generateDocForHtml(element,true, null, null);
- }
-
- protected String generateDocForHtml(PsiElement element, boolean ommitHtmlSpecifics, XmlTag context, PsiElement originalElement) {
+ protected String generateDocForHtml(PsiElement element, boolean omitHtmlSpecifics, XmlTag context, PsiElement originalElement) {
final EntityDescriptor descriptor = findDocumentationDescriptor(element,context);
if (descriptor!=null) {
- return generateJavaDoc(descriptor, ommitHtmlSpecifics, originalElement);
+ return generateJavaDoc(descriptor, omitHtmlSpecifics, originalElement);
}
if (element instanceof XmlEntityDecl) {
final XmlEntityDecl entityDecl = (XmlEntityDecl)element;
@@ -188,11 +185,11 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
return null;
}
- private static String generateJavaDoc(EntityDescriptor descriptor, boolean ommitHtmlSpecifics, PsiElement element) {
+ private static String generateJavaDoc(EntityDescriptor descriptor, boolean omitHtmlSpecifics, PsiElement element) {
StringBuilder buf = new StringBuilder();
- final boolean istag = descriptor instanceof HtmlTagDescriptor;
+ final boolean isTag = descriptor instanceof HtmlTagDescriptor;
- if (istag) {
+ if (isTag) {
DocumentationUtil.formatEntityName(XmlBundle.message("xml.javadoc.tag.name.message"),descriptor.getName(),buf);
} else {
DocumentationUtil.formatEntityName(XmlBundle.message("xml.javadoc.attribute.name.message"),descriptor.getName(),buf);
@@ -200,10 +197,10 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
buf.append(XmlBundle.message("xml.javadoc.description.message")).append(NBSP).append(descriptor.getDescription()).append(BR);
- if (istag) {
+ if (isTag) {
final HtmlTagDescriptor tagDescriptor = (HtmlTagDescriptor)descriptor;
- if (!ommitHtmlSpecifics) {
+ if (!omitHtmlSpecifics) {
boolean hasStartTag = tagDescriptor.isHasStartTag();
if (!hasStartTag) {
buf.append(XmlBundle.message("xml.javadoc.start.tag.could.be.omitted.message")).append(BR);
@@ -227,7 +224,7 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
char dtdId = descriptor.getDtd();
boolean deprecated = dtdId == EntityDescriptor.LOOSE_DTD;
if (deprecated) {
- buf.append(XmlBundle.message("xml.javadoc.deprecated.message", deprecated)).append(BR);
+ buf.append(XmlBundle.message("xml.javadoc.deprecated.message", true)).append(BR);
}
if (dtdId == EntityDescriptor.LOOSE_DTD) {
@@ -240,7 +237,7 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
buf.append(XmlBundle.message("xml.javadoc.defined.in.any.dtd.message"));
}
- if (!istag) {
+ if (!isTag) {
ColorSampleLookupValue.addColorPreviewAndCodeToLookup(element,buf);
}
@@ -255,8 +252,9 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
PsiElement result = createNavigationElementHTML(psiManager, object.toString(),element);
- if (result== null && ourStyleProvider !=null) {
- result = ourStyleProvider.getDocumentationElementForLookupItem(psiManager, object, element);
+ DocumentationProvider styleProvider = getStyleProvider();
+ if (result== null && styleProvider !=null) {
+ result = styleProvider.getDocumentationElementForLookupItem(psiManager, object, element);
}
if (result== null && ourScriptProvider !=null) {
result = ourScriptProvider.getDocumentationElementForLookupItem(psiManager, object, element);
@@ -271,8 +269,9 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
PsiElement result = createNavigationElementHTML(psiManager, link, context);
- if (result== null && ourStyleProvider !=null) {
- result = ourStyleProvider.getDocumentationElementForLink(psiManager, link,context);
+ DocumentationProvider styleProvider = getStyleProvider();
+ if (result== null && styleProvider !=null) {
+ result = styleProvider.getDocumentationElementForLink(psiManager, link, context);
}
if (result== null && ourScriptProvider !=null) {
result = ourScriptProvider.getDocumentationElementForLink(psiManager, link,context);
@@ -281,7 +280,7 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
}
public PsiElement createNavigationElementHTML(PsiManager psiManager, String text, PsiElement context) {
- String key = text.toLowerCase();
+ String key = text.toLowerCase(Locale.US);
final HtmlTagDescriptor descriptor = HtmlDescriptorsTable.getTagDescriptor(key);
if (descriptor != null && !isAttributeContext(context) ) {
@@ -332,4 +331,15 @@ public class HtmlDocumentationProvider implements DocumentationProvider {
public static void registerScriptDocumentationProvider(final DocumentationProvider provider) {
ourScriptProvider = provider;
}
+
+ @Nullable
+ private DocumentationProvider getStyleProvider() {
+ if (myStyleProvider == null) {
+ Language cssLanguage = Language.findLanguageByID("CSS");
+ if (cssLanguage != null) {
+ myStyleProvider = LanguageDocumentation.INSTANCE.forLanguage(cssLanguage);
+ }
+ }
+ return myStyleProvider;
+ }
}
diff --git a/xml/impl/src/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java b/xml/impl/src/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java
index 70ee74f59850..613f588c37f9 100644
--- a/xml/impl/src/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java
+++ b/xml/impl/src/com/intellij/xml/util/documentation/XHtmlDocumentationProvider.java
@@ -26,7 +26,7 @@ import com.intellij.psi.xml.XmlText;
public class XHtmlDocumentationProvider extends HtmlDocumentationProvider {
@Override
- protected String generateDocForHtml(PsiElement element, boolean ommitHtmlSpecifics, XmlTag context, PsiElement originalElement) {
+ protected String generateDocForHtml(PsiElement element, boolean omitHtmlSpecifics, XmlTag context, PsiElement originalElement) {
return super.generateDocForHtml(element, true, context, originalElement);
}
diff --git a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java
index 372c28a338b3..94a1a4b35a98 100644
--- a/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java
+++ b/xml/openapi/src/com/intellij/ide/browsers/WebBrowserUrlProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -16,9 +16,7 @@
package com.intellij.ide.browsers;
import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Url;
import com.intellij.util.containers.ContainerUtil;
@@ -26,26 +24,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
-import java.util.Set;
public abstract class WebBrowserUrlProvider {
public static final ExtensionPointName<WebBrowserUrlProvider> EP_NAME = ExtensionPointName.create("com.intellij.webBrowserUrlProvider");
- private final boolean myDeprecatedMethodOverridden;
-
- protected WebBrowserUrlProvider() {
- boolean deprecatedMethodOverridden;
- try {
- deprecatedMethodOverridden =
- getClass().getMethod("canHandleElement", PsiElement.class, PsiFile.class, Ref.class).getDeclaringClass() != WebBrowserUrlProvider.class ||
- getClass().getMethod("canHandle", PsiElement.class, PsiFile.class, Ref.class).getDeclaringClass() != WebBrowserUrlProvider.class;
- }
- catch (Throwable ignored) {
- deprecatedMethodOverridden = false;
- }
- myDeprecatedMethodOverridden = deprecatedMethodOverridden;
- }
-
/**
* Browser exceptions are printed in Error Dialog when user presses any browser button
*/
@@ -55,39 +37,7 @@ public abstract class WebBrowserUrlProvider {
}
}
- @Deprecated
- /**
- * @deprecated to remove in IDEA 14
- */
- public boolean canHandleElement(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull Ref<Set<Url>> result) {
- Ref<Collection<Url>> ref = Ref.create();
- @SuppressWarnings("deprecation")
- boolean canHandle = canHandle(element, psiFile, ref);
- if (!ref.isNull()) {
- result.set(ContainerUtil.newHashSet(ref.get()));
- }
- return canHandle;
- }
-
- @SuppressWarnings("UnusedParameters")
- @Deprecated
- /**
- * @deprecated to remove in IDEA 15
- */
- public boolean canHandle(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull Ref<Collection<Url>> result) {
- return false;
- }
-
public boolean canHandleElement(@NotNull OpenInBrowserRequest request) {
- if (myDeprecatedMethodOverridden) {
- Ref<Set<Url>> resultRef = Ref.create();
- //noinspection deprecation
- if (canHandleElement(request.getElement(), request.getFile(), resultRef)) {
- request.setResult(resultRef.get());
- return true;
- }
- }
-
try {
Collection<Url> urls = getUrls(request);
if (!urls.isEmpty()) {
@@ -103,17 +53,6 @@ public abstract class WebBrowserUrlProvider {
@Nullable
protected Url getUrl(@NotNull OpenInBrowserRequest request, @NotNull VirtualFile virtualFile) throws BrowserException {
- //noinspection deprecation
- return myDeprecatedMethodOverridden ? getUrl(request.getElement(), request.getFile(), virtualFile) : null;
- }
-
- @SuppressWarnings("UnusedParameters")
- @Deprecated
- @Nullable
- /**
- * @deprecated to remove in IDEA 14
- */
- public Url getUrl(@NotNull PsiElement element, @NotNull PsiFile psiFile, @NotNull VirtualFile virtualFile) throws BrowserException {
return null;
}
@@ -122,13 +61,6 @@ public abstract class WebBrowserUrlProvider {
return ContainerUtil.createMaybeSingletonList(getUrl(request, request.getVirtualFile()));
}
- @SuppressWarnings({"UnusedParameters", "UnusedDeclaration"})
- @Nullable
- @Deprecated
- public String getOpenInBrowserActionText(@NotNull PsiFile file) {
- return null;
- }
-
@Nullable
public String getOpenInBrowserActionDescription(@NotNull PsiFile file) {
return null;
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/RelaxNGReferenceContributor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/RelaxNGReferenceContributor.java
index c9317dd79ac4..268f53d5d846 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/RelaxNGReferenceContributor.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/RelaxNGReferenceContributor.java
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiReferenceRegistrar;
import com.intellij.psi.filters.position.PatternFilter;
import com.intellij.xml.util.XmlUtil;
import org.intellij.plugins.relaxNG.references.PrefixReferenceProvider;
+import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.XmlPatterns.*;
@@ -36,7 +37,7 @@ public class RelaxNGReferenceContributor extends PsiReferenceContributor {
RNG_TAG_PATTERN.withLocalName("element", "attribute"));
@Override
- public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
+ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
XmlUtil.registerXmlAttributeValueReferenceProvider(registrar, new String[]{
"name"
}, new PatternFilter(xmlAttributeValue().withParent(NAME_PATTERN)), true, new PrefixReferenceProvider());
diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncFileImpl.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncFileImpl.java
index 0bc22c5f407b..fcb398019b7b 100644
--- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncFileImpl.java
+++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncFileImpl.java
@@ -115,6 +115,7 @@ public class RncFileImpl extends PsiFileBase implements RncFile, XmlFile {
return false;
}
+ @NotNull
@Override
public GlobalSearchScope getFileResolveScope() {
return ProjectScope.getAllScope(getProject());
diff --git a/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java b/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java
index 9430842053e3..e0775fd00573 100644
--- a/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java
+++ b/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
*/
-public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider {
+public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider implements InspectionSuppressor {
public static final String SUPPRESS_MARK = "suppress";
diff --git a/xml/xml-psi-api/src/com/intellij/codeInspection/XmlInspectionSuppressor.java b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlInspectionSuppressor.java
new file mode 100644
index 000000000000..1ddc7f667ab6
--- /dev/null
+++ b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlInspectionSuppressor.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+public class XmlInspectionSuppressor implements InspectionSuppressor{
+ @Override
+ public boolean isSuppressedFor(@NotNull PsiElement element, String toolId) {
+ return XmlSuppressionProvider.isSuppressed(element, toolId);
+ }
+
+ @Override
+ public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, String toolShortName) {
+ return XmlSuppressableInspectionTool.getSuppressFixes(toolShortName);
+ }
+}
diff --git a/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressableInspectionTool.java b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressableInspectionTool.java
index 5292a1ac6af1..a46cd41085fa 100644
--- a/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressableInspectionTool.java
+++ b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressableInspectionTool.java
@@ -16,6 +16,7 @@
package com.intellij.codeInspection;
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -23,39 +24,31 @@ import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public abstract class XmlSuppressableInspectionTool extends LocalInspectionTool implements BatchSuppressableTool {
@NonNls static final String ALL = "ALL";
- @NotNull
- @Override
- public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
- return new SuppressQuickFix[]{new SuppressTag(), new SuppressForFile(getID()), new SuppressAllForFile()};
+ public static SuppressQuickFix[] getSuppressFixes(final String shortName) {
+ return getSuppressFixes(shortName, new DefaultXmlSuppressionProvider());
}
- @Override
- public boolean isSuppressedFor(@NotNull final PsiElement element) {
- return XmlSuppressionProvider.isSuppressed(element, getID());
+ public static SuppressQuickFix[] getSuppressFixes(final String shortName, XmlSuppressionProvider provider) {
+ final String id = HighlightDisplayKey.find(shortName).getID();
+ return new SuppressQuickFix[]{new SuppressTagStatic(id, provider), new SuppressForFile(id, provider), new SuppressAllForFile(provider)};
}
- public class SuppressTag extends SuppressTagStatic {
- public SuppressTag() {
- super(getID());
- }
- }
+ public static abstract class XmlSuppressFix implements SuppressQuickFix {
- public static class SuppressTagStatic implements SuppressQuickFix {
- private final String id;
+ protected final String myId;
+ protected final XmlSuppressionProvider myProvider;
- public SuppressTagStatic(@NotNull String id) {
- this.id = id;
+ protected XmlSuppressFix(String inspectionId, XmlSuppressionProvider suppressionProvider) {
+ myId = inspectionId;
+ myProvider = suppressionProvider;
}
- @NotNull
- @Override
- public String getName() {
- return InspectionsBundle.message("xml.suppressable.for.tag.title");
+ protected XmlSuppressFix(String id) {
+ this(id, new DefaultXmlSuppressionProvider());
}
@Override
@@ -64,52 +57,66 @@ public abstract class XmlSuppressableInspectionTool extends LocalInspectionTool
}
@Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- PsiElement element = descriptor.getPsiElement();
- if (PsiTreeUtil.getParentOfType(element, XmlTag.class) == null) return;
- XmlSuppressionProvider.getProvider(element.getContainingFile()).suppressForTag(element, id);
- }
-
- @Override
@NotNull
public String getFamilyName() {
return getName();
}
}
- public static class SuppressForFile implements SuppressQuickFix {
- private final String myInspectionId;
+ public static class SuppressTagStatic extends XmlSuppressFix {
- public SuppressForFile(@NotNull String inspectionId) {
- myInspectionId = inspectionId;
+ public SuppressTagStatic(String inspectionId, XmlSuppressionProvider suppressionProvider) {
+ super(inspectionId, suppressionProvider);
+ }
+
+ public SuppressTagStatic(String id) {
+ super(id);
}
@NotNull
@Override
public String getName() {
- return InspectionsBundle.message("xml.suppressable.for.file.title");
+ return InspectionsBundle.message("xml.suppressable.for.tag.title");
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
- if (element == null || !element.isValid() || !(element.getContainingFile() instanceof XmlFile)) return;
- XmlSuppressionProvider.getProvider(element.getContainingFile()).suppressForFile(element, myInspectionId);
+ if (PsiTreeUtil.getParentOfType(element, XmlTag.class) == null) return;
+ myProvider.suppressForTag(element, myId);
+ }
+
+ }
+
+ public static class SuppressForFile extends XmlSuppressFix {
+
+ public SuppressForFile(String inspectionId, XmlSuppressionProvider suppressionProvider) {
+ super(inspectionId, suppressionProvider);
+ }
+
+ public SuppressForFile(String id) {
+ super(id);
}
+ @NotNull
@Override
- public boolean isAvailable(@NotNull Project project, @NotNull PsiElement context) {
- return context.isValid();
+ public String getName() {
+ return InspectionsBundle.message("xml.suppressable.for.file.title");
}
@Override
- @NotNull
- public String getFamilyName() {
- return getName();
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ if (element == null || !element.isValid() || !(element.getContainingFile() instanceof XmlFile)) return;
+ myProvider.suppressForFile(element, myId);
}
}
public static class SuppressAllForFile extends SuppressForFile {
+ public SuppressAllForFile(XmlSuppressionProvider provider) {
+ super(ALL, provider);
+ }
+
public SuppressAllForFile() {
super(ALL);
}
diff --git a/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressionProvider.java b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressionProvider.java
index de68c7a5a7ca..a047f44109ca 100644
--- a/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressionProvider.java
+++ b/xml/xml-psi-api/src/com/intellij/codeInspection/XmlSuppressionProvider.java
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
*/
-public abstract class XmlSuppressionProvider {
+public abstract class XmlSuppressionProvider implements InspectionSuppressor {
public static final ExtensionPointName<XmlSuppressionProvider> EP_NAME = new ExtensionPointName<XmlSuppressionProvider>("com.intellij.xml.xmlSuppressionProvider");
@@ -38,15 +38,6 @@ public abstract class XmlSuppressionProvider {
return false;
}
- public static XmlSuppressionProvider getProvider(@NotNull PsiFile file) {
- for (XmlSuppressionProvider provider : Extensions.getExtensions(EP_NAME)) {
- if (provider.isProviderAvailable(file)) {
- return provider;
- }
- }
- throw new RuntimeException("No providers found for " + file);
- }
-
public abstract boolean isProviderAvailable(@NotNull PsiFile file);
public abstract boolean isSuppressedFor(@NotNull PsiElement element, @NotNull String inspectionId);
@@ -55,4 +46,10 @@ public abstract class XmlSuppressionProvider {
public abstract void suppressForTag(@NotNull PsiElement element, @NotNull String inspectionId);
+ @Override
+ public SuppressQuickFix[] getSuppressActions(@NotNull PsiElement element, String toolShortName) {
+ return XmlSuppressableInspectionTool.getSuppressFixes(toolShortName, this);
+ }
+
+
}
diff --git a/xml/xml-psi-api/src/com/intellij/javaee/ExternalResourceManager.java b/xml/xml-psi-api/src/com/intellij/javaee/ExternalResourceManager.java
index 73f31e3393bf..fb8d7dfae5e9 100644
--- a/xml/xml-psi-api/src/com/intellij/javaee/ExternalResourceManager.java
+++ b/xml/xml-psi-api/src/com/intellij/javaee/ExternalResourceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,7 +18,7 @@ package com.intellij.javaee;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -27,8 +27,7 @@ import org.jetbrains.annotations.Nullable;
/**
* author: lesya
*/
-public abstract class ExternalResourceManager implements ModificationTracker {
-
+public abstract class ExternalResourceManager extends SimpleModificationTracker {
public static ExternalResourceManager getInstance() {
return ServiceManager.getService(ExternalResourceManager.class);
}
diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java b/xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java
index def0f85fd545..8e2202c697b4 100644
--- a/xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java
+++ b/xml/xml-psi-impl/src/com/intellij/javaee/CoreExternalResourceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -183,9 +183,4 @@ public class CoreExternalResourceManager extends ExternalResourceManagerEx {
public String[] getResourceUrls(@Nullable FileType fileType, @NonNls String version, boolean includeStandard) {
throw new UnsupportedOperationException();
}
-
- @Override
- public long getModificationCount() {
- return 0;
- }
}
diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java b/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java
index 38f96f052c44..2eee2882613e 100644
--- a/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java
@@ -92,7 +92,6 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
}
private final List<ExternalResourceListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
- private long myModificationCount = 0;
private final PathMacrosImpl myPathMacros;
@NonNls private static final String RESOURCE_ELEMENT = "resource";
@NonNls private static final String URL_ATTR = "url";
@@ -268,7 +267,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
assert map != null;
map.put(url, location);
myResourceLocations.add(location);
- myModificationCount++;
+ incModificationCount();
}
@Override
@@ -285,7 +284,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
if (location != null) {
myResourceLocations.remove(location);
}
- myModificationCount++;
+ incModificationCount();
fireExternalResourceChanged();
}
}
@@ -325,7 +324,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
ApplicationManager.getApplication().assertWriteAccessAllowed();
clearAllResources();
getProjectResources(project).clearAllResources();
- myModificationCount++;
+ incModificationCount();
fireExternalResourceChanged();
}
@@ -338,14 +337,14 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
private void addIgnoredSilently(String url) {
myIgnoredResources.add(url);
- myModificationCount++;
+ incModificationCount();
}
@Override
public void removeIgnoredResource(String url) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
if (myIgnoredResources.remove(url)) {
- myModificationCount++;
+ incModificationCount();
fireExternalResourceChanged();
}
}
@@ -371,11 +370,6 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
}
@Override
- public long getModificationCount() {
- return myModificationCount;
- }
-
- @Override
public long getModificationCount(@NotNull Project project) {
return getProjectResources(project).getModificationCount();
}
@@ -385,7 +379,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
myPathMacros.addMacroExpands(macroExpands);
macroExpands.substitute(element, SystemInfo.isFileSystemCaseSensitive);
- myModificationCount++;
+ incModificationCount();
for (final Object o1 : element.getChildren(RESOURCE_ELEMENT)) {
Element e = (Element)o1;
addSilently(e.getAttributeValue(URL_ATTR), DEFAULT_VERSION, e.getAttributeValue(LOCATION_ATTR).replace('/', File.separatorChar));
@@ -502,7 +496,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
public void setCatalogPropertiesFile(String filePath) {
myCatalogManager = null;
myCatalogPropertiesFile = filePath;
- myModificationCount++;
+ incModificationCount();
}
@Nullable
@@ -514,7 +508,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx {
}
private void setDefaultHtmlDoctype(String defaultHtmlDoctype) {
- myModificationCount++;
+ incModificationCount();
if (Html5SchemaProvider.getHtml5SchemaLocation().equals(defaultHtmlDoctype)) {
myDefaultHtmlDoctype = HTML5_DOCTYPE_ELEMENT;
diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlFileImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlFileImpl.java
index 780eee70fb51..7fc96844ca09 100644
--- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlFileImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlFileImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -113,6 +113,7 @@ public class XmlFileImpl extends PsiFileImpl implements XmlFile {
}
+ @NotNull
@Override
public GlobalSearchScope getFileResolveScope() {
return ProjectScope.getAllScope(getProject());